View difference between Paste ID: 46DLNY1A and 0yrTkafF
SHOW: | | - or go back to the newest paste.
1
#!/usr/bin/env python
2
3
"""Charitum.py: an extensible IRC bot"""
4
5-
# ----------------------------------------------------------------------------
5+
6-
# "THE BEER-WARE LICENSE" (Revision 42):
6+
7-
# <s0lll0s@blinkenshell.org> wrote this file. As long as you retain this notice you
7+
8-
# can do whatever you want with this stuff. If we meet some day, and you think
8+
__version__ = "1.4.2"
9-
# this stuff is worth it, you can buy me a beer in return. S0lll0s
9+
10-
# ----------------------------------------------------------------------------
10+
11
import sys
12
import signal
13
import time
14
from ircutils import bot, format, protocol
15-
__version__ = "1.4.4"
15+
16
############################## EVENTS ###############################
17
 
18
# event handling seems to be broken
19
 
20
def callback_shutdown( signal, frame ):
21-
import urllib2
21+
22-
import urllib
22+
23
        sys.exit( 0 )
24
 
25
############################# UTILS #################################
26
 
27
def format_command( command, received ):
28
        """ Returns the fitting 'command' based on 'received'.
29
                received is either channel or private"""
30
        if received == "channel":
31
                return "!" + command.lower()
32
        return command.upper()
33
 
34
############################# COMMANDS ##############################
35
 
36
def cmd_exec( self, command, params, event, received="channel" ):
37
        """ {0}!X!- Execute an IRC command:
38
                {0} <COMMAND> <[PARAMS]>!X!- Execute the IRC command <COMMAND> with parameters <PARAMS>"""
39
       
40
        self.execute( params[0].upper(), ' '.join( params[1:] ).strip() )
41
        if received == "private":
42
                self.send_message( event.source, "Executed" + format.bold( params[0].upper() + ' '.join( params[1:] ) ) )
43
 
44
def cmd_say( self, command, params, event, received="channel" ):
45
        """ {0}!X!- Say a Text:
46-
        """ {0}!X!- Execute an IRC command
46+
47
                {0} <CHANNEL> <TEXT>!X!- Say <TEXT> in channel <CHANNEL> (/msg only)"""
48
       
49
        if received == "private":
50
                self.send_message( params[0], ' '.join( params[1:] ).strip() )
51
        else:
52
                self.send_message( event.target, ' '.join( params ).strip() )
53
 
54-
        """ {0}!X!- Say a Text
54+
55
        """ {0}!X!- Update the Voice/HOP/OP info manually:
56
                {0}!X!- Update the Voice/HOP/OP info manually"""
57
 
58
        self.execute( "NAMES", event.target )
59
       
60
def cmd_help( self, command, params, event, received="channel" ):
61
        """ {0}!X!- Help for commands:
62
                {0}!X!- List commands
63
                {0} <COMMAND>!X!- Help for <COMMAND>"""
64-
        """ {0}!X!- Update the Voice/HOP/OP info manually
64+
65
        if len( params ) < 1:
66
                self.send_message( event.source, "List of commands:" )
67
                for cmd in self.commands:
68
                        self.send_message( event.source, format.color( "## ", format.LIME_GREEN ) + '{:<20} {}'.format( *self.commands[ cmd ][1].__doc__.format( format.bold( format_command( cmd, received ) ) ).splitlines()[0].strip().split( "!X!", 1 ) ) ) # split and justify
69
                return
70-
        """ {0}!X!- Help for commands
70+
71
                self.send_message( event.source, "Usage info for command {0}:".format( format.bold( params[0] ) ) )
72
                for line in self.commands[ params[0].lower() ][1].__doc__.format( *[ format.bold( format_command( c, received ) ) for c in params ] ).splitlines():
73
                        self.send_message( event.source, format.color( "## ", format.LIME_GREEN ) + '{:<35} {}'.format( *line.strip().split( "!X!", 1 ) ) ) # split and justify
74
        else:
75
                self.send_message( event.source, "Unkown Command {0}.".format( format.bold( params[0] ) ) )
76
               
77
def cmd_shout( self, command, params, event, received="channel" ):
78
        """ {0}!X!- Shout a Text:
79
                {0} <TEXT>!X!- Shout <TEXT> in current channel
80
                {0} <CHANNEL> <TEXT>!X!- Shout <TEXT> in channel <CHANNEL> (/msg only)"""
81
               
82
        colors = [ format.GREEN, format.RED, format.AQUA, format.YELLOW, format.PINK, format.PURPLE, format.TEAL, format.LIGHT_GRAY ]
83
        if received == "private":
84
                for color, bg in [(x,y) for x in colors for y in colors]:
85
                        self.send_message( params[0], format.color( ' '.join( params[1:] ).strip(), color, bg ) )
86
                        time.sleep( 0.5 )
87-
        """ {0}!X!- Shout a Text
87+
88
                for color, bg in [(x,y) for x in colors for y in colors]:
89
                        self.send_message( event.target, format.color( ' '.join( params ).strip() , color, bg ) )
90
                        time.sleep( 0.5 )
91
92
def cmd_op( self, command, params, event, received="channel" ):
93
        """{0}!X!- Make an user OP:
94
                {0}!X!- Get OP yourself
95
                {0} <USER>!X!- Make <USER> OP
96
                {0} <CHANNEL>!X!- Get OP yourself (/msg)
97
                {0} <CHANNEL> <USER>!X!- Make <USER> OP (/msg)"""
98
99
        user = event.source
100
        if received == "private":
101
                if len( params ) > 1:
102-
        """{0}!X!- Make an user OP
102+
103
                self.execute( "OP", params[0] + " " + user )
104
        else:
105
                if len( params ) > 0:
106
                        user = params[0]
107
                self.execute( "OP", event.target + " " + user )
108
109
def cmd_kick( self, command, params, event, received="channel" ):
110
        """{0}!X!- Kick an user:
111
                {0} <USER>!X!- Kick <USER>
112-
                self.execute( "MODE", params[0], "+o:", user )
112+
113
114
        if len( params ) < 1 or [0] == "Charitum":
115
                return
116-
                self.execute( "MODE", event.target, "+o:", user )
116+
117
        channel = event.target
118
        if len( params ) > 1:
119-
        """{0}!X!- Kick an user
119+
120
        self.execute( "KICK", channel + " " + params[0] )
121
 
122
############################### BOT #################################
123-
        if len( params ) < 1 or params[0] == "Charitum":
123+
124
class Charitum( bot.SimpleBot ):
125
        commands = {}
126
        channelusers = {}
127
        access = dict( ( ([ '', '+', '%', '@', '&', '~' ])[num] , num ) for num in range( 6 ) )
128
       
129-
        self.execute( "KICK", channel, " ", params[0] )
129+
130
                """ Adds a new command. command and short are names for
131
                        the command, used as ![command/short] and [COMMAND/SHORT].
132-
def cmd_banner( self, command, params, event, received="channel" ):
132+
133-
	"""{0}!X!- Print an ASCII Banner
133+
134-
		{0} <BANNER>!X!- Print <BANNER>
134+
135-
		{0} <BANNER> <CHANNEL>!X!- Print <BANNER> in <CHANNEL>"""
135+
136
                        specifically targetting the command. Format your docstring
137-
	rec = event.target
137+
138-
	if received == "private":
138+
139-
		rec = event.source
139+
140-
	if len( params ) > 1:
140+
141-
		rec = params[1]
141+
142
                if short is not None:
143-
	banner = None
143+
144-
	if params[0] == "text":
144+
                print "Added commmand", command, ", level", level, ", func", func.__name__
145-
		banner = ( format.BLUE, urllib2.urlopen( "https://artii.herokuapp.com/make?text=" + urllib.quote( " ".join(  params[2:] ) ) ).read().splitlines() )
145+
146-
		print banner
146+
147-
		print "https://artii.herokuapp.com/make?text=" +  " ".join(params[2:]) 
147+
148-
	elif params[0] == "graffiti":
148+
149-
		banner = ( format.BLUE, urllib2.urlopen( "https://artii.herokuapp.com/make?text=" + urllib.quote( " ".join( params[2:] ) ) + "&font=graffiti" ).read().splitlines() )
149+
150-
		print "graf"
150+
151-
	elif params[0] in banners:
151+
152-
		banner = banners[params[0]]
152+
153-
		print "file"
153+
154-
	else:
154+
155-
		self.send_message( rec, format.color( "ERROR:", format.RED ) + " Banner not found" )
155+
156-
		print "none"
156+
157-
		return
157+
158
                message = event.message.split()
159-
	for line in banner[1]:
159+
160-
		self.send_message( rec, format.color( format.bold( line ), banner[0], format.BLACK ) )
160+
161-
		time.sleep( 0.5 )
161+
162
                if len( command ) == 1: # skip single !'s and stuff
163
                        return
164
               
165
                if command[0] == "!": # only handle commands directed to us...
166
                        command =  command[1:].lower()
167
                        if command in self.commands: # ... that exist
168
                                self.execute( "NAMES", event.target ) # update permissions
169
                                ( level, func ) = self.commands[ command ]
170
 
171
                                for name in self.channelusers[ event.target ]:
172
                                        if protocol.strip_name_symbol( name ) == event.source: break # name is now event.target's name
173
                               
174
                                ulevel = 0
175
                                if name[0] in self.access: # do not handle 'empty' users
176
                                        ulevel = self.access[ name[0] ]
177
                                       
178
                                if  ulevel < self.access[ level ]:
179
                                        self.send_message( event.target, format.color( "ERROR:", format.RED ) + " You are not allowed to use the " + format.bold( command ) + " Command" )
180
                                        return
181
                                func( self, command, params, event )
182
                        else:
183
                                self.send_message( event.target, format.color( "ERROR:", format.RED ) + " Command " + format.bold( command ) +" not found" )
184
                               
185-
                print "Added commmand " + command + ", level " + level + ", func " + func.__name__
185+
186
        def on_private_message( self, event ):         
187
                message = event.message.split()
188
                command = message[0].upper()
189
                params  = message[1:]
190
 
191
                if command.lower() in self.commands:
192
                        self.execute( "NAMES", "#ltfu" ) # update permissions
193
                        ( level, func ) = self.commands[ command.lower() ]
194
                       
195
                        for name in self.channelusers[ "#ltfu" ]:
196
                                if protocol.strip_name_symbol( name ) == event.source: break # name is now event.target's name
197
                       
198
                        ulevel = 0
199
                        if name[0] in self.access: # do not handle 'empty' users
200
                                ulevel = self.access[ name[0] ]
201
 
202
                        if ulevel < self.access[ level ]:
203
                                self.send_message( event.source, format.color( "ERROR:", format.RED ) + " You are not allowed to use the " + format.bold( command ) + " Command" )
204
                                return
205
                        func( self, command, params, event, received="private" ) # tell the function this was a private message and call it
206
                else:
207
                        self.send_message( event.source, format.color( "ERROR:", format.RED ) + " Command " + format.bold( command ) +" not found" )
208
 
209
############################### RUN #################################
210
 
211
if __name__ == "__main__":
212
        charitum = Charitum( "DudelZ" )
213
        charitum.connect( "irc.freenode.net", channel=["#ltfu"] )
214
       
215
 
216
        charitum.add_command( "execute", "~", cmd_exec, short="exec" )
217
        charitum.add_command( "say", "@", cmd_say, "!" )
218
        charitum.add_command( "shout", "@", cmd_shout, "!!" )
219
        charitum.add_command( "update", "", cmd_update, "upd" )
220
        #charitum.add_command( "kick", "@", cmd_kick )
221
        #charitum.add_command( "op", "@", cmd_op )
222
        charitum.add_command( "help", "", cmd_help )
223
       
224
        signal.signal( signal.SIGINT,  callback_shutdown ) # register graceful shutdown here
225
       
226
        charitum.start()