Python
  Home arrow Python arrow Page 3 - IRC on a Higher Level
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
By: Peyton McCullough
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 9
    2005-10-05

    Table of Contents:
  • IRC on a Higher Level
  • Getting Started
  • Events
  • All Supported Events

  • 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 - Events


    (Page 3 of 4 )

    Now that you know how to connect your application to an IRC network, you are probably wondering how to do something useful, namely how to process incoming information and respond appropriately to it. Before we get to that, though, it is important that you understand exactly what information is coming to you. Python-IRCLib will display information to and from the server if you simply add this line after you import irclib:

    irclib.DEBUG = True

    Try creating a program with the line and examining the incoming and outgoing data.

    Now we need to handle the data. Let's work on handling the data initially received from the server first. To do this, we register an event handler with the add_global_handler, passing two or three arguments. The first argument is the code that corresponds to the event we want to handle. We'll get to this in a second. The second argument points to the function that is to handle the event. The third argument is optional, and it is named priority. The lower the number is, the higher the priority of the event:

    import irclib

    # Connection information
    network = 'irc.freenode.net'
    port = 6667
    channel = '#irclib'
    nick = 'PyTest'
    name = 'Test One'

    # Generic echo handler ( space added )
    # This is used to output some initial information from the server
    def handleEcho ( connection, event ):

       print
       print ' '.join ( event.arguments() )

    # Generic echo handler ( no space added )
    def handleNoSpace ( connection, event ):

       print ' '.join ( event.arguments() )

    # Handle private notices
    def handlePrivNotice ( connection, event ):

       if event.source():
          print ':: ' + event.source() + ' ->' + event.arguments() [ 0 ]
       else:
          print event.arguments() [ 0 ]

    # Handle channel joins
    def handleJoin ( connection, event ):

       # The source needs to be split into just the name
       # It comes in the format nickname!user@host
       print event.source().split ( '!' ) [ 0 ] + ' has joined ' + event.target()

    # Create the IRC object
    irc = irclib.IRC()

    # Register handlers
    irc.add_global_handler ( 'privnotice', handlePrivNotice ) #
    Private notice
    irc.add_global_handler ( 'welcome', handleEcho ) # Welcome
    message
    irc.add_global_handler ( 'yourhost', handleEcho ) # Host message
    irc.add_global_handler ( 'created', handleEcho ) # Server
    creation message
    irc.add_global_handler ( 'myinfo', handleEcho ) # "My info"
    message
    irc.add_global_handler ( 'featurelist', handleEcho ) # Server feature list
    irc.add_global_handler ( 'luserclient', handleEcho ) # User count
    irc.add_global_handler ( 'luserop', handleEcho ) # Operator count
    irc.add_global_handler ( 'luserchannels', handleEcho ) # Channel
    count
    irc.add_global_handler ( 'luserme', handleEcho ) # Server client
    count
    irc.add_global_handler ( 'n_local', handleEcho ) # Server client
    count/maximum
    irc.add_global_handler ( 'n_global', handleEcho ) # Network
    client count/maximum
    irc.add_global_handler ( 'luserconns', handleEcho ) # Record
    client count
    irc.add_global_handler ( 'luserunknown', handleEcho ) # Unknown
    connections
    irc.add_global_handler ( 'motdstart', handleEcho ) # Message of
    the day ( start )
    irc.add_global_handler ( 'motd', handleNoSpace ) # Message of the
    day
    irc.add_global_handler ( 'edofmotd', handleEcho ) # Message of
    the day ( end )
    irc.add_global_handler ( 'join', handleJoin ) # Channel join
    irc.add_global_handler ( 'namreply', handleNoSpace ) # Channel
    name list
    irc.add_global_handler ( 'endofnames', handleNoSpace ) # Channel
    name list ( end )

    # Connect to the network
    server = irc.server()
    server.connect ( network, port, nick, ircname = name )
    server.join ( channel )

    # Run an infinite loop
    irc.process_forever()

    The above code may seem like a lot, but in reality, it's not. Before we create the IRC object, we define a few functions to handle certain events. Two are generic functions that merely echo the arguments of the received commands, and the other two are aimed at specific events. We then create the IRC object and register handlers for a number of events.

    The first events we handle are private notices. The server will issue several of these upon connection, so we need to find a way to display them. We then handle a number of messages that the server gives us upon connection. The messages mainly deal with statistics and features of the server, so I won't get into too much detail. They are pretty easy to analyze.

    When the server is about to send us the message of the day, it sends us the command “375”. Python-IRCLib translates this to “motdstart”. We'll be handling many numeric commands from the server, so I'll provide a list shortly. If the DEBUG variable is set to True, the library will display the translated command to us, too. The server then sends us the message of the day, followed by a command to end the message of the day.

    Our client is set to join the channel “#irclib”. When this happens, a message will be sent to the channel notifying its users of our presence. The function handleJoin handles this event. We simply take the source of the command and join it to the target of the command. We also break apart the source to get a more readable name. When we join the channel, the server sends a list of names to us, which we display with handleNoSpace.

    The handler functions are passed two arguments, an event object and a server object. The former contains the source of the command ( event.source ), the target of the command ( event.target ) and the arguments of the command ( event.arguments ). The latter is used in case we need to respond to the message sent. For example, let's consider an “INVITE” message from another user. It is simply a message from the user inviting us to join a certain channel. We could set up a handler that would automatically join the channel like this:

    def handleInvite ( connection, event ):

       connection.join ( event.arguments() [ 0 ] )

    ...

    irc.add_global_handler ( 'invite', handleInvite ) # Invite

    Our application is, of course, far from complete if we're looking to handle even the more common events. We still have more events to consider. For example, if someone sends a message to use or the channel, it would be wise to display or consider a reply:

    # Private messages
    def handlePrivMessage ( connection, event ):

       print event.source().split ( '!' ) [ 0 ] + ': ' + event.arguments() [ 0 ]

       # Respond to a “hello” message
       if event.arguments() [ 0 ].lower().find ( 'hello' ) == 0:
          connection.privmsg ( event.source().split ( '!' ) [ 0 ],
    'Hello.' )

    # Public messages
    def handlePubMessage ( connection, event ):

       print event.target() + '> ' + event.source().split ( '!' ) [ 0 ] + ': ' +
    event.arguments() [ 0 ]

    ...

    irc.add_global_handler ( 'privmsg', handlePrivMessage )
    irc.add_global_handler ( 'pubmsg', handlePubMessage )

    Another common event would be someone changing the topic of a channel. This event could easily be caught:

    def handleTopic ( connection, event ):

       print event.source().split ( '!' ) [ 0 ] + ' has set the topic
    to "' + event.arguments() [ 0 ] + '"'

    ...

    irc.add_global_handler ( 'topic', handleTopic )

    Another common event would be a mode change to either a channel or a user. This bit of code will catch the event and display the appropriate message:

    def handleMode ( connection, event ):

       # Channel mode
       if len ( event.arguments() ) < 2:
          print event.source().split ( '!' ) [ 0 ] + ' has altered
    the channel\'s mode: ' + event.arguments() [ 0 ]

       # User mode
       else:
          print event.source().split ( '!' ) [ 0 ] + ' has altered '
    + event.arguments() [ 1 ] + '\'s mode: ' + event.arguments()
    [ 0 ]

    ...

    irc.add_global_handler ( 'mode', handleMode )

    Of course, the users of a network will leave channels, and we should learn how to catch such an event. A user may part a channel, disconnect from the network or be removed from the channel by an operator, so we should consider all three events:

    def handlePart ( connection, event ):

       print event.source().split ( '!' ) [ 0 ] + ' has quit ' +
    event.target()

    def handleQuit ( connection, event ):

       print event.source().split ( '!' ) [ 0 ] + ' has disconnected:
    ' + event.arguments() [ 0 ]

    def handleKick ( connection, event ):

       print event.arguments() [ 0 ] + ' has been kicked by ' +
    event.source().split ( '!' ) [ 0 ] + ': ' + event.arguments()
    [ 1 ]

    ...

    irc.add_global_handler ( 'part', handlePart )
    irc.add_global_handler ( 'quit', handleQuit )
    irc.add_global_handler ( 'kick', handleKick )

    Now our application should be sensitive to a variety of common events. Each handler function can be modified to perform an appropriate action. For examle, if you wanted to welcome users to the channel when they join, you would simply modify whatever function is attached to the event “join”.

    Sometimes, you'll want to unbind a function. For example, let's say you wanted to remove handleKick from the “kick” event. You would call the remove_global_handler method, which takes the same arguments as add_global_handler:

    irc.remove_global_handler ( 'kick', handleKick )

    More Python Articles
    More By Peyton McCullough


       · Hello, all.I've always been interested in playing around with IRC, and Python...
       · I just finished writing a game-playing bot using irclib. Well, perhaps finished is...
       · As the topic says, how does one detect time outs and other disconnection errors?
     

       

    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 4 hosted by Hostway