Advertisement
S0lll0s

Charitum 1.4.4 Sourcecode

Dec 9th, 2012
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.49 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. """Charitum.py: an extensible IRC bot"""
  4.  
  5. # ----------------------------------------------------------------------------
  6. # "THE BEER-WARE LICENSE" (Revision 42):
  7. # <s0lll0s@blinkenshell.org> wrote this file. As long as you retain this notice you
  8. # can do whatever you want with this stuff. If we meet some day, and you think
  9. # this stuff is worth it, you can buy me a beer in return. S0lll0s
  10. # ----------------------------------------------------------------------------
  11.  
  12. __author__ = "S0lll0s"
  13. __copyright__ = "S0lll0s aka Sol Bekic"
  14. __license__ = "BEER-Ware license"
  15. __version__ = "1.4.4"
  16.  
  17.  
  18. import sys
  19. import signal
  20. import time
  21. import urllib2
  22. import urllib
  23. from ircutils import bot, format, protocol
  24.  
  25. ############################## EVENTS ###############################
  26.  
  27. # event handling seems to be broken
  28.  
  29. def callback_shutdown( signal, frame ):
  30.         # put stuff for gracefull stop here
  31.         print "\nShutting down...\n"
  32.         sys.exit( 0 )
  33.  
  34. ############################# UTILS #################################
  35.  
  36. def format_command( command, received ):
  37.         """ Returns the fitting 'command' based on 'received'.
  38.                received is either channel or private"""
  39.         if received == "channel":
  40.                 return "!" + command.lower()
  41.         return command.upper()
  42.  
  43. ############################# COMMANDS ##############################
  44.  
  45. def cmd_exec( self, command, params, event, received="channel" ):
  46.         """ {0}!X!- Execute an IRC command
  47.                {0} <COMMAND> <[PARAMS]>!X!- Execute the IRC command <COMMAND> with parameters <PARAMS>"""
  48.        
  49.         self.execute( params[0].upper(), ' '.join( params[1:] ).strip() )
  50.         if received == "private":
  51.                 self.send_message( event.source, "Executed" + format.bold( params[0].upper() + ' '.join( params[1:] ) ) )
  52.  
  53. def cmd_say( self, command, params, event, received="channel" ):
  54.         """ {0}!X!- Say a Text
  55.                {0} <TEXT>!X!- Say <TEXT> in current channel
  56.                {0} <CHANNEL> <TEXT>!X!- Say <TEXT> in channel <CHANNEL> (/msg only)"""
  57.        
  58.         if received == "private":
  59.                 self.send_message( params[0], ' '.join( params[1:] ).strip() )
  60.         else:
  61.                 self.send_message( event.target, ' '.join( params ).strip() )
  62.  
  63. def cmd_update( self, command, params, event, received="channel" ):
  64.         """ {0}!X!- Update the Voice/HOP/OP info manually
  65.                {0}!X!- Update the Voice/HOP/OP info manually"""
  66.  
  67.         self.execute( "NAMES", event.target )
  68.        
  69. def cmd_help( self, command, params, event, received="channel" ):
  70.         """ {0}!X!- Help for commands
  71.                {0}!X!- List commands
  72.                {0} <COMMAND>!X!- Help for <COMMAND>"""
  73.        
  74.         if len( params ) < 1:
  75.                 self.send_message( event.source, "List of commands:" )
  76.                 for cmd in self.commands:
  77.                         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
  78.                 return
  79.         if params[0].lower() in self.commands:
  80.                 self.send_message( event.source, "Usage info for command {0}:".format( format.bold( params[0] ) ) )
  81.                 for line in self.commands[ params[0].lower() ][1].__doc__.format( *[ format.bold( format_command( c, received ) ) for c in params ] ).splitlines():
  82.                         self.send_message( event.source, format.color( "## ", format.LIME_GREEN ) + '{:<35} {}'.format( *line.strip().split( "!X!", 1 ) ) ) # split and justify
  83.         else:
  84.                 self.send_message( event.source, "Unkown Command {0}.".format( format.bold( params[0] ) ) )
  85.                
  86. def cmd_shout( self, command, params, event, received="channel" ):
  87.         """ {0}!X!- Shout a Text
  88.                {0} <TEXT>!X!- Shout <TEXT> in current channel
  89.                {0} <CHANNEL> <TEXT>!X!- Shout <TEXT> in channel <CHANNEL> (/msg only)"""
  90.                
  91.         colors = [ format.GREEN, format.RED, format.AQUA, format.YELLOW, format.PINK, format.PURPLE, format.TEAL, format.LIGHT_GRAY ]
  92.         if received == "private":
  93.                 for color, bg in [(x,y) for x in colors for y in colors]:
  94.                         self.send_message( params[0], format.color( ' '.join( params[1:] ).strip(), color, bg ) )
  95.                         time.sleep( 0.5 )
  96.         else:
  97.                 for color, bg in [(x,y) for x in colors for y in colors]:
  98.                         self.send_message( event.target, format.color( ' '.join( params ).strip() , color, bg ) )
  99.                         time.sleep( 0.5 )
  100.  
  101. def cmd_op( self, command, params, event, received="channel" ):
  102.         """{0}!X!- Make an user OP
  103.                {0}!X!- Get OP yourself
  104.                {0} <USER>!X!- Make <USER> OP
  105.                {0} <CHANNEL>!X!- Get OP yourself (/msg)
  106.                {0} <CHANNEL> <USER>!X!- Make <USER> OP (/msg)"""
  107.  
  108.         user = event.source
  109.         if received == "private":
  110.                 if len( params ) > 1:
  111.                         user = params[1]
  112.                 self.execute( "MODE", params[0], "+o:", user )
  113.         else:
  114.                 if len( params ) > 0:
  115.                         user = params[0]
  116.                 self.execute( "MODE", event.target, "+o:", user )
  117.  
  118. def cmd_kick( self, command, params, event, received="channel" ):
  119.         """{0}!X!- Kick an user
  120.                {0} <USER>!X!- Kick <USER>
  121.                {0} <USER> <CHANNEL>!X!- Kick <USER> from <CHANNEL> (/msg)"""
  122.  
  123.         if len( params ) < 1 or params[0] == "Charitum":
  124.                 return
  125.  
  126.         channel = event.target
  127.         if len( params ) > 1:
  128.                 channel = params[1]
  129.         self.execute( "KICK", channel, " ", params[0] )
  130.  
  131.  
  132. def cmd_banner( self, command, params, event, received="channel" ):
  133.     """{0}!X!- Print an ASCII Banner
  134.         {0} <BANNER>!X!- Print <BANNER>
  135.         {0} <BANNER> <CHANNEL>!X!- Print <BANNER> in <CHANNEL>"""
  136.  
  137.     rec = event.target
  138.     if received == "private":
  139.         rec = event.source
  140.     if len( params ) > 1:
  141.         rec = params[1]
  142.  
  143.     banner = None
  144.     if params[0] == "text":
  145.         banner = ( format.BLUE, urllib2.urlopen( "https://artii.herokuapp.com/make?text=" + urllib.quote( " ".join(  params[2:] ) ) ).read().splitlines() )
  146.         print banner
  147.         print "https://artii.herokuapp.com/make?text=" +  " ".join(params[2:])
  148.     elif params[0] == "graffiti":
  149.         banner = ( format.BLUE, urllib2.urlopen( "https://artii.herokuapp.com/make?text=" + urllib.quote( " ".join( params[2:] ) ) + "&font=graffiti" ).read().splitlines() )
  150.         print "graf"
  151.     elif params[0] in banners:
  152.         banner = banners[params[0]]
  153.         print "file"
  154.     else:
  155.         self.send_message( rec, format.color( "ERROR:", format.RED ) + " Banner not found" )
  156.         print "none"
  157.         return
  158.  
  159.     for line in banner[1]:
  160.         self.send_message( rec, format.color( format.bold( line ), banner[0], format.BLACK ) )
  161.         time.sleep( 0.5 )
  162.  
  163. ############################### BOT #################################
  164.  
  165. class Charitum( bot.SimpleBot ):
  166.         commands = {}
  167.         channelusers = {}
  168.         access = dict( ( ([ '', '+', '%', '@', '&', '~' ])[num] , num ) for num in range( 6 ) )
  169.        
  170.         def add_command( self, command, level, func, short=None ):
  171.                 """ Adds a new command. command and short are names for
  172.                        the command, used as ![command/short] and [COMMAND/SHORT].
  173.                        level is a numeric user level and func a function pointer.
  174.                      
  175.                        The docstring of func will be used by the help command, the
  176.                        first line shows up in the list, the rest only when
  177.                        specifically targetting the command. Format your docstring
  178.                        like this: '{0}!X!- Update the Voice/HOP/OP info manually'
  179.                        You can use {0}-{9} for the parameters passed to help ( {0}
  180.                        is the command itself ) and !X! for the point where the text
  181.                        is left-justified."""
  182.                 self.commands[ command.lower() ] = ( level, func )
  183.                 if short is not None:
  184.                         self.commands[ short.lower() ] = ( level, func )
  185.                 print "Added commmand " + command + ", level " + level + ", func " + func.__name__
  186.        
  187.         def on_welcome( self, event ):
  188.                 self.identify( "topSecretChariPass" ) # authenticate with nickserv
  189.  
  190.         def on_reply( self, event ):
  191.                 if event.command == "RPL_NAMREPLY": # NAMES' reply. used for updating permissions
  192.                         self.channelusers[ event.params[1] ] = event.params[2].split()
  193.        
  194.         def on_join( self, event ):
  195.                 if event.source != self.nickname: # don't welcome yourself
  196.                         self.send_message( event.target, "Welcome to " + format.color( format.bold( ' LTFU :' ), format.BLACK, format.LIGHT_GRAY ) + format.color( ': hangout ', format.WHITE, format.GREEN ) + ", " +  format.bold( event.source ) )
  197.  
  198.         def on_channel_message( self, event ):
  199.                 message = event.message.split()
  200.                 command = message[0]
  201.                 params  = message[1:]
  202.                
  203.                 if len( command ) == 1: # skip single !'s and stuff
  204.                         return
  205.                
  206.                 if command[0] == "!": # only handle commands directed to us...
  207.                         command =  command[1:].lower()
  208.                         if command in self.commands: # ... that exist
  209.                                 self.execute( "NAMES", event.target ) # update permissions
  210.                                 ( level, func ) = self.commands[ command ]
  211.  
  212.                                 for name in self.channelusers[ event.target ]:
  213.                                         if protocol.strip_name_symbol( name ) == event.source: break # name is now event.target's name
  214.                                
  215.                                 ulevel = 0
  216.                                 if name[0] in self.access: # do not handle 'empty' users
  217.                                         ulevel = self.access[ name[0] ]
  218.                                        
  219.                                 if  ulevel < self.access[ level ]:
  220.                                         self.send_message( event.target, format.color( "ERROR:", format.RED ) + " You are not allowed to use the " + format.bold( command ) + " Command" )
  221.                                         return
  222.                                 func( self, command, params, event )
  223.                         else:
  224.                                 self.send_message( event.target, format.color( "ERROR:", format.RED ) + " Command " + format.bold( command ) +" not found" )
  225.                                
  226.                
  227.         def on_private_message( self, event ):
  228.                 message = event.message.split()
  229.                 command = message[0].upper()
  230.                 params  = message[1:]
  231.  
  232.                 if command.lower() in self.commands:
  233.                         self.execute( "NAMES", "#ltfu" ) # update permissions
  234.                         ( level, func ) = self.commands[ command.lower() ]
  235.                        
  236.                         for name in self.channelusers[ "#ltfu" ]:
  237.                                 if protocol.strip_name_symbol( name ) == event.source: break # name is now event.target's name
  238.                        
  239.                         ulevel = 0
  240.                         if name[0] in self.access: # do not handle 'empty' users
  241.                                 ulevel = self.access[ name[0] ]
  242.  
  243.                         if ulevel < self.access[ level ]:
  244.                                 self.send_message( event.source, format.color( "ERROR:", format.RED ) + " You are not allowed to use the " + format.bold( command ) + " Command" )
  245.                                 return
  246.                         func( self, command, params, event, received="private" ) # tell the function this was a private message and call it
  247.                 else:
  248.                         self.send_message( event.source, format.color( "ERROR:", format.RED ) + " Command " + format.bold( command ) + " not found" )
  249.  
  250.  
  251.  
  252. banners = {
  253. "blame_end": ( format.RED, [
  254.     "                                                                       ",
  255.     "   __________.__                          ___________           .___   ",
  256.     "   \______   \ | _____    _____   ____   \_   _____/ ____    __| _/   ",
  257.     "    |    |  _/  | \__  \ /     \_/ __ \  |    __)_ /    \ / __ |    ",
  258.     "    |    |   \ |__/ __ \|  Y Y  \ ___/   |        \  |  \/ /_/ |    ",
  259.     "    |______  /____(____  /__|_|  /\___  > /_______  /___|  /\____ |    ",
  260.     "           \/          \/      \/     \/          \/     \/      \/    ",
  261.     "                                                                       ",
  262.     "                                              (seriously, blame end)   "
  263.     ]),
  264. "ltfu": ( format.GREEN, [
  265.     " .____           __  .__                       _____.__            .___                  ",
  266.     " |    |    _____/  |_|  |__   ____   _____   _/ ____\__| ____    __| _/    __ __  ______ ",
  267.     " |    |  _/ __ \  __\ |  \_/ __ \ /     \ \  __\|  |/    \ / __ |    |  |  \/  ___/ ",
  268.     " |    |__\ ___/|  | |   Y  \ ___/|  Y Y  \ |  |  |  |   |  \/ /_/ |    |  |  /\___ \ ",
  269.     " |_______ \___  >__| |___|  /\___  >__|_|  /  |__|  |__|___|  /\____ | /\ |____//____  > ",
  270.     "         \/   \/          \/     \/      \/                 \/      \/ \/            \/  ",
  271.     "                                                                           lethemfind.us "
  272.     ])
  273. }
  274.  
  275.  
  276. ############################### RUN #################################
  277.  
  278. if __name__ == "__main__":
  279.         charitum = Charitum( "Charitum" )
  280.         charitum.connect( "irc.freenode.net", channel=["#ltfu"] )
  281.        
  282.  
  283.         charitum.add_command( "execute", "~", cmd_exec, "exec" )
  284.         charitum.add_command( "say", "@", cmd_say, "!" )
  285.         charitum.add_command( "shout", "@", cmd_shout, "!!" )
  286.         charitum.add_command( "kick", "@", cmd_kick )
  287.         charitum.add_command( "op", "@", cmd_op )
  288.         charitum.add_command( "banner", "", cmd_banner )
  289.         charitum.add_command( "update", "", cmd_update, "upd" )
  290.         charitum.add_command( "help", "", cmd_help )
  291.        
  292.         signal.signal( signal.SIGINT,  callback_shutdown ) # register graceful shutdown here
  293.        
  294.         charitum.start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement