Beispiel #1
0
    def _sentnotes(self, irc, msg, receiver):
        try:
            user = ircdb.users.getUser(msg.prefix)
        except KeyError:
            irc.errorNotRegistered()
            return

        def p(note):
            return note.frm == user.id

        if receiver:
            originalP = p

            def p(note):
                return originalP(note) and note.to == receiver.id

        notes = list(self.db.select(p))
        if not notes:
            irc.error('I couldn\'t find any sent notes for your user.')
        else:
            utils.sortBy(operator.attrgetter('id'), notes)
            notes.reverse()  # Most recently sent first.
            ids = [self._formatNoteId(msg, note, sent=True) for note in notes]
            ids = self._condense(ids)
            irc.reply(format('%L.', ids))
Beispiel #2
0
    def nicks(self, irc, msg, args, channel, optlist):
        """[<channel>] [--count]

        Returns the nicks in <channel>.  <channel> is only necessary if the
        message isn't sent in the channel itself. Returns only the number of
        nicks if --count option is provided.
        """
        # Make sure we don't elicit information about private channels to
        # people or channels that shouldn't know. Someone is allowed if
        # any of these are true:
        # * the channel is not secret (mode +s),
        # * the request is sent to the channel itself (FIXME: what about
        #   channels without +n?),
        # * the requester is op,
        # * the request is not sent to a channel (or else everyone in the
        #   channel would see the response) and the requester is in the
        #   channel themselves
        capability = ircdb.makeChannelCapability(channel, 'op')
        if 's' in irc.state.channels[channel].modes and \
            msg.channel != channel and \
            not ircdb.checkCapability(msg.prefix, capability) and \
            (msg.channel or \
             msg.nick not in irc.state.channels[channel].users):
            irc.error(_('You don\'t have access to that information.'),
                    Raise=True)
        L = list(irc.state.channels[channel].users)
        keys = [option for (option, arg) in optlist]
        if 'count' not in keys:
            utils.sortBy(str.lower, L)
            private = self.registryValue("nicksInPrivate", channel, irc.network)
            irc.reply(utils.str.commaAndify(L), private=private)
        else:
            irc.reply(str(len(L)))
Beispiel #3
0
    def search(self, irc, msg, args, user, optlist, glob):
        """[--{regexp} <value>] [--sent] [<glob>]

        Searches your received notes for ones matching <glob>.  If --regexp is
        given, its associated value is taken as a regexp and matched against
        the notes.  If --sent is specified, only search sent notes.
        """
        criteria = []
        def to(note):
            return note.to == user.id
        def frm(note):
            return note.frm == user.id
        own = to
        for (option, arg) in optlist:
            if option == 'regexp':
                criteria.append(lambda x: commands.regexp_wrapper(x, reobj=arg, 
                        timeout=0.1, plugin_name = self.name(), fcn_name='search'))
            elif option == 'sent':
                own = frm
        if glob:
            glob = utils.python.glob2re(glob)
            criteria.append(re.compile(glob).search)
        def match(note):
            for p in criteria:
                if not p(note.text):
                    return False
            return True
        notes = list(self.db.select(lambda n: match(n) and own(n)))
        if not notes:
            irc.reply('No matching notes were found.')
        else:
            utils.sortBy(operator.attrgetter('id'), notes)
            ids = [self._formatNoteId(msg, note) for note in notes]
            ids = self._condense(ids)
            irc.reply(format('%L', ids))
Beispiel #4
0
    def nicks(self, irc, msg, args, channel, optlist):
        """[<channel>] [--count]

        Returns the nicks in <channel>.  <channel> is only necessary if the
        message isn't sent in the channel itself. Returns only the number of
        nicks if --count option is provided.
        """
        # Make sure we don't elicit information about private channels to
        # people or channels that shouldn't know
        capability = ircdb.makeChannelCapability(channel, 'op')
        hostmask = irc.state.nickToHostmask(msg.nick)
        if 's' in irc.state.channels[channel].modes and \
            msg.args[0] != channel and \
            not ircdb.checkCapability(hostmask, capability) and \
            (ircutils.isChannel(msg.args[0]) or \
             msg.nick not in irc.state.channels[channel].users):
            irc.error(_('You don\'t have access to that information.'),
                    Raise=True)
        L = list(irc.state.channels[channel].users)
        keys = [option for (option, arg) in optlist]
        if 'count' not in keys:
            utils.sortBy(str.lower, L)
            private = self.registryValue("nicksInPrivate", channel)
            irc.reply(utils.str.commaAndify(L), private=private)
        else:
            irc.reply(str(len(L)))
Beispiel #5
0
    def _oldnotes(self, irc, msg, sender):
        try:
            user = ircdb.users.getUser(msg.prefix)
        except KeyError:
            irc.errorNotRegistered()
            return

        def p(note):
            return note.to == user.id and note.read

        if sender:
            originalP = p

            def p(note):
                return originalP(note) and note.frm == sender.id

        notes = list(self.db.select(p))
        if not notes:
            irc.reply("I couldn't find any matching read notes " "for your user.")
        else:
            utils.sortBy(operator.attrgetter("id"), notes)
            notes.reverse()
            ids = [self._formatNoteId(msg, note) for note in notes]
            ids = self._condense(ids)
            irc.reply(format("%L.", ids))
