Beispiel #1
0
 def _add_command(self, cmd, func):
     assert callable(func)
     if cmd in self.commands:
         log.error("Redefining command: %s" % cmd)
     else:
         log.debug("Registering command: %s" % cmd)
         self.commands[cmd] = func
Beispiel #2
0
    def __init__(self, config, net=None):
        self._conf = None

        if net is not None and net.find("acl"):
            conffile = net.find("acl").get("file", None)
        elif config.find("acl") is not None:
            conffile = config.find("acl").get("file", None)
        else:
            log.debug("No ACL file to load")
            return

        if conffile is None:
            raise ConfigError("<acl> tag is missing the file attribute!")

        if not os.path.isabs(conffile):
            confdir = config.get('config', None)
            if not confdir:
                log.error("Unable to resolve relative path to ACL")
                return
            confdir = os.path.dirname(confdir)
            conffile = os.path.join(confdir, conffile)

        if not os.access(conffile, os.R_OK):
            raise ConfigError("Cannot read ACL file %s" % conffile)

        log.debug("Loading ACL file %s" % conffile)
        self._conf = ElementTree.parse(conffile)
Beispiel #3
0
 def _add_command(self, cmd, func):
     assert callable(func)
     if cmd in self.commands:
         log.error("Redefining command: %s" % cmd)
     else:
         log.debug("Registering command: %s" % cmd)
         self.commands[cmd] = func
Beispiel #4
0
    def __init__(self, config, net=None):
        self._conf = None

        if net is not None and net.find("acl"):
            conffile = net.find("acl").get("file", None)
        elif config.find("acl") is not None:
            conffile = config.find("acl").get("file", None)
        else:
            log.debug("No ACL file to load")
            return

        if conffile is None:
            raise ConfigError("<acl> tag is missing the file attribute!");

        if not os.path.isabs(conffile):
            confdir = config.get('config', None)
            if not confdir:
                log.error("Unable to resolve relative path to ACL")
                return
            confdir = os.path.dirname(confdir)
            conffile = os.path.join(confdir, conffile)

        if not os.access(conffile, os.R_OK):
            raise ConfigError("Cannot read ACL file %s" % conffile);

        log.debug("Loading ACL file %s" % conffile)
        self._conf = ElementTree.parse(conffile)
Beispiel #5
0
    def msg(self, conn, event):
        if ('internal' in event and event['internal']
                or event['sent_to'] == conn.nickname):
            return

        dbpool = conn.manager.dbpool

        for match in re.finditer(self._regex, event['text']):
            if match.group(2) == "++":
                inc = 1
            else:
                inc = -1

            log.debug("score: %s += %s" % (match.group(1), inc))

            defer = dbpool.runOperation("INSERT INTO `score` "
                    "(`name`, `value`, `nick`, `chan`, `date`) "
                    "VALUES (%s, %s, %s, %s, FROM_UNIXTIME(%s)) "
                    "ON DUPLICATE KEY UPDATE "
                    "`value` = `value` + VALUES(`value`), "
                    "`nick` = VALUES(`nick`), "
                    "`chan` = VALUES(`chan`), "
                    "`date` = VALUES(`date`)",
                    (match.group(1), inc, event['sent_by'],
                        event['sent_to'], event['time']))
            defer.addErrback(log.error)
Beispiel #6
0
 def check(_):
     if self._pending:
         log.debug("Waiting on %d plugin commands" % len(self._pending))
         d = defer.DeferredList(self._pending, consumeErrors=True)
         d.addBoth(check)
         return d
     else:
         log.trace("All plugin commands complete")
Beispiel #7
0
 def check(_):
     if self._pending:
         log.debug("Waiting on %d plugin commands" % len(self._pending))
         d = defer.DeferredList(self._pending, consumeErrors=True)
         d.addBoth(check)
         return d
     else:
         log.trace("All plugin commands complete")
Beispiel #8
0
 def processEnded(self, reason):
     if isinstance(reason.value, error.ProcessDone):
         log.debug("Process ended", prefix=self._pid)
         reason = None
     else:
         log.warn(reason, prefix=self._pid)
     deferred = self._deferred
     self._deferred = None
     deferred.callback(reason)
Beispiel #9
0
 def processEnded(self, reason):
     if isinstance(reason.value, error.ProcessDone):
         log.debug("Process ended", prefix=self._pid)
         reason = None
     else:
         log.warn(reason, prefix=self._pid)
     deferred = self._deferred
     self._deferred = None
     deferred.callback(reason)
Beispiel #10
0
    def reload(self):
        """Reload all available plugins"""

        log.debug("Reloading all plugins...")

        # Is this the best way to do this?
        for module in modules.getModule(plugins.__name__).iterModules():
            reload(module.load())

        self._load()
Beispiel #11
0
    def reload(self):
        """Reload all available plugins"""

        log.debug("Reloading all plugins...")

        # Is this the best way to do this?
        for module in modules.getModule(plugins.__name__).iterModules():
            reload(module.load())

        self._load()
Beispiel #12
0
    def _handle_event(self, conn, event):
        if 'internal' in event and event['internal']:
            return

        conf = conn.manager.config
        if event['type'] == "command":
            commands = glob("%s/commands/%s" %
                    (conf.get('root'), event['command']))
        else:
            commands = glob("%s/hooks/%s/*" %
                (conf.get('root'), event['type']))

        if not commands:
            return

        vars = os.environ.copy()
        for key, val in conf.items():
            vars["HB_%s" % key.upper()] = str(val)

        if conn.network.id:
            vars['HB_NETWORK'] = conn.network.id

        vars['HB_NICK'] = conn.nickname
        vars['HB_XML'] = ElementTree.tostring(conn.manager.config)
        text = ""
        for key, val in event.iteritems():
            if key == 'text':
                text = val
            else:
                vars['HBEV_%s' % key.upper()] = str(val)

        if 'PERL5LIB' in vars:
            vars['PERL5LIB'] = "%s:%s" % (conf.get('perl'), vars['PERL5LIB'])
        else:
            vars['PERL5LIB'] = conf.get('perl')

        if 'PYTHONPATH' in vars:
            vars['PYTHONPATH'] = ("%s:%s" %
                    (conf.get('python'), vars['PYTHONPATH']))
        else:
            vars['PYTHONPATH'] = conf.get('python')

        deferreds = []
        for cmd in commands:
            if os.access(cmd, os.X_OK):
                log.debug("Running %s" % cmd)
                deferred = defer.Deferred()
                deferreds.append(deferred)
                proto = HBProcessProtocol(conn, event, deferred)
                reactor.spawnProcess(proto, cmd, [cmd], vars)

        if len(deferreds) == 1:
            return deferreds[0]
        elif len(deferreds) > 1:
            return defer.DeferredList(deferreds, consumeErrors=True)
Beispiel #13
0
    def _handle_event(self, conn, event):
        if 'internal' in event and event['internal']:
            return

        conf = conn.manager.config
        if event['type'] == "command":
            commands = glob("%s/commands/%s" %
                            (conf.get('root'), event['command']))
        else:
            commands = glob("%s/hooks/%s/*" %
                            (conf.get('root'), event['type']))

        if not commands:
            return

        vars = os.environ.copy()
        for key, val in conf.items():
            vars["HB_%s" % key.upper()] = str(val)

        if conn.network.id:
            vars['HB_NETWORK'] = conn.network.id

        vars['HB_NICK'] = conn.nickname
        vars['HB_XML'] = ElementTree.tostring(conn.manager.config)
        text = ""
        for key, val in event.iteritems():
            if key == 'text':
                text = val
            else:
                vars['HBEV_%s' % key.upper()] = str(val)

        if 'PERL5LIB' in vars:
            vars['PERL5LIB'] = "%s:%s" % (conf.get('perl'), vars['PERL5LIB'])
        else:
            vars['PERL5LIB'] = conf.get('perl')

        if 'PYTHONPATH' in vars:
            vars['PYTHONPATH'] = ("%s:%s" %
                                  (conf.get('python'), vars['PYTHONPATH']))
        else:
            vars['PYTHONPATH'] = conf.get('python')

        deferreds = []
        for cmd in commands:
            if os.access(cmd, os.X_OK):
                log.debug("Running %s" % cmd)
                deferred = defer.Deferred()
                deferreds.append(deferred)
                proto = HBProcessProtocol(conn, event, deferred)
                reactor.spawnProcess(proto, cmd, [cmd], vars)

        if len(deferreds) == 1:
            return deferreds[0]
        elif len(deferreds) > 1:
            return defer.DeferredList(deferreds, consumeErrors=True)
