Python
  Home arrow Python arrow Basic IRC Tasks
FaxWave - Free Trial.
Dev Shed Forums 
Administration  
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 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Download TestComplete 
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: 5 stars5 stars5 stars5 stars5 stars / 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:
      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

    The Web Buyer's Guide is your best source for white papers on a wide range of IT products and services. This Week's Featured White Papers: Building a Virtual Infrastructure from Servers to Storage by Network Appliance

    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


       · One thing though, your code does not take into account the IRC PING command, so your...
       · The source (...!...@...) on the beginning of the message is not mandatory. The first...
     

       

    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...

     
    Accelerating Trading Partner Performance
     
    Competing on Analytics
     
    Cost Effective Scaling with Virtualization and Coyote Point Systems
     
    Five Checkpoints to Implementing IP Telephony
     
    Hosted Email Security: Staying Ahead of New Threats
     




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