Beispiel #6
0
    def search(self, irc, msg, args, user, optlist, glob):
        """[--{regexp} <value>] [--sent] [<glob>]

        Searches your received notes for ones matching <glob>.  If --regexp is
        given, its associated value is taken as a regexp and matched against
        the notes.  If --sent is specified, only search sent notes.
        """
        criteria = []
        def to(note):
            return note.to == user.id
        def frm(note):
            return note.frm == user.id
        own = to
        for (option, arg) in optlist:
            if option == 'regexp':
                criteria.append(lambda x: commands.regexp_wrapper(x, reobj=arg, 
                        timeout=0.1, plugin_name = self.name(), fcn_name='search'))
            elif option == 'sent':
                own = frm
        if glob:
            glob = utils.python.glob2re(glob)
            criteria.append(re.compile(glob).search)
        def match(note):
            for p in criteria:
                if not p(note.text):
                    return False
            return True
        notes = list(self.db.select(lambda n: match(n) and own(n)))
        if not notes:
            irc.reply('No matching notes were found.')
        else:
            utils.sortBy(operator.attrgetter('id'), notes)
            ids = [self._formatNoteId(msg, note) for note in notes]
            ids = self._condense(ids)
            irc.reply(format('%L', ids))
Beispiel #7
0
    def nicks(self, irc, msg, args, channel, optlist):
        """[<channel>] [--count]

        Returns the nicks in <channel>.  <channel> is only necessary if the
        message isn't sent in the channel itself. Returns only the number of
        nicks if --count option is provided.
        """
        # Make sure we don't elicit information about private channels to
        # people or channels that shouldn't know
        capability = ircdb.makeChannelCapability(channel, 'op')
        hostmask = irc.state.nickToHostmask(msg.nick)
        if 's' in irc.state.channels[channel].modes and \
            msg.args[0] != channel and \
            not ircdb.checkCapability(hostmask, capability) and \
            (ircutils.isChannel(msg.args[0]) or \
             msg.nick not in irc.state.channels[channel].users):
            irc.error(_('You don\'t have access to that information.'),
                      Raise=True)
        L = list(irc.state.channels[channel].users)
        keys = [option for (option, arg) in optlist]
        if 'count' not in keys:
            utils.sortBy(str.lower, L)
            private = self.registryValue("nicksInPrivate", channel)
            irc.reply(utils.str.commaAndify(L), private=private)
        else:
            irc.reply(str(len(L)))
Beispiel #8
0
    def list(self, irc, msg, args, optlist, glob):
        """[--capability=<capability>] [<glob>]

        Returns the valid registered usernames matching <glob>.  If <glob> is
        not given, returns all registered usernames.
        """
        predicates = []
        for (option, arg) in optlist:
            if option == 'capability':
                def p(u, cap=arg):
                    try:
                        return u._checkCapability(cap)
                    except KeyError:
                        return False
                predicates.append(p)
        if glob:
            r = re.compile(fnmatch.translate(glob), re.I)
            def p(u):
                return r.match(u.name) is not None
            predicates.append(p)
        users = []
        for u in ircdb.users.itervalues():
            for predicate in predicates:
                if not predicate(u):
                    break
            else:
                users.append(u.name)
        if users:
            utils.sortBy(str.lower, users)
            irc.reply(format('%L', users))
        else:
            if predicates:
                irc.reply('There are no matching registered users.')
            else:
                irc.reply('There are no registered users.')
Beispiel #9
0
    def nicks(self, irc, msg, args, channel, optlist):
        """[<channel>] [--count]

        Returns the nicks in <channel>.  <channel> is only necessary if the
        message isn't sent in the channel itself. Returns only the number of
        nicks if --count option is provided.
        """
        # Make sure we don't elicit information about private channels to
        # people or channels that shouldn't know
        if 's' in irc.state.channels[channel].modes and \
            msg.args[0] != channel and \
            (ircutils.isChannel(msg.args[0]) or \
             msg.nick not in irc.state.channels[channel].users):
            irc.error(_('You don\'t have access to that information.'),
                    Raise=True)
        L = list(irc.state.channels[channel].users)
        keys = [option for (option, arg) in optlist]
        if 'count' not in keys:
            irc.reply(channel)
            irc.reply(optlist)
            irc.reply(keys)
            irc.reply(args)
            utils.sortBy(str.lower, L)
            irc.reply(utils.str.commaAndify(L))
        else:
            irc.reply(args)
            irc.reply(channel)
            irc.reply(optlist)
            irc.reply(keys)
            irc.reply(str(len(L)))
Beispiel #10
0
    def search(self, irc, msg, args, user, optlist, glob):
        """[--{regexp} <value>] [--sent] [<glob>]

        Searches your received notes for ones matching <glob>.  If --regexp is
        given, its associated value is taken as a regexp and matched against
        the notes.  If --sent is specified, only search sent notes.
        """
        criteria = []
        def to(note):
            return note.to == user.id
        def frm(note):
            return note.frm == user.id
        own = to
        for (option, arg) in optlist:
            if option == 'regexp':
                criteria.append(arg.search)
            elif option == 'sent':
                own = frm
        if glob:
            glob = fnmatch.translate(glob)
            # ignore the trailing $ fnmatch.translate adds to the regexp
            criteria.append(re.compile(glob[:-1]).search)
        def match(note):
            for p in criteria:
                if not p(note.text):
                    return False
            return True
        notes = list(self.db.select(lambda n: match(n) and own(n)))
        if not notes:
            irc.reply('No matching notes were found.')
        else:
            utils.sortBy(operator.attrgetter('id'), notes)
            ids = [self._formatNoteId(msg, note) for note in notes]
            ids = self._condense(ids)
            irc.reply(format('%L', ids))
Beispiel #11
0
 def getTopUsers(self, channel, word, n):
     L = [(id, d[word]) for ((chan, id), d) in self.iteritems()
          if ircutils.nickEqual(channel, chan) and word in d]
     utils.sortBy(lambda (_, i): i, L)
     L = L[-n:]
     L.reverse()
     return L