Beispiel #14
0
    def _load_sql(self, dump):
        """Execute a chunk of SQL from a file"""

        log.debug("Loading SQL from %s" % dump)

        try:
            dumpfd = open(dump)
            sql = dumpfd.read()
            dumpfd.close()
        except IOError, (errno, errstr):
            raise DBError("Failed to read %s: %s" % (dump, errstr))
Beispiel #15
0
    def _load_sql(self, dump):
        """Execute a chunk of SQL from a file"""

        log.debug("Loading SQL from %s" % dump)

        try:
            dumpfd = open(dump)
            sql = dumpfd.read()
            dumpfd.close()
        except IOError, (errno, errstr):
            raise DBError("Failed to read %s: %s" % (dump, errstr))
Beispiel #16
0
    def userQuit(self, user, msg):
        log.debug("%s quit: %s" % (user, msg))
        for chan in self.channels.itervalues():
            chan['users'].discard(user)

        event = {
            'type': 'quit',
            'user': user,
            'text': msg,
            'time': time.time()
        }

        self.manager.plugins.hook(self, event)
Beispiel #17
0
    def userJoined(self, user, channel):
        log.debug("%s joined channel %s" % (user, channel))
        self.channels[channel]['users'].add(user)

        event = {
            'type': 'join',
            'user': user,
            'reply_to': channel,
            'channel': channel,
            'time': time.time()
        }

        self.manager.plugins.hook(self, event)
Beispiel #18
0
    def msg(self, conn, event):
        if event["sent_by"] == conn.nickname:
            return

        message = event["text"].lower()
        for topping in self.toppings:
            if topping in message:
                if "no " + topping in message or "not " + topping in message:
                    log.debug("Decrementing %s" % topping)
                    self.toppings[topping] -= 1
                else:
                    log.debug("Incrementing %s" % topping)
                    self.toppings[topping] += 1
Beispiel #19
0
    def msg(self, conn, event):
        if "internal" in event and event["internal"] or event["sent_to"] == conn.nickname:
            return

        for match in re.finditer(self._regex, event["text"]):
            url = match.group(0)

            log.debug("bitly: Got URL %s" % url)

            d = defer.Deferred()
            d.addCallback(self.api.shorten)
            d.addCallback(self._reply_with_shortened_url, conn, event)
            reactor.callLater(0, d.callback, url)
Beispiel #20
0
    def userQuit(self, user, msg):
        log.debug("%s quit: %s" % (user, msg))
        for chan in self.channels.itervalues():
            chan['users'].discard(user)

        event = {
                'type': 'quit',
                'user': user,
                'text': msg,
                'time': time.time()
                }

        self.manager.plugins.hook(self, event)
Beispiel #21
0
    def userJoined(self, user, channel):
        log.debug("%s joined channel %s" % (user, channel))
        self.channels[channel]['users'].add(user)

        event = {
                'type': 'join',
                'user': user,
                'reply_to': channel,
                'channel': channel,
                'time': time.time()
                }

        self.manager.plugins.hook(self, event)
Beispiel #22
0
    def topicUpdated(self, user, channel, topic):
        log.debug("%s topic: %s" % (channel, topic))
        self.channels[channel]['topic'] = topic

        event = {
            'type': 'topic',
            'user': user,
            'reply_to': channel,
            'channel': channel,
            'text': topic,
            'time': time.time()
        }

        self.manager.plugins.hook(self, event)
