irc.py
author Tero Marttila <terom@paivola.fi>
Wed, 26 Mar 2008 01:16:54 +0200
changeset 16 521fec9bb663
parent 13 ae9e6e894492
parent 15 e31e38d654b6
child 20 1711f40a7c39
permissions -rw-r--r--
git is starting to confuse me...

Merge commit 'refs/remotes/publish/master'

Conflicts:

irc.py

committer: Tero Marttila <terom@paivola.fi>
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
from twisted.words.protocols import irc
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
from twisted.internet import protocol
4
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
     3
from twisted.python import log
6
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
     4
import traceback
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
import buffer
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
13
ae9e6e894492 use notice instead of msg
Tero Marttila <terom@paivola.fi>
parents: 9
diff changeset
     8
from irc_config import *
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
6
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    10
class ReplyException (Exception) :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    11
    def __init__ (self, reply) :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    12
        self.reply = reply
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    13
4
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    14
class BotProtocol (irc.IRCClient, object) :
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
    """
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
        Fixme IRC bot
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
    """
4
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    18
    
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    19
    def __init__ (self) :
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    20
        self.nickname = NICKNAME
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    21
        self.username = USERNAME
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
    # housekeeping
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
    def connectionMade (self) :
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
        log.msg("Connected")
4
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    26
        super(BotProtocol, self).connectionMade()
6
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    27
        
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    28
        self.nexus = self.factory.nexus
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
    def connectionLost (self, reason) :
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
        log.msg("Connection lost: %s" % reason)
4
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    32
        super(BotProtocol, self).connectionLost(reason)
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
    def signedOn (self) :
4
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    35
        log.msg("Signed on, joining channel %s" % CHANNEL)
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
        self.join(CHANNEL)
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
    def joined (self, channel) :
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
        log.msg("Joined channel %s" % channel)
4
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    40
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    41
        self.factory.connection = self
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    42
    
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    43
    # our actual functionality
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
    def send (self, msg) :
4
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    45
        msg = str(msg)
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    46
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    47
        if len(msg) > 480 :
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    48
            log.msg("truncating: %s" % msg)
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    49
            msg = msg[:480] + "..."
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    50
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    51
        msg = msg.replace("\n", "\\n").replace("\r", "\\r").replace("\0", "\\0")
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    52
13
ae9e6e894492 use notice instead of msg
Tero Marttila <terom@paivola.fi>
parents: 9
diff changeset
    53
        self.notice(CHANNEL, msg)
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
    def sendEvent (self, event) :
4
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    56
        self.send("[%s.%s] %s" % (event.module.name, event.type, event.msg))
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
    def moduleConnected (self, module, addr) :
4
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    59
        self.send("{modules.%s} connected from %s:%d, version %s" % (module.name, addr.host, addr.port, module.version))
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
4
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    61
    def moduleDisconnected (self, module, reason) :
34d7897bd0f5 logwatcher works
Tero Marttila <terom@paivola.fi>
parents: 1
diff changeset
    62
        self.send("{modules.%s} disconnected: %s" % (module.name, reason))
6
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    63
    
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    64
    class _noDefault : pass
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
6
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    66
    def _lookupCommand (self, command, default=_noDefault) :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    67
        if '.' in command :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    68
            raise ReplyException("No support for module commands yet :P")
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    69
        else :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    70
            method = getattr(self, "cmd_%s" % command, None)
1
16d7aadc6f31 initial, modified code
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
6
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    72
        if method :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    73
            return method
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    74
        elif default is self._noDefault :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    75
            raise ReplyException("No such command '%s'. See `help commands'" % command)
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    76
        else :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    77
            return default
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    78
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    79
    def privmsg (self, user, channel, message) :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    80
        if message.lower().startswith(self.nickname.lower()) :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    81
            me, command = message.split(":", 1)
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    82
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    83
            args = command.strip().split()
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    84
            command = args.pop(0)
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    85
            
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    86
            try :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    87
                method = self._lookupCommand(command)
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    88
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    89
                reply = method(*args)
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    90
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    91
                if reply :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    92
                    self.send(reply)
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    93
            
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    94
            except ReplyException, e :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    95
                self.send(e.reply)
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    96
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    97
            except Exception, e :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    98
                self.send("Error: %s: %s" % (e.__class__.__name__, e))
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
    99
                traceback.print_exc()
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   100
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   101
    def cmd_help (self, cmd="help") :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   102
        """help <command|module> - Display help about the given command or module"""
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   103
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   104
        method = self._lookupCommand(cmd, None)
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   105
        
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   106
        if method :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   107
            return method.__doc__
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   108
        else :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   109
            try :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   110
                module, addr = self.nexus.getModuleInfo(cmd)
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   111
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   112
                return "%s is version %d from %s:%d. Events: %s. See `commands %s' for a list of commands" % (module.name, module.version, addr.host, addr.port, ', '.join(module.event_types), module.name)
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   113
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   114
            except KeyError :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   115
                raise ReplyException("No command/module called `%s'. See `help commands'" % cmd)
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   116
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   117
    def cmd_commands (self, module=None) :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   118
        """commands [<module>] - Show primary commands, or commands in the given module (see `help modules')"""
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   119
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   120
        if module :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   121
            raise ReplyException("No support for module commands yet :P")
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   122
        else :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   123
            return "Commands: %s" % ', '.join(
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   124
                attr_name.split('_', 1)[1]
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   125
                for attr_name in BotProtocol.__dict__.iterkeys()
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   126
                if attr_name.startswith("cmd_")
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   127
            )
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   128
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   129
    def cmd_modules (self) :
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   130
        """modules - Show a list of connected modules"""
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   131
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   132
        return "Modules: %s" % ', '.join(
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   133
            module.name
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   134
            for module in self.nexus.getModules()
614161f85d9b some cleanup, bugfixes, commands for the irc bot, shared-secret for the API
Tero Marttila <terom@paivola.fi>
parents: 4
diff changeset
   135
        )