Beispiel #12
0
    def _oldnotes(self, irc, msg, sender):
        try:
            user = ircdb.users.getUser(msg.prefix)
        except KeyError:
            irc.errorNotRegistered()
            return

        def p(note):
            return note.to == user.id and note.read

        if sender:
            originalP = p

            def p(note):
                return originalP(note) and note.frm == sender.id

        notes = list(self.db.select(p))
        if not notes:
            irc.reply('I couldn\'t find any matching read notes '
                      'for your user.')
        else:
            utils.sortBy(operator.attrgetter('id'), notes)
            notes.reverse()
            ids = [self._formatNoteId(irc, msg, note) for note in notes]
            ids = self._condense(ids)
            irc.reply(format('%L.', ids))
Beispiel #13
0
    def networks(self, irc, msg, args):
        """takes no arguments

        Returns the networks to which the bot is currently connected.
        """
        L = ['%s: %s' % (ircd.network, ircd.server) for ircd in world.ircs]
        utils.sortBy(str.lower, L)
        irc.reply(format('%L', L))
Beispiel #14
0
    def networks(self, irc, msg, args):
        """takes no arguments

        Returns the networks to which the bot is currently connected.
        """
        L = ['%s: %s' % (ircd.network, ircd.server) for ircd in world.ircs]
        utils.sortBy(str.lower, L)
        irc.reply(format('%L', L))
Beispiel #15
0
 def sortAuthors():
     """
     Sort the list of 'long names' based on the number of contributions
     associated with each.
     """
     L = module.__contributors__.items()
     def negativeSecondElement(x):
         return -len(x[1])
     utils.sortBy(negativeSecondElement, L)
     return [t[0] for t in L]
Beispiel #16
0
 def sortAuthors():
     """
     Sort the list of 'long names' based on the number of contributions
     associated with each.
     """
     L = list(module.__contributors__.items())
     def negativeSecondElement(x):
         return -len(x[1])
     utils.sortBy(negativeSecondElement, L)
     return [t[0] for t in L]
Beispiel #17
0
    def wulist(self, irc, msg, args):
        """takes no arguments

        Returns the list of urls in the whitelist.
        """
        L = list(self.registryValue('urlWhitelist'))
        if L:
            utils.sortBy(str.lower, L)
            irc.reply(format('%L', L))
        else:
            irc.reply('There are no urls in the whitelist.')
Beispiel #18
0
    def channels(self, irc, msg, args):
        """takes no arguments

        Returns the channels the bot is on.
        """
        L = irc.state.channels.keys()
        if L:
            utils.sortBy(ircutils.toLower, L)
            irc.reply(format('%L', L), private=True)
        else:
            irc.reply(_('I\'m not currently in any channels.'))
Beispiel #19
0
    def channels(self, irc, msg, args):
        """takes no arguments

        Returns the channels the bot is on.
        """
        L = irc.state.channels.keys()
        if L:
            utils.sortBy(ircutils.toLower, L)
            irc.reply(format('%L', L), private=True)
        else:
            irc.reply(_('I\'m not currently in any channels.'))
Beispiel #20
0
    def wulist(self, irc, msg, args):
        """takes no arguments

        Returns the list of urls in the whitelist.
        """
        L = list(self.registryValue('urlWhitelist'))
        if L:
            utils.sortBy(str.lower, L)
            irc.reply(format('%L', L))
        else:
            irc.reply('There are no urls in the whitelist.')
Beispiel #21
0
    def nicks(self, irc, msg, args):
        """takes no arguments

        Returns the nicks that this plugin is configured to identify and ghost
        with.
        """
        L = list(self.registryValue('nicks'))
        if L:
            utils.sortBy(ircutils.toLower, L)
            irc.reply(format('%L', L))
        else:
            irc.reply('I\'m not currently configured for any nicks.')
Beispiel #22
0
    def nicks(self, irc, msg, args):
        """takes no arguments

        Returns the nicks that this plugin is configured to identify and ghost
        with.
        """
        L = list(self.registryValue('nicks'))
        if L:
            utils.sortBy(ircutils.toLower, L)
            irc.reply(format('%L', L))
        else:
            irc.reply('I\'m not currently configured for any nicks.')
Beispiel #23
0
    def list(self, irc, msg, args):
        """takes no arguments

        Returns the list of words being censored.
        """
        L = list(self.words())
        if L:
            self.filtering = False
            utils.sortBy(str.lower, L)
            irc.reply(format('%L', L))
        else:
            irc.reply(_('I\'m not currently censoring any bad words.'))
Beispiel #24
0
 def do315(self, irc, msg):
     mask = msg.args[1]
     if mask in self.whos:
         (replyIrc, msgs) = self.whos.pop(mask)
         nicks = []
         for msg in msgs:
             nicks.append(msg.args[5])
         utils.sortBy(ircutils.toLower, nicks)
         if nicks:
             replyIrc.reply(format('%s matched: %L.', len(nicks), nicks))
         else:
             replyIrc.reply('No users matched %s.' % mask)
Beispiel #25
0
    def channels(self, irc, msg, args):
        """takes no arguments

        Returns the channels the bot is on.  Must be given in private, in order
        to protect the secrecy of secret channels.
        """
        L = irc.state.channels.keys()
        if L:
            utils.sortBy(ircutils.toLower, L)
            irc.reply(format('%L', L))
        else:
            irc.reply('I\'m not currently in any channels.')
Beispiel #26
0
 def do315(self, irc, msg):
     mask = msg.args[1]
     if mask in self.whos:
         (replyIrc, msgs) = self.whos.pop(mask)
         nicks = []
         for msg in msgs:
             nicks.append(msg.args[5])
         utils.sortBy(ircutils.toLower, nicks)
         if nicks:
             replyIrc.reply(format('%s matched: %L.', len(nicks), nicks))
         else:
             replyIrc.reply('No users matched %s.' % mask)
Beispiel #27
0
    def channels(self, irc, msg, args):
        """takes no arguments

        Returns the channels the bot is on.  Must be given in private, in order
        to protect the secrecy of secret channels.
        """
        L = irc.state.channels.keys()
        if L:
            utils.sortBy(ircutils.toLower, L)
            irc.reply(format('%L', L))
        else:
            irc.reply(_('I\'m not currently in any channels.'))
Beispiel #28
0
    def dict(self, irc, msg, args, words):
        """[<dictionary>] <word>

        Looks up the definition of <word> on the dictd server specified by
        the supybot.plugins.Dict.server config variable.
        """
        try:
            server = conf.supybot.plugins.Dict.server()
            conn = dictclient.Connection(server)
        except socket.error as e:
            irc.error(utils.web.strError(e), Raise=True)
        dbs = set(conn.getdbdescs())
        if words[0] in dbs:
            dictionary = words.pop(0)
        else:
            default = self.registryValue('default', msg.channel, irc.network)
            if default in dbs:
                dictionary = default
            else:
                if default:
                    self.log.info(
                        'Default dict for %s @ %s is not a supported '
                        'dictionary: %s.', msg.channel, irc.network, default)
                dictionary = '*'
        if not words:
            irc.error(_('You must give a word to define.'), Raise=True)
        word = ' '.join(words)
        definitions = conn.define(dictionary, word)
        dbs = set()
        if not definitions:
            if dictionary == '*':
                irc.reply(
                    format(_('No definition for %q could be found.'), word))
            else:
                irc.reply(
                    format(_('No definition for %q could be found in '
                             '%s'), word, ircutils.bold(dictionary)))
            return
        L = []
        for d in definitions:
            dbs.add(ircutils.bold(d.getdb().getname()))
            (db, s) = (d.getdb().getname(), d.getdefstr())
            db = ircutils.bold(db)
            s = utils.str.normalizeWhitespace(s).rstrip(';.,')
            L.append('%s: %s' % (db, s))
        utils.sortBy(len, L)
        if dictionary == '*' and len(dbs) > 1 and \
                self.registryValue("showDictName", msg.channel, irc.network):
            s = format(_('%L responded: %s'), list(dbs), '; '.join(L))
        else:
            s = '; '.join(L)
        irc.reply(s)
Beispiel #29
0
    def list(self, irc, msg, args, optlist, glob):
        """[--capability=<capability>] [<glob>]

        Returns the valid registered usernames matching <glob>.  If <glob> is
        not given, returns all registered usernames.
        """
        predicates = []
        for (option, arg) in optlist:
            if option == 'capability':
                if arg in conf.supybot.capabilities.private():
                    try:
                        u = ircdb.users.getUser(msg.prefix)
                        if not u._checkCapability('admin'):
                            raise KeyError
                    except KeyError:
                        # Note that it may be raised by checkCapability too.
                        irc.error(_(
                            'This is a private capability. Only admins '
                            'can see who has it.'),
                                  Raise=True)

                def p(u, cap=arg):
                    try:
                        return u._checkCapability(cap)
                    except KeyError:
                        return False

                predicates.append(p)
        if glob:
            r = re.compile(fnmatch.translate(glob), re.I)

            def p(u):
                return r.match(u.name) is not None

            predicates.append(p)
        users = []
        for u in ircdb.users.values():
            for predicate in predicates:
                if not predicate(u):
                    break
            else:
                users.append(u.name)
        if users:
            utils.sortBy(str.lower, users)
            private = self.registryValue("listInPrivate", msg.channel,
                                         irc.network)
            irc.reply(format('%L', users), private=private)
        else:
            if predicates:
                irc.reply(_('There are no matching registered users.'))
            else:
                irc.reply(_('There are no registered users.'))
Beispiel #30
0
 def _list(self, group):
     L = []
     for (vname, v) in group._children.items():
         if hasattr(group, 'channelValue') and group.channelValue and \
            ircutils.isChannel(vname) and not v._children:
             continue
         if hasattr(v, 'channelValue') and v.channelValue:
             vname = '#' + vname
         if v._added and not all(ircutils.isChannel, v._added):
             vname = '@' + vname
         L.append(vname)
     utils.sortBy(str.lower, L)
     return L
Beispiel #31
0
 def _list(self, group):
     L = []
     for (vname, v) in group._children.iteritems():
         if hasattr(group, 'channelValue') and group.channelValue and \
            ircutils.isChannel(vname) and not v._children:
             continue
         if hasattr(v, 'channelValue') and v.channelValue:
             vname = '#' + vname
         if v._added and not all(ircutils.isChannel, v._added):
             vname = '@' + vname
         L.append(vname)
     utils.sortBy(str.lower, L)
     return L
Beispiel #32
0
    def glossary (self, irc, msg, args):
        """<no arguments>

        Returns a list of defined lookup words
        """
        words = []
        for (name, (text, url, _)) in self.abbr.items():
            words.append(name)
        if words:
            utils.sortBy(str.lower, words)
            irc.reply(format('Available definitions: %L', words))
        else:
            irc.reply('There are no words defined.')
Beispiel #33
0
    def todo(self, irc, msg, args, user, taskid):
        """[<username>] [<task id>]

        Retrieves a task for the given task id.  If no task id is given, it
        will return a list of task ids that that user has added to their todo
        list.
        """
        try:
            u = ircdb.users.getUser(msg.prefix)
        except KeyError:
            u = None
        if u != user and not self.registryValue('allowThirdpartyReader'):
            irc.error(_('You are not allowed to see other users todo-list.'))
            return
        # List the active tasks for the given user
        if not taskid:
            try:
                tasks = self.db.getTodos(user.id)
                utils.sortBy(operator.attrgetter('priority'), tasks)
                tasks = [
                    format(_('#%i: %s'), t.id, self._shrink(t.task))
                    for t in tasks
                ]
                Todo = 'Todo'
                if len(tasks) != 1:
                    Todo = 'Todos'
                irc.reply(format(_('%s for %s: %L'), Todo, user.name, tasks))
            except dbi.NoRecordError:
                if u != user:
                    irc.reply(_('That user has no tasks in their todo list.'))
                else:
                    irc.reply(_('You have no tasks in your todo list.'))
                return
        # Reply with the user's task
        else:
            try:
                t = self.db.get(user.id, taskid)
                if t.active:
                    active = _('Active')
                else:
                    active = _('Inactive')
                if t.priority:
                    t.task += format(_(', priority: %i'), t.priority)
                at = time.strftime(conf.supybot.reply.format.time(),
                                   time.localtime(t.at))
                s = format(_('%s todo for %s: %s (Added at %s)'), active,
                           user.name, t.task, at)
                irc.reply(s)
            except dbi.NoRecordError:
                irc.errorInvalid(_('task id'), taskid)
Beispiel #34
0
    def dict(self, irc, msg, args, words):
        """[<dictionary>] <word>

        Looks up the definition of <word> on the dictd server specified by
        the supybot.plugins.Dict.server config variable.
        """
        try:
            server = conf.supybot.plugins.Dict.server()
            conn = dictclient.Connection(server)
        except socket.error as e:
            irc.error(utils.web.strError(e), Raise=True)
        dbs = set(conn.getdbdescs())
        if words[0] in dbs:
            dictionary = words.pop(0)
        else:
            default = self.registryValue('default', msg.args[0])
            if default in dbs:
                dictionary = default
            else:
                if default:
                    self.log.info('Default dict for %s is not a supported '
                                  'dictionary: %s.', msg.args[0], default)
                dictionary = '*'
        if not words:
            irc.error(_('You must give a word to define.'), Raise=True)
        word = ' '.join(words)
        definitions = conn.define(dictionary, word)
        dbs = set()
        if not definitions:
            if dictionary == '*':
                irc.reply(format(_('No definition for %q could be found.'),
                                 word))
            else:
                irc.reply(format(_('No definition for %q could be found in '
                                   '%s'), word, ircutils.bold(dictionary)))
            return
        L = []
        for d in definitions:
            dbs.add(ircutils.bold(d.getdb().getname()))
            (db, s) = (d.getdb().getname(), d.getdefstr())
            db = ircutils.bold(db)
            s = utils.str.normalizeWhitespace(s).rstrip(';.,')
            L.append('%s: %s' % (db, s))
        utils.sortBy(len, L)
        if dictionary == '*' and len(dbs) > 1 and \
                self.registryValue("showDictName", msg.args[0]):
            s = format(_('%L responded: %s'), list(dbs), '; '.join(L))
        else:
            s = '; '.join(L)
        irc.reply(s)
Beispiel #35
0
    def todo(self, irc, msg, args, user, taskid):
        """[<username>] [<task id>]

        Retrieves a task for the given task id.  If no task id is given, it
        will return a list of task ids that that user has added to their todo
        list.
        """
        try:
            u = ircdb.users.getUser(msg.prefix)
        except KeyError:
            u = None
        if u != user and not self.registryValue('allowThirdpartyReader'):
            irc.error(_('You are not allowed to see other users todo-list.'))
            return
        # List the active tasks for the given user
        if not taskid:
            try:
                tasks = self.db.getTodos(user.id)
                utils.sortBy(operator.attrgetter('priority'), tasks)
                tasks = [format(_('#%i: %s'), t.id, self._shrink(t.task))
                         for t in tasks]
                Todo = 'Todo'
                if len(tasks) != 1:
                    Todo = 'Todos'
                irc.reply(format(_('%s for %s: %L'),
                                 Todo, user.name, tasks))
            except dbi.NoRecordError:
                if u != user:
                    irc.reply(_('That user has no tasks in their todo list.'))
                else:
                    irc.reply(_('You have no tasks in your todo list.'))
                return
        # Reply with the user's task
        else:
            try:
                t = self.db.get(user.id, taskid)
                if t.active:
                    active = _('Active')
                else:
                    active = _('Inactive')
                if t.priority:
                    t.task += format(_(', priority: %i'), t.priority)
                at = time.strftime(conf.supybot.reply.format.time(),
                                   time.localtime(t.at))
                s = format(_('%s todo for %s: %s (Added at %s)'),
                           active, user.name, t.task, at)
                irc.reply(s)
            except dbi.NoRecordError:
                irc.errorInvalid(_('task id'), taskid)
Beispiel #36
0
    def networks(self, irc, msg, args, opts):
        """[--all]

        Returns the networks to which the bot is currently connected.
        If --all is given, also includes networks known by the bot,
        but not connected to.
        """
        opts = dict(opts)
        L = ['%s: %s' % (ircd.network, ircd.server) for ircd in world.ircs]
        if 'all' in opts:
            for net in conf.supybot.networks._children.keys():
                if net not in [ircd.network for ircd in world.ircs]:
                    L.append('%s: (%s)' % (net, _('disconnected')))
        utils.sortBy(str.lower, L)
        irc.reply(format('%L', L))
Beispiel #37
0
    def networks(self, irc, msg, args, opts):
        """[--all]

        Returns the networks to which the bot is currently connected.
        If --all is given, also includes networks known by the bot,
        but not connected to.
        """
        opts = dict(opts)
        L = ["%s: %s" % (ircd.network, ircd.server) for ircd in world.ircs]
        if "all" in opts:
            for net in conf.supybot.networks._children.keys():
                if net not in [ircd.network for ircd in world.ircs]:
                    L.append("%s: (%s)" % (net, _("disconnected")))
        utils.sortBy(str.lower, L)
        irc.reply(format("%L", L))
Beispiel #38
0
    def nicks(self, irc, msg, args, channel):
        """[<channel>]

        Returns the nicks in <channel>.  <channel> is only necessary if the
        message isn't sent in the channel itself.
        """
        # Make sure we don't elicit information about private channels to
        # people or channels that shouldn't know
        if 's' in irc.state.channels[channel].modes and \
            msg.args[0] != channel and \
            (ircutils.isChannel(msg.args[0]) or \
             msg.nick not in irc.state.channels[channel].users):
            irc.error('You don\'t have access to that information.')
        L = list(irc.state.channels[channel].users)
        utils.sortBy(str.lower, L)
        irc.reply(utils.str.commaAndify(L))