Beispiel #23
0
    def topicUpdated(self, user, channel, topic):
        log.debug("%s topic: %s" % (channel, topic))
        self.channels[channel]['topic'] = topic

        event = {
                'type': 'topic',
                'user': user,
                'reply_to': channel,
                'channel': channel,
                'text': topic,
                'time': time.time()
                }

        self.manager.plugins.hook(self, event)
Beispiel #24
0
    def userRenamed(self, oldname, newname):
        log.debug("%s changed to %s" % (oldname, newname))
        for chan in self.channels.itervalues():
            if oldname in chan['users']:
                chan['users'].discard(oldname)
                chan['users'].add(newname)

        event = {
            'type': 'rename',
            'old': oldname,
            'new': newname,
            'time': time.time()
        }

        self.manager.plugins.hook(self, event)
Beispiel #25
0
    def userLeft(self, user, channel):
        log.debug("%s left channel %s" % (user, channel))
        self.channels[channel]['users'].discard(user)

        # TODO: re-implement this so we can get the text
        event = {
                'type': 'part',
                'user': user,
                'reply_to': channel,
                'channel': channel,
                'text': "",
                'time': time.time()
                }

        self.manager.plugins.hook(self, event)
Beispiel #26
0
    def userKicked(self, user, channel, kicker, msg):
        log.debug("%s kicked from %s by %s: %s" % (user, channel, kicker, msg))
        self.channels[channel]['users'].discard(user)

        event = {
                'type': 'kick',
                'kicker': kicker,
                'kickee': user,
                'reply_to': channel,
                'channel': channel,
                'text': msg,
                'time': time.time()
                }

        self.manager.plugins.hook(self, event)
Beispiel #27
0
    def userRenamed(self, oldname, newname):
        log.debug("%s changed to %s" % (oldname, newname))
        for chan in self.channels.itervalues():
            if oldname in chan['users']:
                chan['users'].discard(oldname)
                chan['users'].add(newname)

        event = {
                'type': 'rename',
                'old': oldname,
                'new': newname,
                'time': time.time()
                }

        self.manager.plugins.hook(self, event)
Beispiel #28
0
    def userKicked(self, user, channel, kicker, msg):
        log.debug("%s kicked from %s by %s: %s" % (user, channel, kicker, msg))
        self.channels[channel]['users'].discard(user)

        event = {
            'type': 'kick',
            'kicker': kicker,
            'kickee': user,
            'reply_to': channel,
            'channel': channel,
            'text': msg,
            'time': time.time()
        }

        self.manager.plugins.hook(self, event)
Beispiel #29
0
    def userLeft(self, user, channel):
        log.debug("%s left channel %s" % (user, channel))
        self.channels[channel]['users'].discard(user)

        # TODO: re-implement this so we can get the text
        event = {
            'type': 'part',
            'user': user,
            'reply_to': channel,
            'channel': channel,
            'text': "",
            'time': time.time()
        }

        self.manager.plugins.hook(self, event)
Beispiel #30
0
    def _set_version(self, version):
        """Update the schema version metadata"""

        if version <= 0:
            return

        cursor = self._db.cursor()

        log.debug("Setting schema version to %s" % version)

        try:
            cursor.execute(
                "INSERT `metadata` (`name` , `value`) "
                "VALUES ('schema', '%s') "
                "ON DUPLICATE KEY UPDATE `value` = %s", (version, version))
        except MySQLdb.Error, (errno, errstr):
            raise DBError("DB error: [%s] %s" % (errno, errstr))
Beispiel #31
0
    def _set_version(self, version):
        """Update the schema version metadata"""

        if version <= 0:
            return

        cursor = self._db.cursor()

        log.debug("Setting schema version to %s" % version)

        try:
            cursor.execute("INSERT `metadata` (`name` , `value`) "
                    "VALUES ('schema', '%s') "
                    "ON DUPLICATE KEY UPDATE `value` = %s",
                    (version, version))
        except MySQLdb.Error, (errno, errstr):
            raise DBError("DB error: [%s] %s"%(errno, errstr))
