Python
  Home arrow Python arrow Page 4 - IRC on a Higher Level Concluded
Dev Shed Forums 
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Forums Sitemap 
IBM® developerWorks 
Sun Developer Network 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Actuate Whitepapers 
VeriSign Whitepapers 
VPS Hosting 
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PYTHON

IRC on a Higher Level Concluded
By: Peyton McCullough
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 5
    2005-10-26

    Table of Contents:
  • IRC on a Higher Level Concluded
  • SingleServerIRCBot
  • Channel Information
  • Something Practical

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT

    Stay one step ahead of the competition. Evaluate and give feedback on some of the hottest web development tools on the market today. Make your opinion heard! Click Here

    IRC on a Higher Level Concluded - Something Practical


    (Page 4 of 4 )

    Let's take a look at something a bit more practical now: a full-fledged IRC bot capable of accepting commands from users. If that doesn't sound interesting, then let's take things one step futher: a bot that responds to users based on external scripts that can be loaded and reloaded on-the-fly.

    Our bot will scan a directory, “commands”, for Python files. It will load these files as modules and store them in a dictionary. If a user prefixes the bot's name with a dollar symbol ( for example, “$PyBot” ), then the bot will examine the incoming message for a second argument. If a second argument is present, it will be compared to the dictionary of modules. If a module's name matches the command, the index function of the module will be called, and the connection and event type will be passed. Also, if we receive a CTCP command whose name matches a special password, the bot will rescan. Let's translate this to Python:

    import glob
    import ircbot
    import imp

    # Bot scan password
    password = 'd3vsh3d0652'

    # Connection informatoin
    network = 'irc.freenode.net'
    port = 6667
    channel = '#irclib'
    nick = 'PyBot'
    name = 'Python Bot'

    # We'll store the commands here
    commands = {}

    # Scan the "commands" directory and load the modules
    def scan():
       commands.clear()
       for moduleSource in glob.glob ( 'commands/*.py' ):
          name = moduleSource.replace ( '.py', '' ).replace ( '\\',
    '/' ).split ( '/' ) [ 1 ].upper()
          handle = open ( moduleSource )
          module = imp.load_module ( 'COMMAND', handle, ( 'commands/'
    + moduleSource ), ( '.py', 'r', imp.PY_SOURCE ) )
          commands [ name ] = module

    # Create our bot class
    class ModularBot ( ircbot.SingleServerIRCBot ):

       # Join a channel when welcomed
       def on_welcome ( self, connection, event ):
          connection.join ( channel )

       # Listen to public messages
       # If the user says our name, prefixed with "$", then we act
       def on_pubmsg ( self, connection, event ):
          if event.arguments() [ 0 ].split() [ 0 ].upper() == ( '$' +
    nick.upper() ):

              # See if the user specified a valid command
              # If so, call the module
              if len ( event.arguments() [ 0 ].split() ) == 1:
                 pass
              elif commands.has_key ( event.arguments() [ 0 ].split()
    [ 1 ].upper() ):
                 commands [ event.arguments() [ 0 ].split()
    [ 1 ].upper() ].index ( connection, event )

       # Listen to CTCP messages for the scan password
       # If we get it, rescan
       def on_ctcp ( self, connection, event ):
          if event.arguments() [ 0 ] == password.upper():
             scan()

    # Scan for commands
    scan()

    # Create the bot and run it
    bot = ModularBot ( [( network, port )], nick, name )
    bot.start()

    There are no suprises, the bot works exactly in the way I explained above. Now, all that's left is giving the bot a few commands to work with. To begin, let's start with an “about” command. To implement this, we simply create a file called “about.py” and place it in the “commands” directory, filling an index function with the appropriate information:

    def index ( connection, event ):
       connection.privmsg ( event.source().split ( '!' ) [ 0 ], 'I am
    an IRC bot built in Python.' )
       connection.privmsg ( event.source().split ( '!' ) [ 0 ], 'I am
    modular and can load command modules on the fly.' )

    The module will be automatically loaded when the bot is started up. Alternatively, we can have it reload the module by using this command in an IRC client:

    /ctcp PyBot d3vsh3d0652

    Pretty neat, huh? Of course, we can create commands that accept additional arguments as well. Consider a command that accepts a number and then attempts to square it:

    def index ( connection, event ):

       # Do we have an extra argument?
       # If not, complain
       if len ( event.arguments() [ 0 ].split() ) == 2:
          connection.privmsg ( event.source().split ( '!' ) [ 0 ],
    'Please include a number.' )

       # Try to square the number and return it to the user
       else:
          try:
             number = float ( event.arguments() [ 0 ].split() [ 2 ] )
             number = number ** 2
             connection.privmsg ( event.source().split ( '!' ) [ 0 ],
    str ( number ) )
          except:
             pass

    Conclusion

    While working directly with the IRC protocol can get the job done, development can be messy and slow. The Python-IRCLib library exists between your applications and the IRC protocol, allowing you to take an object-oriented approach to the IRC protocol. It ensures that the result is quickly put together, compact and clean.

    The library allows you to work with the protocol on several levels. In this article, we explored the top-most level of interaction: objects that act as clients, automating much of the dirty or otherwise repetitive work. You now have the skill necessary to develop a wide variety of IRC applications fit for just about any task you can think of –- whether it is recording statistics about users or accepting commands and interacting with users.

    We also built a modular IRC bot. Feel free to use it and modify it as you see fit. If you wish to share any modifications or modules to the bot –- or information about any IRC project –- then please e-mail me because I would love to hear about it. One simple modification to the bot might be a help command, which lists the supported commands or calls a certain method of the modules.

    There is one thing you should remember though: bots are nice, but the niceness can quickly wear off. Never build an overly-annoying application, and never seek to use a bot for malicious purposes.


    DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

       · This article is the final article in this short series, dealing with some helpful...
       · The scan function is:def scan(): commands.clear() for moduleSource in...
       · Peyton:your tutorials have been really helpful as there really is no documentation...
     

       

    PYTHON ARTICLES

    - SSH with Twisted
    - Mobile Programming in Python using PyS60: UI...
    - Python: Count on It
    - Python Strings: Spinning Yarns
    - Python: More Fun with Strings
    - Python: Stringing You Along
    - Python Operators
    - Bluetooth Programming in Python: Network Pro...
    - Python Sets
    - Python Conditionals, Lists, Dictionaries, an...
    - Python: Input and Variables
    - Introduction to Python Programming
    - Mobile Programming in Python using PyS60: Ge...
    - Bluetooth Programming using Python
    - Finishing the PyMailGUI Client: User Help To...





    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway