Example #1
0
    def pkt_part(self, event):
        """ Received a part packet.
            
            Similar to ``pkt_join``. This method determines whether or
            not the client is being kicked off the server.
        """
        if event.arguments['ns'] in self.channel.keys():
            del self.channel[event.arguments['ns']]

        if len(self.channel) > 0:
            return

        if 'r' in event.arguments:
            if event.arguments['r'] in ('bad data', 'bad msg', 'msg too big'
                                        ) or 'killed:' in event.arguments['r']:
                self.handle_pkt(
                    Packet('disconnect{0}e={1}{2}{3}'.format(
                        "\n", event.arguments['r'], "\n", "\n")), time.time())
                return

        if event.arguments['e'] != 'ok':
            return

        if self.channel or self.flag.disconnecting or self.flag.quitting:
            return

        self.handle_pkt(Packet('disconnect\ne=no joined channels\n\n'),
                        time.time())
Example #2
0
 def process_property(self, data):
     """ Called when receive a property packet for the channel.
         
         This method makes sure that the data is stored in the right
         places in the object.
     """
     if data.arguments['p'] == 'title':
         self.title.content = data.arguments['value']
         self.title.by = data.arguments['by']
         self.title.ts = data.arguments['ts']
     
     if data.arguments['p'] == 'topic':
         self.topic.content = data.arguments['value']
         self.topic.by = data.arguments['by']
         self.topic.ts = data.arguments['ts']
     
     if data.arguments['p'] == 'privclasses':
         self.pc = Packet(data.arguments['value'], ':').args
         self.pc_order = sorted(self.pc.keys(), key=int)
         self.pc_order.reverse()
     
     if data.arguments['p'] == 'members':
         member = Packet(data.arguments['value'])
         while member.cmd != None and len(member.args) > 0:
             self.register_user(member)
             member = Packet(member.body)
Example #3
0
 def process_property(self, data):
     """ Called when receive a property packet for the channel.
         
         This method makes sure that the data is stored in the right
         places in the object.
     """
     if data.arguments['p'] == 'title':
         self.title.content = data.arguments['value']
         self.title.by = data.arguments['by']
         self.title.ts = data.arguments['ts']
     
     if data.arguments['p'] == 'topic':
         self.topic.content = data.arguments['value']
         self.topic.by = data.arguments['by']
         self.topic.ts = data.arguments['ts']
     
     if data.arguments['p'] == 'privclasses':
         self.pc = Packet(data.arguments['value'], ':').args
         self.pc_order = sorted(self.pc.keys(), key=int)
         self.pc_order.reverse()
     
     if data.arguments['p'] == 'members':
         member = Packet(data.arguments['value'])
         while member.cmd != None and len(member.args) > 0:
             self.register_user(member)
             member = Packet(member.body)
Example #4
0
    def dataReceived(self, data):
        """ Called by twisted when data is received.
            
            The data received is added to out buffer. If there are any full
            packets in the buffer, these packets are sent to the
            :py:class:`ChatClient <dAmnViper.base.ChatClient>` instance to be
            parsed properly.
            
            Any event handling relating to specific packets is done in the
            ``ChatClient`` instance.
        """

        # Tell the client some data has arrived. Woo...
        self.client.dataReceived(data)

        # Split on null.
        self.__buffer += data
        raw = self.__buffer.split('\0')
        self.__buffer = raw.pop()

        for chunk in raw:
            packet = Packet(chunk)

            # If it's a ping packet, send a pong straight away!
            if packet.cmd == 'ping':
                self.send_packet('pong\n')

            # Let the client do whatever it needs to with the packet.
            self.client.handle_pkt(packet, time.time())
Example #5
0
class Channel:
    """ Objects representing dAmn channels.
        Information about the channels are stored in here.
    """
    
    class header:
        def __init__(self):
            self.content = ''
            self.by = ''
            self.ts = 0.0
    
    def __init__(self, namespace, shorthand):
        """Set up all our variables."""
        self.title = Channel.header()
        self.topic = Channel.header()
        self.pc = {}
        self.pc_order = []
        self.member = {}
        
        self.namespace = namespace
        self.shorthand = shorthand
        
        self.type = '<dAmn channel \''+self.namespace+'\'>'
    
    def process_property(self, data):
        if data['p'] == 'title':
            self.title.content = data['value']
            self.title.by = data['by']
            self.title.ts = data['ts']
        if data['p'] == 'topic':
            self.topic.content = data['value']
            self.topic.by = data['by']
            self.topic.ts = data['ts']
        if data['p'] == 'privclasses':
            self.pc = Packet(data['value'], ':').args
            self.pc_order = sorted(self.pc.keys(), key=int)
            self.pc_order.reverse()
        if data['p'] == 'members':
            member = Packet(data['value'])
            while member.cmd != None and len(member.args) > 0:
                self.register_user(member)
                member = Packet(member.body)
    
    def register_user(self, info, user = None):
        user = user if user != None else info.param
        if user in self.member:
            self.member[user]['con']+= 1
        else:
            self.member[user] = info.args
            self.member[user]['con'] = 1
    
    def __str__(self):
        return self.namespace

# EOF
Example #6
0
 def pkt_recv_join(self, event):
     """ Received a recv_join packet.
         
         This happens when a user joins a channel in which the client
         is also present.
         
         This method simply stores information about the user that
         just joined.
     """
     self.channel[event.arguments['ns']].register_user(
         Packet(event.arguments['info']), event.arguments['user'])
Example #7
0
 def process_property(self, data):
     if data['p'] == 'title':
         self.title.content = data['value']
         self.title.by = data['by']
         self.title.ts = data['ts']
     if data['p'] == 'topic':
         self.topic.content = data['value']
         self.topic.by = data['by']
         self.topic.ts = data['ts']
     if data['p'] == 'privclasses':
         self.pc = Packet(data['value'], ':').args
         self.pc_order = sorted(self.pc.keys(), key=int)
         self.pc_order.reverse()
     if data['p'] == 'members':
         member = Packet(data['value'])
         while member.cmd != None and len(member.args) > 0:
             self.register_user(member)
             member = Packet(member.body)
 def test_construct_packet(self):
     """ Test constructing packets using the packet object. """
     packet = Packet()
     
     packet.cmd = 'command'
     packet.param = 'parameter'
     packet.args['argument'] = 'value'
     packet.body = 'body'
     
     raw = packet.compile()
     
     self.failIf(raw != 'command parameter\nargument=value\n\nbody',
         'Packet object failed to correctly construct the raw packet')
Example #9
0
    def pkt_kicked(self, event):
        """ Received a kicked packet.
            
            This happens when the client is kicked from a channel.
            
            Here we automatically rejoin the channel if we are permitted
            to do so.
        """
        del self.channel[event.arguments['ns']]
        if self.flag.disconnecting or self.flag.quitting:
            return

        if 'r' in event.arguments:
            if 'autokicked' in event.arguments['r'].lower(
            ) or 'not privileged' in event.arguments['r'].lower():
                if len(self.channel) > 0:
                    return
                self.handle_pkt(Packet('disconnect\ne=no joined channels\n\n'),
                                time.time())
                return

        if self.flag.autorejoin:
            self.join(event.arguments['ns'])
Example #10
0
    def pkt_join(self, event):
        """ Received a join packet.
            
            This is sent by the server when the client tries to join a
            channel on the server.
            
            If the join was successful, a :py:class:`Channel object
            <dAmnViper.data.Channel>` is created for the channel and
            stored in the ``channel`` attribute of the client.
            
            If the join failed, the client disconnects if there are no
            other joined channels. (``naive``)
        """
        if event.arguments['e'] == 'ok':
            ns = event.arguments['ns']
            self.channel[ns] = Channel(ns, self.deform_ns(ns))
            return

        if len(self.channel) > 0:
            return

        self.handle_pkt(Packet('disconnect\ne=no joined channels\n\n'),
                        time.time())
Example #11
0
class Channel(object):
    """ Objects representing dAmn channels.
    
        Information about the channels are stored in here. The different
        attributes of the object are as follows:
        
        * ``title`` - This is an instance of the class
          ``Channel.header``, and stores information about the title of
          the channel. The object has the attributes ``content``, ``by``
          and ``ts``. These store the content of the title, the person
          who set the title, and the timestamp from when they set it,
          respectively.
        * ``topic`` - Similar to the ``title`` attribute, but it stores
          information about the channel's topic, as opposed to the
          channel's title.
        * ``pc`` - Stores information about the channel's privclasses.
        * ``pc_order`` - A list storing the the privclass names in order
          of hierarchy. This is to allow applications to display
          information more easily if needed.
        * ``member`` - A dictionary storing information about each user
          currently in the channel.
        * ``namespace`` - The channel's full namespace. This is usually
          a string in the form ``chat:channel_name``. This can differ
          depending on the type of channel the object represents.
        * ``shorthand`` - The shorthand form of the channel
          ``namespace``. This is usually a string in the format
          ``#channel_name`` if the namespace is of the format
          ``chat:channel_name``. This can differ depending on the type
          of channel the object represents.
        * ``type`` - A string in for format ``<dAmn channel
          'namespace'>`` where ``namespace`` is the same as the object's
          ``namespace`` attribute.
        
        Calling ``str(channel)``, where ``channel`` is an instance of
        the ``Channel`` class, returns the ``namespace`` attribute.
        
        As an example, here is what some of the attributes would look
        like for the **#Botdom** channel when the object is created::
            
            >>> channel = Channel('chat:Botdom', '#Botdom')
            >>> channel.namespace
            'chat:Botdom'
            >>> channel.shorthand
            '#Botdom'
            >>> str(channel)
            'chat:Botdom'
        
        The other attributes would be empty objects of their respective
        types until the appropriate data is received from the server.
    """
    
    class Header:
        def __init__(self):
            self.content = ''
            self.by = ''
            self.ts = 0.0
    
    def __init__(self, namespace, shorthand):
        """Set up all our variables."""
        self.title = Channel.Header()
        self.topic = Channel.Header()
        self.pc = {}
        self.pc_order = []
        self.member = {}
        
        self.namespace = namespace
        self.shorthand = shorthand
        
        self.type = '<dAmn channel \''+self.namespace+'\'>'
    
    def process_property(self, data):
        """ Called when receive a property packet for the channel.
            
            This method makes sure that the data is stored in the right
            places in the object.
        """
        if data.arguments['p'] == 'title':
            self.title.content = data.arguments['value']
            self.title.by = data.arguments['by']
            self.title.ts = data.arguments['ts']
        
        if data.arguments['p'] == 'topic':
            self.topic.content = data.arguments['value']
            self.topic.by = data.arguments['by']
            self.topic.ts = data.arguments['ts']
        
        if data.arguments['p'] == 'privclasses':
            self.pc = Packet(data.arguments['value'], ':').args
            self.pc_order = sorted(self.pc.keys(), key=int)
            self.pc_order.reverse()
        
        if data.arguments['p'] == 'members':
            member = Packet(data.arguments['value'])
            while member.cmd != None and len(member.args) > 0:
                self.register_user(member)
                member = Packet(member.body)
    
    def register_user(self, info, user = None):
        """ Called when a user joins the channel.
            
            Simply store their information in the ``member`` dictionary.
        """
        user = user if user != None else info.param
        if user in self.member:
            self.member[user]['con']+= 1
        else:
            self.member[user] = info.args
            self.member[user]['con'] = 1
    
    def __str__(self):
        return self.namespace
Example #12
0
class Channel(object):
    """ Objects representing dAmn channels.
    
        Information about the channels are stored in here. The different
        attributes of the object are as follows:
        
        * ``title`` - This is an instance of the class
          ``Channel.header``, and stores information about the title of
          the channel. The object has the attributes ``content``, ``by``
          and ``ts``. These store the content of the title, the person
          who set the title, and the timestamp from when they set it,
          respectively.
        * ``topic`` - Similar to the ``title`` attribute, but it stores
          information about the channel's topic, as opposed to the
          channel's title.
        * ``pc`` - Stores information about the channel's privclasses.
        * ``pc_order`` - A list storing the the privclass names in order
          of hierarchy. This is to allow applications to display
          information more easily if needed.
        * ``member`` - A dictionary storing information about each user
          currently in the channel.
        * ``namespace`` - The channel's full namespace. This is usually
          a string in the form ``chat:channel_name``. This can differ
          depending on the type of channel the object represents.
        * ``shorthand`` - The shorthand form of the channel
          ``namespace``. This is usually a string in the format
          ``#channel_name`` if the namespace is of the format
          ``chat:channel_name``. This can differ depending on the type
          of channel the object represents.
        * ``type`` - A string in for format ``<dAmn channel
          'namespace'>`` where ``namespace`` is the same as the object's
          ``namespace`` attribute.
        
        Calling ``str(channel)``, where ``channel`` is an instance of
        the ``Channel`` class, returns the ``namespace`` attribute.
        
        As an example, here is what some of the attributes would look
        like for the **#Botdom** channel when the object is created::
            
            >>> channel = Channel('chat:Botdom', '#Botdom')
            >>> channel.namespace
            'chat:Botdom'
            >>> channel.shorthand
            '#Botdom'
            >>> str(channel)
            'chat:Botdom'
        
        The other attributes would be empty objects of their respective
        types until the appropriate data is received from the server.
    """
    
    class Header:
        def __init__(self):
            self.content = ''
            self.by = ''
            self.ts = 0.0
    
    def __init__(self, namespace, shorthand):
        """Set up all our variables."""
        self.title = Channel.Header()
        self.topic = Channel.Header()
        self.pc = {}
        self.pc_order = []
        self.member = {}
        
        self.namespace = namespace
        self.shorthand = shorthand
        
        self.type = '<dAmn channel \''+self.namespace+'\'>'
    
    def process_property(self, data):
        """ Called when receive a property packet for the channel.
            
            This method makes sure that the data is stored in the right
            places in the object.
        """
        if data.arguments['p'] == 'title':
            self.title.content = data.arguments['value']
            self.title.by = data.arguments['by']
            self.title.ts = data.arguments['ts']
        
        if data.arguments['p'] == 'topic':
            self.topic.content = data.arguments['value']
            self.topic.by = data.arguments['by']
            self.topic.ts = data.arguments['ts']
        
        if data.arguments['p'] == 'privclasses':
            self.pc = Packet(data.arguments['value'], ':').args
            self.pc_order = sorted(self.pc.keys(), key=int)
            self.pc_order.reverse()
        
        if data.arguments['p'] == 'members':
            member = Packet(data.arguments['value'])
            while member.cmd != None and len(member.args) > 0:
                self.register_user(member)
                member = Packet(member.body)
    
    def register_user(self, info, user = None):
        """ Called when a user joins the channel.
            
            Simply store their information in the ``member`` dictionary.
        """
        user = user if user != None else info.param
        if user in self.member:
            self.member[user]['con']+= 1
        else:
            self.member[user] = info.args
            self.member[user]['con'] = 1
    
    def __str__(self):
        return self.namespace