Python
  Home arrow Python arrow Basic IRC Tasks
Dev Shed Forums  
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Smartphone Development  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Mobile Linux  
App Generation ROI  
IBM® developerWorks  
Forums Sitemap  
E-Commerce Hosting  
Linux Web Hosting  
Managed Hosting  
Small Business Hosting  
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

Basic IRC Tasks
By: Peyton McCullough
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: starstarstarstarstar / 3
    2005-04-18


    Table of Contents:
  • Basic IRC Tasks
  • Communication Tasks
  • Channel Related Tasks
  • User Related Tasks
  • Processing Information

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      error-file:tidyout.log Del.ici.ous error-file:tidyout.log Digg
      error-file:tidyout.log Blink error-file:tidyout.log Simpy
      error-file:tidyout.log Google error-file:tidyout.log Spurl
      error-file:tidyout.log Y! MyWeb error-file:tidyout.log 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


    Basic IRC Tasks
    ( Page 1 of 5 )

    Following up on an earlier DevShed article covering the basics of Python and Internet Relay Chat, this article takes some common IRC tasks, such as listing the users in a given channel or manipulating a channel's modes, and shows how to turn them into Pyton code.

    Introduction

    In “Python and IRC,” I explained the basics of connecting to an IRC server and sending a few messages. Obviously, however, you know that there is much more to IRC than I explained. Forgive the cliché, but what the last article covers is truly only the tip of the iceberg that is the Internet Relay Chat Protocol.

    This article will cover some more basics. We'll take some common tasks, such as listing the users in a given channel or manipulating a channel's modes, and turn them into Python code. If you haven't read “Python and IRC,” this article won't do you much good. Even if you have, it might be helpful to speed through it and refresh your memory. With that said, let's move on.

    Creating an IRC Module

    If I loaded each and every example in this article with basic socket garbage, not only would it be incredibly pointless, but it would be annoying and difficult to sort through to actually get the important stuff. The solution is to create a module that will do all the socket work for us. Actually, scratch that, why not turn this article a bit and build a module that will do socket work and basic IRC tasks? That sounds a lot better, and, as a bonus, all the code we produce can be recycled in future applications.

    Let's call our module irchat. In ths module, let's create a class, IRC. Our code will be put into IRC's methods. When an instance of IRC is created, Python will automatically connect to the network specified in the arguments, using the data specified in the arguments. To avoid repetition of “\r\n”, we'll create a send method that automatically appends “\r\n” to the given text and then sends it over. To connect to the server, we're going to have to specify a nickname using IRC's “NICK” command. Since you may want your Python client to use the “NICK” command again, we'll make a method for it. A quit method would also be helpful. Enough lecturing, though, let's get to some code:

    import socket

    class IRC:

       def __init__ ( self, network, port, name, hostName, serverName, realName ):

          self.network =  network

          self.port = port

          self.hostName = hostName

          self.serverName = serverName

          self.realName = realName

          self.socket = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )

          self.socket.connect ( ( self.network, self.port ) )

          self.nick ( name )

          self.send ( 'USER ' + self.name + ' ' + self.serverName + ' ' + self.hostName + ' :' + self.realName )

       def quit ( self ):

          self.send ( 'QUIT' )

          self.socket.close()

       def send ( self, text ):

          self.socket.send ( text + '\r\n' )

       def nick ( self, name ):

          self.name = name

          self.send ( 'NICK ' + self.name )

    The above module will handle the very basics. When an instance of IRC is created and the required data is passed to it, a socket is created and connected. The nickname is then set using the nick method, which takes advantage of the send method. The “USER” command is then sent. No suprises there.

    To use the module, you would do something like this:

    import irchat

    conn = irchat.IRC ( 'irc.network.com', 6667, 'PyIRC', 'PyIRC', 'PyIRC', 'John Doe' )

    # Insert code here

    conn.quit()

    From here on, we will be adding methods to the IRC class. Keep that in mind. Don't go off and create lone functions and later wonder why nothing happens.

    Let's catch up with “Python and IRC” now. One of the most important things that “Python and IRC” teaches us is how to receive messages from the server and take them apart, making them easier to process. To do this, we must first create a method, recv, which receives data from the network and then splits it up. The data should be split at “\r\n” (which effectively splits it into commands) and added to a variable, queue. Remember that data will get cut off, too, so we have to store partial data in a variable, partial, and let it get picked up by queue on the next call to recv. This may sound complicated, but it's pretty simple:

    queue = []

    partial = ''

    def recv ( self, size = 2048 ):

    commands = self.socket.recv ( size ).split ( '\r\n' )

    if len ( self.partial ):

       commands [ 0 ] = self.partial + commands [ 0 ]

       self.partial = ''

    if len ( commands [ -1 ] ):

       self.partial = commands [ -1 ]

       self.queue.extend ( commands [ :-1 ] )

    else:

       self.queue.extend ( commands )

    We must now create a method, retrieve, that pops the first command off of queue and returns it. If the queue is empty, the method should return False:

    def retrieve ( self ):

       if len ( self.queue ):

          command = self.queue [ 0 ]

          self.queue.pop ( 0 )

          return command

       else:

          return False

    Finally, we have to create a method that dismantles individual commands into something more workable. Recall what a message from the server looks like:

    :source some parameters

    :source some parameters :another parameter

    Pulling that apart isn't too complicated, although it may seem like it. If we split the string in the correct places, we can manage:

    def dismantle ( self, command ):

       if command:

          source = command.split ( ':' ) [ 1 ].split ( ' ' ) [ 0 ]

          parameters = command.split ( ':' ) [ 1 ].split ( ' ' ) [ 1: ]

          if not len ( parameters [ -1 ] ):

             parameters.pop()

          if command.count ( ':' ) > 1:

             parameters.append ( ''.join ( command.split ( ':' ) [ 2: ] ) )

          return source, parameters

    To clarify, the irchat module should now look something like this:

    import socket

    class IRC:

       queue = []

       partial = ''

       def __init__ ( self, network, port, name, hostName, serverName, realName ):

          self.network =  network

          self.port = port

          self.hostName = hostName

          self.serverName = serverName

          self.realName = realName

          self.socket = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )

          self.socket.connect ( ( self.network, self.port ) )

          self.nick ( name )

          self.send ( 'USER ' + self.name + ' ' + self.serverName + ' ' + self.hostName + ' :' + self.realName )

       def quit ( self ):

          self.send ( 'QUIT' )

          self.socket.close()

       def send ( self, text ):

          self.socket.send ( text + '\r\n' )

       def nick ( self, name ):

          self.name = name

          self.send ( 'NICK ' + self.name )

       def recv ( self, size = 2048 ):

          commands = self.socket.recv ( size ).split ( '\r\n' )

          if len ( self.partial ):

             commands [ 0 ] = self.partial + commands [ 0 ]

             self.partial = ''

          if len ( commands [ -1 ] ):

             self.partial = commands [ -1 ]

             self.queue.extend ( commands [ :-1 ] )

          else:

             self.queue.extend ( commands )

       def retrieve ( self ):

          if len ( self.queue ):

             command = self.queue [ 0 ]

             self.queue.pop ( 0 )

             return command

          else:

             return False

       def dismantle ( self, command ):

          if command:

             source = command.split ( ':' ) [ 1 ].split ( ' ' ) [ 0 ]

             parameters = command.split ( ':' ) [ 1 ].split ( ' ' ) [ 1: ]

             if not len ( parameters [ -1 ] ):

                parameters.pop()

             if command.count ( ':' ) > 1:

                parameters.append ( ''.join ( command.split ( ':' ) [ 2: ] ) )

             return source, parameters

    Here's one way to use our new module. The following script connects to an IRC network and spawns a thread to constantly call the recv module, which, as you know, puts commands into the queue list. It then dismantles the data and prints it out in a neater form:

    import irchat

    import thread

    def autoRecv():

       while True:

          conn.recv()

    conn = irchat.IRC ( 'irc.network.com, 6667, 'PyBot', 'PyBot', 'PyBot', 'John Doe' )

    thread.start_new_thread ( autoRecv, () )

    while True:

       x = conn.dismantle ( conn.retrieve() )

       if x:

          print x [ 0 ] + ':', x [ 1 ]

          print

    Let's move on. 



     
     
    >>> More Python Articles          >>> More By Peyton McCullough
     

       

    PYTHON ARTICLES

    - Tuples and Other Python Object Types
    - The Dictionary Python Object Type
    - String and List Python Object Types
    - Introducing Python Object Types
    - Mobile Programming using PyS60: Advanced UI ...
    - Nested Functions in Python
    - Python Parameters, Functions and Arguments
    - Python Statements and Functions
    - Statements and Iterators in Python
    - Sequences and Sets in Python
    - Python Expressions and Operators
    - Dictionaries, Variables and Statements in Py...
    - Data Types in Python
    - The Python Language
    - SSH with Twisted





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 5 Hosted by Hostway
    Stay green...Green IT