Beispiel #32
0
    def irc_RPL_NAMREPLY(self, prefix, params):
        # Odd that twisted doesn't handle this one
        channel = params[2]
        users = params[3]

        log.debug("%s users: %s" % (channel, users))

        users = [u.lstrip("+@") for u in users.split()]
        users.sort()

        # Is it safe to assume that a single NAMREPLY covers all users?
        self.channels[channel]['users'] = set(users)

        event = {
            'type': 'names',
            'channel': channel,
            'users': users,
            'time': time.time()
        }
        self.manager.plugins.hook(self, event)
Beispiel #33
0
    def irc_RPL_NAMREPLY(self, prefix, params):
        # Odd that twisted doesn't handle this one
        channel = params[2]
        users = params[3]

        log.debug("%s users: %s" % (channel, users))

        users = [u.lstrip("+@") for u in users.split()]
        users.sort()

        # Is it safe to assume that a single NAMREPLY covers all users?
        self.channels[channel]['users'] = set(users)

        event = {
            'type': 'names',
            'channel': channel,
            'users': users,
            'time': time.time()
        }
        self.manager.plugins.hook(self, event)
Beispiel #34
0
    def msg(self, conn, event):
        if ('internal' in event and event['internal']
                or event['sent_to'] == conn.nickname):
            return

        dbpool = conn.manager.dbpool

        for match in re.finditer(self._regex, event['text']):
            if match.group(2) == "++":
                if match.group(1) == event['sent_by']:
                    conn.msg(
                        event['reply_to'],
                        "%s: no self promotion! You lose 5 points." %
                        event['sent_by'])
                    inc = -5
                else:
                    inc = 1
            else:
                if match.group(1) == event['sent_by']:
                    conn.msg(
                        event['reply_to'],
                        "%s: Aww, cheer up! You can keep your point." %
                        event['sent_by'])
                    return
                else:
                    inc = -1

            log.debug("score: %s += %s" % (match.group(1), inc))

            defer = dbpool.runOperation(
                "INSERT INTO `score` "
                "(`name`, `value`, `nick`, `chan`, `date`) "
                "VALUES (%s, %s, %s, %s, FROM_UNIXTIME(%s)) "
                "ON DUPLICATE KEY UPDATE "
                "`value` = `value` + VALUES(`value`), "
                "`nick` = VALUES(`nick`), "
                "`chan` = VALUES(`chan`), "
                "`date` = VALUES(`date`)",
                (match.group(1), inc, event['sent_by'], event['sent_to'],
                 event['time']))
            defer.addErrback(log.error)
Beispiel #35
0
    def noticed(self, sent_by, sent_to, msg):
        sent_by = nick(sent_by)
        sent_to = nick(sent_to)
        log.debug("<%s> %s" % (sent_by, msg))

        event = {
            'type': 'notice',
            'sent_by': sent_by,
            'sent_to': sent_to,
            'text': msg,
            'time': time.time()
        }

        if sent_to == self.nickname:
            event['reply_to'] = sent_by
            event['private'] = True
        else:
            event['reply_to'] = sent_to
            event['private'] = False

        self.manager.plugins.hook(self, event)
Beispiel #36
0
    def noticed(self, sent_by, sent_to, msg):
        sent_by = nick(sent_by)
        sent_to = nick(sent_to)
        log.debug("<%s> %s" % (sent_by, msg))

        event = {
                'type': 'notice',
                'sent_by': sent_by,
                'sent_to': sent_to,
                'text': msg,
                'time': time.time()
                }

        if sent_to == self.nickname:
            event['reply_to'] = sent_by
            event['private'] = True
        else:
            event['reply_to'] = sent_to
            event['private'] = False

        self.manager.plugins.hook(self, event)
Beispiel #37
0
    def privmsg(self, sent_by, sent_to, msg):
        sent_by = nick(sent_by)
        sent_to = nick(sent_to)
        log.debug("<%s> %s" % (sent_by, msg))

        event = {
            'type': 'msg',
            'sent_by': sent_by,
            'sent_to': sent_to,
            'text': msg,
            'time': time.time()
        }

        if sent_to == self.nickname:
            event['reply_to'] = sent_by
            event['private'] = True
        else:
            event['reply_to'] = sent_to
            event['private'] = False

        self.manager.plugins.hook(self, event)

        match = self.COMMAND.match(msg)
        if match:
            command = match.group(1)
            text = match.group(2)
            text = text.strip()

            cmdevent = event.copy()
            cmdevent['type'] = "command"
            cmdevent['command'] = command
            cmdevent['text'] = text

            ok, reply = self.factory.acl.check(cmdevent)
            if reply:
                self.msg(event['reply_to'], reply)
            if ok:
                self.manager.plugins.command(self, cmdevent)