Beispiel #39
0
    def list(self, irc, msg, args, optlist, glob):
        """[--capability=<capability>] [<glob>]

        Returns the valid registered usernames matching <glob>.  If <glob> is
        not given, returns all registered usernames.
        """
        predicates = []
        for (option, arg) in optlist:
            if option == 'capability':
                if arg in conf.supybot.capabilities.private():
                    try:
                        u = ircdb.users.getUser(msg.prefix)
                        if not u._checkCapability('admin'):
                            raise KeyError
                    except KeyError:
                        # Note that it may be raised by checkCapability too.
                        irc.error(_('This is a private capability. Only admins '
                            'can see who has it.'), Raise=True)
                def p(u, cap=arg):
                    try:
                        return u._checkCapability(cap)
                    except KeyError:
                        return False
                predicates.append(p)
        if glob:
            r = re.compile(fnmatch.translate(glob), re.I)
            def p(u):
                return r.match(u.name) is not None
            predicates.append(p)
        users = []
        for u in ircdb.users.values():
            for predicate in predicates:
                if not predicate(u):
                    break
            else:
                users.append(u.name)
        if users:
            utils.sortBy(str.lower, users)
            private = self.registryValue("listInPrivate", msg.args[0])
            irc.reply(format('%L', users), private=private)
        else:
            if predicates:
                irc.reply(_('There are no matching registered users.'))
            else:
                irc.reply(_('There are no registered users.'))
Beispiel #40
0
 def seenWildcard(self, channel, nick):
     nicks = ircutils.IrcSet()
     nickRe = re.compile('^%s$' % '.*'.join(nick.split('*')), re.I)
     for (searchChan, searchNick) in self.keys():
         #print 'chan: %s ... nick: %s' % (searchChan, searchNick)
         if isinstance(searchNick, int):
             # We need to skip the reponses that are keyed by id as they
             # apparently duplicate the responses for the same person that
             # are keyed by nick-string
             continue
         if ircutils.strEqual(searchChan, channel):
             if nickRe.search(searchNick) is not None:
                 nicks.add(searchNick)
     L = [[nick, self.seen(channel, nick)] for nick in nicks]
     def negativeTime(x):
         return -x[1][0]
     utils.sortBy(negativeTime, L)
     return L
Beispiel #41
0
 def seenWildcard(self, channel, nick):
     nicks = ircutils.IrcSet()
     nickRe = re.compile('^%s$' % '.*'.join(nick.split('*')), re.I)
     for (searchChan, searchNick) in self.keys():
         #print 'chan: %s ... nick: %s' % (searchChan, searchNick)
         if isinstance(searchNick, int):
             # We need to skip the reponses that are keyed by id as they
             # apparently duplicate the responses for the same person that
             # are keyed by nick-string
             continue
         if ircutils.strEqual(searchChan, channel):
             if nickRe.search(searchNick) is not None:
                 nicks.add(searchNick)
     L = [[nick, self.seen(channel, nick)] for nick in nicks]
     def negativeTime(x):
         return -x[1][0]
     utils.sortBy(negativeTime, L)
     return L
Beispiel #42
0
 def preserve(self, fd, indent=''):
     def write(s):
         fd.write(indent)
         fd.write(s)
         fd.write(os.linesep)
     write('lobotomized %s' % self.lobotomized)
     write('defaultAllow %s' % self.defaultAllow)
     for capability in self.capabilities:
         write('capability ' + capability)
     bans = self.bans.items()
     utils.sortBy(operator.itemgetter(1), bans)
     for (ban, expiration) in bans:
         write('ban %s %d' % (ban, expiration))
     ignores = self.ignores.items()
     utils.sortBy(operator.itemgetter(1), ignores)
     for (ignore, expiration) in ignores:
         write('ignore %s %d' % (ignore, expiration))
     fd.write(os.linesep)
Beispiel #43
0
    def notes(self, irc, msg, args, nick):
        """[<nick>]

        If <nick> is given, replies with what notes are waiting on <nick>,
        otherwise, replies with the nicks that have notes waiting for them.
        """
        if nick:
            if nick in self._notes:
                notes = [self._formatNote(when, whence, note) for (when, whence, note) in self._notes[nick]]
                irc.reply(format("%L", notes))
            else:
                irc.error(_("I have no notes for that nick."))
        else:
            nicks = self._notes.keys()
            if nicks:
                utils.sortBy(ircutils.toLower, nicks)
                irc.reply(format(_("I currently have notes waiting for %L."), nicks))
            else:
                irc.error(_("I have no notes waiting to be delivered."))
Beispiel #44
0
    def preserve(self, fd, indent=''):
        def write(s):
            fd.write(indent)
            fd.write(s)
            fd.write(os.linesep)

        write('lobotomized %s' % self.lobotomized)
        write('defaultAllow %s' % self.defaultAllow)
        for capability in self.capabilities:
            write('capability ' + capability)
        bans = self.bans.items()
        utils.sortBy(operator.itemgetter(1), bans)
        for (ban, expiration) in bans:
            write('ban %s %d' % (ban, expiration))
        ignores = self.ignores.items()
        utils.sortBy(operator.itemgetter(1), ignores)
        for (ignore, expiration) in ignores:
            write('ignore %s %d' % (ignore, expiration))
        fd.write(os.linesep)