Beispiel #38
0
    def privmsg(self, sent_by, sent_to, msg):
        sent_by = nick(sent_by)
        sent_to = nick(sent_to)
        log.debug("<%s> %s" % (sent_by, msg))

        event = {
                'type': 'msg',
                'sent_by': sent_by,
                'sent_to': sent_to,
                'text': msg,
                'time': time.time()
                }

        if sent_to == self.nickname:
            event['reply_to'] = sent_by
            event['private'] = True
        else:
            event['reply_to'] = sent_to
            event['private'] = False

        self.manager.plugins.hook(self, event)

        match = self.COMMAND.match(msg)
        if match:
            command = match.group(1)
            text = match.group(2)
            text = text.strip()

            cmdevent = event.copy()
            cmdevent['type'] = "command"
            cmdevent['command'] = command
            cmdevent['text'] = text

            ok, reply = self.factory.acl.check(cmdevent)
            if reply:
                self.msg(event['reply_to'], reply)
            if ok:
                self.manager.plugins.command(self, cmdevent)
Beispiel #39
0
    def check(self, event):
        """Check if a command can be run by a user.
        
        Returns a tuple: (True/False, message)
        """

        if self._conf is None:
            acl = None
        elif event['private']:
            acl = self.check_private(event['command'], event['sent_by'])
        else:
            acl = self.check_public(event['command'], event['sent_by'],
                                    event['sent_to'])

        if acl is None:
            log.debug("No acl")
            return (True, "")
        else:
            log.debug("Using acl: %s" % ElementTree.tostring(acl).strip())
            action = acl.get("action", "")
            if action == "" or action not in ("allow", "deny"):
                log.error('Invalid acl action="%s", allowing.' % action)
            return (action != "deny", acl.get("msg", ""))
Beispiel #40
0
    def check(self, event):
        """Check if a command can be run by a user.
        
        Returns a tuple: (True/False, message)
        """

        if self._conf is None:
            acl = None
        elif event['private']:
            acl = self.check_private(event['command'], event['sent_by'])
        else:
            acl = self.check_public(event['command'], event['sent_by'],
                    event['sent_to'])

        if acl is None:
            log.debug("No acl")
            return (True, "")
        else:
            log.debug("Using acl: %s" % ElementTree.tostring(acl).strip())
            action = acl.get("action", "")
            if action == "" or action not in ("allow", "deny"):
                log.error('Invalid acl action="%s", allowing.' % action)
            return (action != "deny", acl.get("msg", ""))
Beispiel #41
0
 def readConnectionLost(self):
     log.debug("Lost read connection.")
     reactor.callLater(0,self.transport.loseConnection)
Beispiel #42
0
 def connectionLost(self, reason):
     log.debug("Lost connection.")
Beispiel #43
0
 def connectionMade(self):
     log.debug("New connection.")
Beispiel #44
0
 def connectionMade(self):
     self._pid = str(self.transport.pid)
     log.debug("Process started", prefix=self._pid)
Beispiel #45
0
def _connected(connection):
    log.debug("Created database connection...")
Beispiel #46
0
 def connectionMade(self):
     self._pid = str(self.transport.pid)
     log.debug("Process started", prefix=self._pid)
Beispiel #47
0
 def connectionLost(self, reason):
     log.debug("Lost connection.")
Beispiel #48
0
 def readConnectionLost(self):
     log.debug("Lost read connection.")
     reactor.callLater(0, self.transport.loseConnection)
Beispiel #49
0
def _connected(connection):
    log.debug("Created database connection...")
Beispiel #50
0
 def connectionMade(self):
     log.debug("New connection.")