Beispiel #45
0
 def _list(self, irc, group):
     L = []
     for (vname, v) in group._children.items():
         if getattr(group, '_networkValue', False) and \
                 vname.startswith(':'):
             # Skip pseudo-children that are network names
             continue
         if getattr(group, '_channelValue', False) and \
                 irc.isChannel(vname):
             # Skip pseudo-children that are channel names
             continue
         if getattr(v, '_networkValue', False):
             vname = ':' + vname
         if getattr(v, '_channelValue', False):
             vname = '#' + vname
         if v._added and not all(irc.isChannel, v._added):
             vname = '@' + vname
         L.append(vname)
     utils.sortBy(str.lower, L)
     return L
Beispiel #46
0
    def list(self, irc, msg, args, user, optlist):
        """[--{old,sent}] [--{from,to} <user>]

        Retrieves the ids of all your unread notes.  If --old is given, list
        read notes.  If --sent is given, list notes that you have sent.  If
        --from is specified, only lists notes sent to you from <user>.  If
        --to is specified, only lists notes sent by you to <user>.
        """
        (sender, receiver, old, sent) = (None, None, False, False)
        for (option, arg) in optlist:
            if option == "old":
                old = True
            if option == "sent":
                sent = True
            if option == "from":
                sender = arg
            if option == "to":
                receiver = arg
                sent = True
        if old:
            return self._oldnotes(irc, msg, sender)
        if sent:
            return self._sentnotes(irc, msg, receiver)

        def p(note):
            return not note.read and note.to == user.id

        if sender:
            originalP = p

            def p(note):
                return originalP(note) and note.frm == sender.id

        notes = list(self.db.select(p))
        if not notes:
            irc.reply("You have no unread notes.")
        else:
            utils.sortBy(operator.attrgetter("id"), notes)
            ids = [self._formatNoteId(msg, note) for note in notes]
            ids = self._condense(ids)
            irc.reply(format("%L.", ids))
Beispiel #47
0
    def list(self, irc, msg, args, user, optlist):
        """[--{old,sent}] [--{from,to} <user>]

        Retrieves the ids of all your unread notes.  If --old is given, list
        read notes.  If --sent is given, list notes that you have sent.  If
        --from is specified, only lists notes sent to you from <user>.  If
        --to is specified, only lists notes sent by you to <user>.
        """
        (sender, receiver, old, sent) = (None, None, False, False)
        for (option, arg) in optlist:
            if option == 'old':
                old = True
            if option == 'sent':
                sent = True
            if option == 'from':
                sender = arg
            if option == 'to':
                receiver = arg
                sent = True
        if old:
            return self._oldnotes(irc, msg, sender)
        if sent:
            return self._sentnotes(irc, msg, receiver)

        def p(note):
            return not note.read and note.to == user.id

        if sender:
            originalP = p

            def p(note):
                return originalP(note) and note.frm == sender.id

        notes = list(self.db.select(p))
        if not notes:
            irc.reply('You have no unread notes.')
        else:
            utils.sortBy(operator.attrgetter('id'), notes)
            ids = [self._formatNoteId(irc, msg, note) for note in notes]
            ids = self._condense(ids)
            irc.reply(format('%L.', ids))
Beispiel #48
0
    def nicks(self, irc, msg, args, channel):
        """[<channel>]

        Returns the nicks of the people in the channel on the various networks
        the bot is connected to.  <channel> is only necessary if the message
        isn't sent on the channel itself.
        """
        realIrc = self._getRealIrc(irc)
        if channel not in self.registryValue('channels'):
            irc.error(format('I\'m not relaying in %s.', channel))
            return
        users = []
        for otherIrc in world.ircs:
            network = self._getIrcName(otherIrc)
            ops = []
            halfops = []
            voices = []
            usersS = []
            if network != self._getIrcName(realIrc):
                try:
                    Channel = otherIrc.state.channels[channel]
                except KeyError:
                    users.append(format('(not in %s on %s)', channel, network))
                    continue
                numUsers = 0
                for s in Channel.users:
                    s = s.strip()
                    if not s:
                        continue
                    numUsers += 1
                    if s in Channel.ops:
                        ops.append('@' + s)
                    elif s in Channel.halfops:
                        halfops.append('%' + s)
                    elif s in Channel.voices:
                        voices.append('+' + s)
                    else:
                        usersS.append(s)
                utils.sortBy(ircutils.toLower, ops)
                utils.sortBy(ircutils.toLower, voices)
                utils.sortBy(ircutils.toLower, halfops)
                utils.sortBy(ircutils.toLower, usersS)
                usersS = ', '.join(
                    filter(
                        None,
                        list(map(', '.join, (ops, halfops, voices, usersS)))))
                users.append(
                    format('%s (%i): %s', ircutils.bold(network), numUsers,
                           usersS))
        users.sort()
        irc.reply('; '.join(users))
Beispiel #49
0
    def target(self, irc, msg, args, optlist, targets):
        """[--remove] [<target> ...]

        If given no arguments, returns the current list of targets for this
        plugin.  If given any number of targets, will add these targets to
        the current list of targets.  If given --remove and any number of
        targets, will remove those targets from the current list of targets.
        """
        remove = False
        for (option, arg) in optlist:
            if option == 'remove':
                remove = True
        if not targets:
            L = self.registryValue('targets')
            if L:
                utils.sortBy(ircutils.toLower, L)
                irc.reply(format('%L', L))
            else:
                irc.reply('I\'m not currently targeting anywhere.')
        elif remove:
            pass  #XXX
Beispiel #50
0
    def notes(self, irc, msg, args, nick):
        """[<nick>]

        If <nick> is given, replies with what notes are waiting on <nick>,
        otherwise, replies with the nicks that have notes waiting for them.
        """
        if nick:
            if nick in self._notes:
                notes = [self._formatNote(when, whence, note)
                         for (when, whence, note) in self._notes[nick]]
                irc.reply(format('%L', notes))
            else:
                irc.error(_('I have no notes for that nick.'))
        else:
            nicks = self._notes.keys()
            if nicks:
                utils.sortBy(ircutils.toLower, nicks)
                irc.reply(format(_('I currently have notes waiting for %L.'),
                                 nicks))
            else:
                irc.error(_('I have no notes waiting to be delivered.'))
Beispiel #51
0
 def _sentnotes(self, irc, msg, receiver):
     try:
         user = ircdb.users.getUser(msg.prefix)
     except KeyError:
         irc.errorNotRegistered()
         return
     def p(note):
         return note.frm == user.id
     if receiver:
         originalP = p
         def p(note):
             return originalP(note) and note.to == receiver.id
     notes = list(self.db.select(p))
     if not notes:
         irc.error('I couldn\'t find any sent notes for your user.')
     else:
         utils.sortBy(operator.attrgetter('id'), notes)
         notes.reverse() # Most recently sent first.
         ids = [self._formatNoteId(msg, note, sent=True) for note in notes]
         ids = self._condense(ids)
         irc.reply(format('%L.', ids))
Beispiel #52
0
    def target(self, irc, msg, args, optlist, targets):
        """[--remove] [<target> ...]

        If given no arguments, returns the current list of targets for this
        plugin.  If given any number of targets, will add these targets to
        the current list of targets.  If given --remove and any number of
        targets, will remove those targets from the current list of targets.
        """
        remove = False
        for (option, arg) in optlist:
            if option == 'remove':
                remove = True
        if not targets:
            L = self.registryValue('targets')
            if L:
                utils.sortBy(ircutils.toLower, L)
                irc.reply(format('%L', L))
            else:
                irc.reply('I\'m not currently targeting anywhere.')
        elif remove:
            pass #XXX
Beispiel #53
0
    def search(self, irc, msg, args, user, optlist, glob):
        """[--{regexp} <value>] [--sent] [<glob>]

        Searches your received notes for ones matching <glob>.  If --regexp is
        given, its associated value is taken as a regexp and matched against
        the notes.  If --sent is specified, only search sent notes.
        """
        criteria = []

        def to(note):
            return note.to == user.id

        def frm(note):
            return note.frm == user.id

        own = to
        for (option, arg) in optlist:
            if option == 'regexp':
                criteria.append(arg.search)
            elif option == 'sent':
                own = frm
        if glob:
            glob = fnmatch.translate(glob)
            # ignore the trailing $ fnmatch.translate adds to the regexp
            criteria.append(re.compile(glob[:-1]).search)

        def match(note):
            for p in criteria:
                if not p(note.text):
                    return False
            return True

        notes = list(self.db.select(lambda n: match(n) and own(n)))
        if not notes:
            irc.reply('No matching notes were found.')
        else:
            utils.sortBy(operator.attrgetter('id'), notes)
            ids = [self._formatNoteId(msg, note) for note in notes]
            ids = self._condense(ids)
            irc.reply(format('%L', ids))
Beispiel #54
0
    def list(self, irc, msg, args):
        """[<channel>]

        Lists the currently available observers.  If <channel> is given,
        returns the currently active observers on <channel>.
        """
        if args:
            # We don't use getChannel here because we don't want it to
            # automatically pick the channel if the message is sent in
            # the channel itself.
            channel = args.pop(0)
            if args or not ircutils.isChannel(channel):
                raise callbacks.ArgumentError
            observers = self.registryValue('observers.active', channel)
            # We don't sort because order matters.
        else:
            observers = self.registryValue('observers')
            utils.sortBy(str.lower, observers)
        if observers:
            irc.reply(utils.commaAndify(observers))
        else:
            irc.reply('There were no relevant observers.')
Beispiel #55
0
    def guide(self, irc, msg, args):
        """ requires no arguments

        Replies with a greeting.
        """
        x = irc.irc.nick
        xOwners = []
        for u in ircdb.users.itervalues():
            try:
                if u.checkCapability('owner'):
                    xOwners.append(u.name)
            except:
                pass
        if xOwners:
            utils.sortBy(str.lower, xOwners)
            y = 'The registered \'owners\' of this bot are %s. ' \
                'Please report any problems with \'%s\' to them. ' % (
                utils.commaAndify(xOwners), x) 
        else:
            y = ''
        irc.reply(self.helloMessage % (x, x, y, x),
            to=msg.nick, prefixNick=False, private=True)
Beispiel #56
0
    def nicks(self, irc, msg, args, channel, optlist):
        """[<channel>] [--count]

        Returns the nicks in <channel>.  <channel> is only necessary if the
        message isn't sent in the channel itself. Returns only the number of 
        nicks if --count option is provided.
        """
        # Make sure we don't elicit information about private channels to
        # people or channels that shouldn't know
        if 's' in irc.state.channels[channel].modes and \
            msg.args[0] != channel and \
            (ircutils.isChannel(msg.args[0]) or \
             msg.nick not in irc.state.channels[channel].users):
            irc.error('You don\'t have access to that information.',
                      Raise=True)
        L = list(irc.state.channels[channel].users)
        keys = [option for (option, arg) in optlist]
        if 'count' not in keys:
            utils.sortBy(str.lower, L)
            irc.reply(utils.str.commaAndify(L))
        else:
            irc.reply(str(len(L)))
Beispiel #57
0
    def list(self, irc, msg, args):
        """[<channel>]

        Lists the currently available observers.  If <channel> is given,
        returns the currently active observers on <channel>.
        """
        if args:
            # We don't use getChannel here because we don't want it to
            # automatically pick the channel if the message is sent in
            # the channel itself.
            channel = args.pop(0)
            if args or not ircutils.isChannel(channel):
                raise callbacks.ArgumentError
            observers = self.registryValue('observers.active', channel)
            # We don't sort because order matters.
        else:
            observers = self.registryValue('observers')
            utils.sortBy(str.lower, observers)
        if observers:
            irc.reply(utils.commaAndify(observers))
        else:
            irc.reply('There were no relevant observers.')