Example #1
0
 def _normalize(self, m):
     if ircmsgs.isAction(m):
         n = ircmsgs.prettyPrint(m).split(None, 2)
         try:
             return [' '.join(n[:2]), n[2]]
         except IndexError: # empty action
             return [' '.join(n[:2]), '\x00']
     else:
         pretty = ircmsgs.prettyPrint(m).split(None, 1)
         if len(pretty) == 1:
             pretty.append('\x00')
         return pretty
Example #2
0
 def _normalize(self, m):
     if ircmsgs.isAction(m):
         n = ircmsgs.prettyPrint(m).split(None, 2)
         try:
             return [" ".join(n[:2]), n[2]]
         except IndexError:  # empty action
             return [" ".join(n[:2]), "\x00"]
     else:
         pretty = ircmsgs.prettyPrint(m).split(None, 1)
         if len(pretty) == 1:
             pretty.append("\x00")
         return pretty
Example #3
0
 def doPart(self, irc, msg):
     channel = msg.args[0]
     said = ircmsgs.prettyPrint(msg)
     self.anydb.update(channel, msg.nick, said)
     try:
         id = ircdb.users.getUserId(msg.prefix)
         self.anydb.update(channel, id, said)
     except KeyError:
         pass  # Not in the database.
Example #4
0
 def doPart(self, irc, msg):
     channel = msg.args[0]
     said = ircmsgs.prettyPrint(msg)
     self.anydb.update(channel, msg.nick, said)
     try:
         id = ircdb.users.getUserId(msg.prefix)
         self.anydb.update(channel, id, said)
     except KeyError:
         pass # Not in the database.
Example #5
0
 def doQuit(self, irc, msg):
     said = ircmsgs.prettyPrint(msg)
     try:
         id = ircdb.users.getUserId(msg.prefix)
     except KeyError:
         id = None # Not in the database.
     for channel in msg.tagged('channels'):
         self.anydb.update(channel, msg.nick, said)
         if id is not None:
             self.anydb.update(channel, id, said)
Example #6
0
 def doPrivmsg(self, irc, msg):
     if self.shouldRelay(msg):
         target = self.registryValue('target')
         if target and target in irc.state.channels:
             if self.registryValue('fancy'):
                 s = ircmsgs.prettyPrint(msg)
             else:
                 s = msg.args[1]
             s = self.registryValue('prefix') + s
             irc.queueMsg(ircmsgs.privmsg(target, s))
Example #7
0
 def doQuit(self, irc, msg):
     said = ircmsgs.prettyPrint(msg)
     try:
         id = ircdb.users.getUserId(msg.prefix)
     except KeyError:
         id = None  # Not in the database.
     for channel in msg.tagged('channels'):
         self.anydb.update(channel, msg.nick, said)
         if id is not None:
             self.anydb.update(channel, id, said)
Example #8
0
 def doPrivmsg(self, irc, msg):
     if self.shouldRelay(msg):
         target = self.registryValue('target')
         if target and target in irc.state.channels:
             if self.registryValue('fancy'):
                 s = ircmsgs.prettyPrint(msg)
             else:
                 s = msg.args[1]
             s = self.registryValue('prefix') + s
             irc.queueMsg(ircmsgs.privmsg(target, s))
Example #9
0
    def twitter_post(self, irc, msg):
        text = ircmsgs.prettyPrint(msg)
        text = text[text.find('>') + 2:]

        if len(text) > 140:
            text = text[:138] + '...'

        try:
            self.twitter.PostUpdate(text)
        except twitter.TwitterError:
            self.log.exception('Posting quote to twitter failed')
Example #10
0
 def doMode(self, irc, msg):
     # Filter out messages from network Services
     if msg.nick:
         try:
             id = ircdb.users.getUserId(msg.prefix)
         except KeyError:
             id = None # Not in the database.
         channel = msg.args[0]
         said = ircmsgs.prettyPrint(msg)
         self.anydb.update(channel, msg.nick, said)
         if id is not None:
             self.anydb.update(channel, id, said)
Example #11
0
    def wat(self, irc, msg, args, nick):
        """<nick>

        Grabs the last line said by <nick> and returns it with emojis translated
        """
        chan = msg.args[0]
        selfCaller = False
        for m in reversed(irc.state.history):
            if m.command == 'PRIVMSG' and \
            ircutils.nickEqual(m.nick, nick) and \
            ircutils.strEqual(m.args[0], chan):
                if ircutils.nickEqual(nick, msg.nick) and selfCaller:
                    irc.reply(emoji.demojize(ircmsgs.prettyPrint(m)))
                    return
                elif ircutils.nickEqual(nick, msg.nick):
                    selfCaller = True
                    continue
                else:
                    irc.reply(emoji.demojize(ircmsgs.prettyPrint(m)))
                    return
        irc.error(_('I couldn\'t find a proper message to translate.'))
Example #12
0
 def doPrivmsg(self, irc, msg):
     ''' Dummy docstring. '''
     if self.shouldRelay(msg):
         target = self.registryValue('target')
         if target and target in irc.state.channels:
             if self.registryValue('fancy'):
                 s = ircmsgs.prettyPrint(msg)
             else:
                 s = msg.args[1]
             s = self.registryValue('prefix') + s
             self.log.debug("regexrelay, queuing: " + s)
             irc.queueMsg(ircmsgs.privmsg(target, s))
Example #13
0
 def doMode(self, irc, msg):
     # Filter out messages from network Services
     if msg.nick:
         try:
             id = ircdb.users.getUserId(msg.prefix)
         except KeyError:
             id = None  # Not in the database.
         channel = msg.args[0]
         said = ircmsgs.prettyPrint(msg)
         self.anydb.update(channel, msg.nick, said)
         if id is not None:
             self.anydb.update(channel, id, said)
Example #14
0
 def doQuit(self, irc, msg):
     said = ircmsgs.prettyPrint(msg)
     if irc not in self.ircstates:
         return
     try:
         id = ircdb.users.getUserId(msg.prefix)
     except KeyError:
         id = None # Not in the database.
     for channel in self.ircstates[irc].channels:
         if msg.nick in self.ircstates[irc].channels[channel].users:
             self.anydb.update(channel, msg.nick, said)
             if id is not None:
                 self.anydb.update(channel, id, said)
Example #15
0
 def doQuit(self, irc, msg):
     said = ircmsgs.prettyPrint(msg)
     if irc not in self.ircstates:
         return
     try:
         id = ircdb.users.getUserId(msg.prefix)
     except KeyError:
         id = None  # Not in the database.
     for channel in self.ircstates[irc].channels:
         if msg.nick in self.ircstates[irc].channels[channel].users:
             self.anydb.update(channel, msg.nick, said)
             if id is not None:
                 self.anydb.update(channel, id, said)
Example #16
0
 def doPrivmsg(self, irc, msg):
     if ircmsgs.isCtcp(msg) and not ircmsgs.isAction(msg):
         return
     if msg.channel:
         channel = msg.channel
         said = ircmsgs.prettyPrint(msg)
         self.db.update(channel, msg.nick, said)
         self.anydb.update(channel, msg.nick, said)
         try:
             id = ircdb.users.getUserId(msg.prefix)
             self.db.update(channel, id, said)
             self.anydb.update(channel, id, said)
         except KeyError:
             pass  # Not in the database.
Example #17
0
 def doPrivmsg(self, irc, msg):
     if ircmsgs.isCtcp(msg) and not ircmsgs.isAction(msg):
         return
     if irc.isChannel(msg.args[0]):
         channel = msg.args[0]
         said = ircmsgs.prettyPrint(msg)
         self.db.update(channel, msg.nick, said)
         self.anydb.update(channel, msg.nick, said)
         try:
             id = ircdb.users.getUserId(msg.prefix)
             self.db.update(channel, id, said)
             self.anydb.update(channel, id, said)
         except KeyError:
             pass # Not in the database.
Example #18
0
 def add(self, channel, msg, by):
     db = self._getDb(channel)
     cursor = db.cursor()
     text = ircmsgs.prettyPrint(msg)
     # Check to see if the latest quotegrab is identical
     cursor.execute("""SELECT quote FROM quotegrabs
                       WHERE nick=%s
                       ORDER BY id DESC LIMIT 1""", msg.nick)
     if cursor.rowcount != 0:
         if text == cursor.fetchone()[0]:
             return
     cursor.execute("""INSERT INTO quotegrabs
                       VALUES (NULL, %s, %s, %s, %s, %s)""",
                    msg.nick, msg.prefix, by, int(time.time()), text)
     db.commit()
Example #19
0
 def add(self, channel, msg, by):
     db = self._getDb(channel)
     cursor = db.cursor()
     text = ircmsgs.prettyPrint(msg)
     # Check to see if the latest quotegrab is identical
     cursor.execute("""SELECT quote FROM quotegrabs
                       WHERE nick=?
                       ORDER BY id DESC LIMIT 1""", (msg.nick,))
     results = cursor.fetchall()
     if len(results) != 0:
         if text == results[0][0]:
             return
     cursor.execute("""INSERT INTO quotegrabs
                       VALUES (NULL, ?, ?, ?, ?, ?)""",
                    (msg.nick, msg.prefix, by, int(time.time()), text,))
     db.commit()
Example #20
0
 def add(self, msg, by):
     channel = msg.args[0]
     db = self.getDb(channel)
     cursor = db.cursor()
     text = ircmsgs.prettyPrint(msg)
     # Check to see if the latest quotegrab is identical
     cursor.execute("""SELECT quote FROM quotegrabs
                       WHERE nick=?
                       ORDER BY id DESC LIMIT 1""", (msg.nick,))
     quote = cursor.fetchone()
     if quote and text == quote[0]:
         return
     cursor.execute("""INSERT INTO quotegrabs
                       VALUES (NULL, ?, ?, ?, ?, ?, 0)""",
                    (msg.nick, msg.prefix, by, int(time.time()), text))
     db.commit()
Example #21
0
 def add(self, channel, msg, by):
     db = self._getDb(channel)
     cursor = db.cursor()
     text = ircmsgs.prettyPrint(msg)
     # Check to see if the latest quotegrab is identical
     cursor.execute("""SELECT quote FROM quotegrabs
                       WHERE nick=?
                       ORDER BY id DESC LIMIT 1""", (msg.nick,))
     results = cursor.fetchall()
     if len(results) != 0:
         if text == results[0][0]:
             return
     cursor.execute("""INSERT INTO quotegrabs
                       VALUES (NULL, ?, ?, ?, ?, ?)""",
                    (msg.nick, msg.prefix, by, int(time.time()), text,))
     db.commit()
Example #22
0
 def add(self, channel, msg, by):
     db = self._getDb(channel)
     cursor = db.cursor()
     text = ircmsgs.prettyPrint(msg)
     # Check to see if the latest quotegrab is identical
     cursor.execute(
         """SELECT quote FROM quotegrabs
                       WHERE nick=%s
                       ORDER BY id DESC LIMIT 1""", msg.nick)
     if cursor.rowcount != 0:
         if text == cursor.fetchone()[0]:
             return
     cursor.execute(
         """INSERT INTO quotegrabs
                       VALUES (NULL, %s, %s, %s, %s, %s)""", msg.nick,
         msg.prefix, by, int(time.time()), text)
     db.commit()
Example #23
0
 def add(self, msg, by):
     channel = msg.args[0]
     db = self.getDb(channel)
     cursor = db.cursor()
     text = ircmsgs.prettyPrint(msg)
     # Check to see if the latest quotegrab is identical
     cursor.execute(
         """SELECT quote FROM quotegrabs
                       WHERE nick=?
                       ORDER BY id DESC LIMIT 1""", (msg.nick, ))
     quote = cursor.fetchone()
     if quote and text == quote[0]:
         return
     cursor.execute(
         """INSERT INTO quotegrabs
                       VALUES (NULL, ?, ?, ?, ?, ?, 0)""",
         (msg.nick, msg.prefix, by, int(time.time()), text))
     db.commit()
Example #24
0
    def doPrivmsg(self, irc, msg):
        __dir__ = os.path.dirname(os.path.abspath(__file__))

        if not irc.isChannel(msg.args[0]):
            return

        curTime = time.time()
        channel = msg.args[0]
        said = ircmsgs.prettyPrint(msg, showNick=False)
        nick = msg.nick

        print("Checking %s %s: %s at time %d" % (channel, nick, said, curTime))

        if said.find("I CALL UPON THE POWER OF THE SPREADSHEET") != -1:
            if (self.lastPull + SS_DOWNLOAD_SECONDS) < curTime:
                irc.reply("loading hacking tools...")
                os.system("cd " + __dir__ + "; ./get_new_opinions.sh")
                irc.reply("hacking tools loaded, %d hacks total" %
                          (len(self.opinions), ))
                self.load_opinions()
                self.lastPull = time.time()
                self.lastSent = time.time() - COOL_DOWN_SECONDS  # allow test
            else:
                print("ignored %s, %d minutes remain" %
                      (said,
                       ((self.lastPull + SS_DOWNLOAD_SECONDS) - curTime) / 60))
            return

        didReply = False
        for (reg, res) in self.opinions:
            # match beginning of string/whitespace word end of string/whitespace
            m = reg.search(said)
            if m is not None:
                if (self.lastSent + COOL_DOWN_SECONDS) < curTime:
                    irc.reply(m.group(2) + res)
                    didReply = True
                else:
                    print(
                        "ignored %s, %d minutes remain" %
                        (said,
                         ((self.lastSent + COOL_DOWN_SECONDS) - curTime) / 60))

        if didReply:
            self.lastSent = time.time()
Example #25
0
    def doPrivmsg(self, irc, msg):
        curTime = time.time()
        if (self.lastSent + COOL_DOWN_SECONDS) > curTime:
            return  # skip, we're cooling down

        if irc.isChannel(msg.args[0]):
            channel = msg.args[0]
            said = ircmsgs.prettyPrint(msg, showNick=False)
            nick = msg.nick

            __dir__ = os.path.dirname(os.path.abspath(__file__))
            filepath = os.path.join(__dir__, "opinions.csv")

            opinions = csv.reader(open(filepath, "rb"))
            for row in opinions:
                # match beginning of string/whitespace word end of string/whitespace
                if re.search("(\(|\s|^)" + row[0].lower() + "(\s|\)|\.|\?|\!|$)", said.lower()) is not None:
                    irc.reply(row[0] + "? " + row[1] + ". " + ",".join(row[2:]))
                    self.lastSent = time.time()
Example #26
0
    def doPrivmsg(self, irc, msg):
        __dir__ = os.path.dirname(os.path.abspath(__file__))

        if not irc.isChannel(msg.args[0]):
            return 

        curTime = time.time()
        channel = msg.args[0]
        said = ircmsgs.prettyPrint(msg, showNick=False)
        nick = msg.nick

        print("Checking %s %s: %s at time %d" % (channel, nick, said, curTime));

        if said.find("I CALL UPON THE POWER OF THE SPREADSHEET") != -1:
            if (self.lastPull + SS_DOWNLOAD_SECONDS) < curTime:
                irc.reply("loading hacking tools...")
                os.system("cd " + __dir__ + "; ./get_new_opinions.sh")
                irc.reply("hacking tools loaded, %d hacks total" % (len(self.opinions),))
                self.load_opinions()
                self.lastPull = time.time()
                self.lastSent = time.time() - COOL_DOWN_SECONDS # allow test
            else:
                print("ignored %s, %d minutes remain" % 
                    (said, 
                    ((self.lastPull + SS_DOWNLOAD_SECONDS) - curTime)/60))
            return

        didReply = False
        for (reg, res) in self.opinions:
            # match beginning of string/whitespace word end of string/whitespace
            m = reg.search(said)
            if m is not None:
                if (self.lastSent + COOL_DOWN_SECONDS) < curTime:
                    irc.reply(m.group(2) + res)
                    didReply = True
                else:
                    print("ignored %s, %d minutes remain" % 
                        (said, 
                        ((self.lastSent + COOL_DOWN_SECONDS) - curTime)/60))

        if didReply:
            self.lastSent = time.time()
Example #27
0
    def last(self, irc, msg, args, optlist):
        """[--{from,in,on,with,without,regexp} <value>] [--nolimit]

        Returns the last message matching the given criteria.  --from requires
        a nick from whom the message came; --in requires a channel the message
        was sent to; --on requires a network the message was sent on; --with
        requires some string that had to be in the message; --regexp requires
        a regular expression the message must match; --nolimit returns all
        the messages that can be found.  By default, the channel this command is
        given in is searched.
        """
        predicates = {}
        nolimit = False
        skipfirst = True
        if ircutils.isChannel(msg.args[0]):
            predicates["in"] = lambda m: ircutils.strEqual(m.args[0], msg.args[0])
        else:
            skipfirst = False
        for (option, arg) in optlist:
            if option == "from":

                def f(m, arg=arg):
                    return ircutils.hostmaskPatternEqual(arg, m.nick)

                predicates["from"] = f
            elif option == "in":

                def f(m, arg=arg):
                    return ircutils.strEqual(m.args[0], arg)

                predicates["in"] = f
                if arg != msg.args[0]:
                    skipfirst = False
            elif option == "on":

                def f(m, arg=arg):
                    return m.receivedOn == arg

                predicates["on"] = f
            elif option == "with":

                def f(m, arg=arg):
                    return arg.lower() in m.args[1].lower()

                predicates.setdefault("with", []).append(f)
            elif option == "without":

                def f(m, arg=arg):
                    return arg.lower() not in m.args[1].lower()

                predicates.setdefault("without", []).append(f)
            elif option == "regexp":

                def f(m, arg=arg):
                    def f1(s, arg):
                        """Since we can't enqueue match objects into the multiprocessing queue,
                        we'll just wrap the function to return bools."""
                        if arg.search(s) is not None:
                            return True
                        else:
                            return False

                    if ircmsgs.isAction(m):
                        m1 = ircmsgs.unAction(m)
                        # return arg.search(ircmsgs.unAction(m))
                    else:
                        m1 = m.args[1]
                        # return arg.search(m.args[1])
                    try:
                        # use a subprocess here, since specially crafted regexps can
                        # take exponential time and hang up the bot.
                        # timeout of 0.1 should be more than enough for any normal regexp.
                        v = commands.process(f1, m1, arg, timeout=0.1, pn=self.name(), cn="last")
                        return v
                    except commands.ProcessTimeoutError:
                        return False

                predicates.setdefault("regexp", []).append(f)
            elif option == "nolimit":
                nolimit = True
        iterable = ifilter(self._validLastMsg, reversed(irc.state.history))
        if skipfirst:
            # Drop the first message only if our current channel is the same as
            # the channel we've been instructed to look at.
            iterable.next()
        predicates = list(utils.iter.flatten(predicates.itervalues()))
        # Make sure the user can't get messages from channels they aren't in
        def userInChannel(m):
            return m.args[0] in irc.state.channels and msg.nick in irc.state.channels[m.args[0]].users

        predicates.append(userInChannel)
        # Make sure the user can't get messages from a +s channel unless
        # they're calling the command from that channel or from a query
        def notSecretMsg(m):
            return (
                not irc.isChannel(msg.args[0])
                or msg.args[0] == m.args[0]
                or (m.args[0] in irc.state.channels and "s" not in irc.state.channels[m.args[0]].modes)
            )

        predicates.append(notSecretMsg)
        resp = []
        if irc.nested and not self.registryValue("last.nested.includeTimestamp"):
            tsf = None
        else:
            tsf = self.registryValue("timestampFormat")
        if irc.nested and not self.registryValue("last.nested.includeNick"):
            showNick = False
        else:
            showNick = True
        for m in iterable:
            for predicate in predicates:
                try:
                    if not predicate(m):
                        break
                except RegexpTimeout:
                    irc.error(_("The regular expression timed out."))
                    return
            else:
                if nolimit:
                    resp.append(ircmsgs.prettyPrint(m, timestampFormat=tsf, showNick=showNick))
                else:
                    irc.reply(ircmsgs.prettyPrint(m, timestampFormat=tsf, showNick=showNick))
                    return
        if not resp:
            irc.error(
                _("I couldn't find a message matching that criteria in " "my history of %s messages.")
                % len(irc.state.history)
            )
        else:
            irc.reply(format("%L", resp))
Example #28
0
    def last(self, irc, msg, args, optlist):
        """[--{from,in,on,with,without,regexp} <value>] [--nolimit]

        Returns the last message matching the given criteria.  --from requires
        a nick from whom the message came; --in requires a channel the message
        was sent to; --on requires a network the message was sent on; --with
        requires some string that had to be in the message; --regexp requires
        a regular expression the message must match; --nolimit returns all
        the messages that can be found.  By default, the channel this command is
        given in is searched.
        """
        predicates = {}
        nolimit = False
        skipfirst = True
        if msg.channel:
            predicates['in'] = lambda m: ircutils.strEqual(
                m.args[0], msg.channel)
        else:
            skipfirst = False

        final_predicates = []

        for (option, arg) in optlist:
            if option == 'from':

                def f(m, arg=arg):
                    return ircutils.hostmaskPatternEqual(arg, m.nick)

                predicates['from'] = f
            elif option == 'in':

                def f(m, arg=arg):
                    return ircutils.strEqual(m.args[0], arg)

                predicates['in'] = f
                if arg != msg.channel:
                    skipfirst = False
            elif option == 'on':

                def f(m, arg=arg):
                    return m.receivedOn == arg

                predicates['on'] = f
            elif option == 'with':

                def f(m, arg=arg):
                    return arg.lower() in m.args[1].lower()

                predicates.setdefault('with', []).append(f)
            elif option == 'without':

                def f(m, arg=arg):
                    return arg.lower() not in m.args[1].lower()

                predicates.setdefault('without', []).append(f)
            elif option == 'regexp':

                def f(messages, arg=arg):
                    reobj = re.compile(arg)

                    # using a queue to return results, so we can return at
                    # least some results in case of timeout
                    q = multiprocessing.Queue()

                    def p(messages):
                        for m in messages:
                            if ircmsgs.isAction(m):
                                s = ircmsgs.unAction(m)
                            else:
                                s = m.args[1]
                            if reobj.search(s):
                                q.put(m)

                    try:
                        process(p,
                                messages,
                                timeout=3.,
                                pn=self.name(),
                                cn='last')
                    except ProcessTimeoutError:
                        pass
                    results = []
                    while True:
                        try:
                            results.append(q.get(False))
                        except queue.Empty:
                            break
                    return results

                final_predicates.append(f)
            elif option == 'nolimit':
                nolimit = True
        iterable = filter(functools.partial(self._validLastMsg, irc),
                          reversed(irc.state.history))
        if skipfirst:
            # Drop the first message only if our current channel is the same as
            # the channel we've been instructed to look at.
            next(iterable)
        predicates = list(utils.iter.flatten(predicates.values()))

        # Make sure the user can't get messages from channels they aren't in
        def userInChannel(m):
            return m.args[0] in irc.state.channels \
                    and msg.nick in irc.state.channels[m.args[0]].users

        predicates.append(userInChannel)

        # Make sure the user can't get messages from a +s channel unless
        # they're calling the command from that channel or from a query
        # TODO: support statusmsg, but be careful about leaking scopes.
        def notSecretMsg(m):
            return not irc.isChannel(msg.args[0]) \
                    or msg.args[0] == m.args[0] \
                    or (m.args[0] in irc.state.channels \
                        and 's' not in irc.state.channels[m.args[0]].modes)

        predicates.append(notSecretMsg)
        resp = []
        if irc.nested and not \
          self.registryValue('last.nested.includeTimestamp'):
            tsf = None
        else:
            tsf = self.registryValue('timestampFormat')
        if irc.nested and not self.registryValue('last.nested.includeNick'):
            showNick = False
        else:
            showNick = True

        candidates = []

        # Run predicates that filter on individual messages
        for m in iterable:
            for predicate in predicates:
                if not predicate(m):
                    break
            else:
                candidates.append(m)

        # Run predicates that filter lists of messages
        for predicate in final_predicates:
            candidates = predicate(candidates)

        for m in candidates:
            if nolimit:
                resp.append(
                    ircmsgs.prettyPrint(m,
                                        timestampFormat=tsf,
                                        showNick=showNick))
            else:
                irc.reply(
                    ircmsgs.prettyPrint(m,
                                        timestampFormat=tsf,
                                        showNick=showNick))
                return

        if not resp:
            irc.error(
                _('I couldn\'t find a message matching that criteria in '
                  'my history of %s messages.') % len(irc.state.history))
        else:
            irc.reply(format('%L', resp))
Example #29
0
    def last(self, irc, msg, args, optlist):
        """[--{from,in,on,with,without,regexp} <value>] [--nolimit]

        Returns the last message matching the given criteria.  --from requires
        a nick from whom the message came; --in requires a channel the message
        was sent to; --on requires a network the message was sent on; --with
        requires some string that had to be in the message; --regexp requires
        a regular expression the message must match; --nolimit returns all
        the messages that can be found.  By default, the channel this command is
        given in is searched.
        """
        predicates = {}
        nolimit = False
        skipfirst = True
        if ircutils.isChannel(msg.args[0]):
            predicates["in"] = lambda m: ircutils.strEqual(m.args[0], msg.args[0])
        else:
            skipfirst = False
        for (option, arg) in optlist:
            if option == "from":

                def f(m, arg=arg):
                    return ircutils.hostmaskPatternEqual(arg, m.nick)

                predicates["from"] = f
            elif option == "in":

                def f(m, arg=arg):
                    return ircutils.strEqual(m.args[0], arg)

                predicates["in"] = f
                if arg != msg.args[0]:
                    skipfirst = False
            elif option == "on":

                def f(m, arg=arg):
                    return m.receivedOn == arg

                predicates["on"] = f
            elif option == "with":

                def f(m, arg=arg):
                    return arg.lower() in m.args[1].lower()

                predicates.setdefault("with", []).append(f)
            elif option == "without":

                def f(m, arg=arg):
                    return arg.lower() not in m.args[1].lower()

                predicates.setdefault("without", []).append(f)
            elif option == "regexp":

                def f(m, arg=arg):
                    if ircmsgs.isAction(m):
                        m1 = ircmsgs.unAction(m)
                    else:
                        m1 = m.args[1]
                    return regexp_wrapper(m1, reobj=arg, timeout=0.1, plugin_name=self.name(), fcn_name="last")

                predicates.setdefault("regexp", []).append(f)
            elif option == "nolimit":
                nolimit = True
        iterable = ifilter(self._validLastMsg, reversed(irc.state.history))
        if skipfirst:
            # Drop the first message only if our current channel is the same as
            # the channel we've been instructed to look at.
            iterable.next()
        predicates = list(utils.iter.flatten(predicates.itervalues()))
        # Make sure the user can't get messages from channels they aren't in
        def userInChannel(m):
            return m.args[0] in irc.state.channels and msg.nick in irc.state.channels[m.args[0]].users

        predicates.append(userInChannel)
        # Make sure the user can't get messages from a +s channel unless
        # they're calling the command from that channel or from a query
        def notSecretMsg(m):
            return (
                not irc.isChannel(msg.args[0])
                or msg.args[0] == m.args[0]
                or (m.args[0] in irc.state.channels and "s" not in irc.state.channels[m.args[0]].modes)
            )

        predicates.append(notSecretMsg)
        resp = []
        if irc.nested and not self.registryValue("last.nested.includeTimestamp"):
            tsf = None
        else:
            tsf = self.registryValue("timestampFormat")
        if irc.nested and not self.registryValue("last.nested.includeNick"):
            showNick = False
        else:
            showNick = True
        for m in iterable:
            for predicate in predicates:
                if not predicate(m):
                    break
            else:
                if nolimit:
                    resp.append(ircmsgs.prettyPrint(m, timestampFormat=tsf, showNick=showNick))
                else:
                    irc.reply(ircmsgs.prettyPrint(m, timestampFormat=tsf, showNick=showNick))
                    return
        if not resp:
            irc.error(
                "I couldn't find a message matching that criteria in "
                "my history of %s messages." % len(irc.state.history)
            )
        else:
            irc.reply(format("%L", resp))
Example #30
0
    def last(self, irc, msg, args, optlist):
        """[--{from,in,on,with,without,regexp} <value>] [--nolimit]

        Returns the last message matching the given criteria.  --from requires
        a nick from whom the message came; --in requires a channel the message
        was sent to; --on requires a network the message was sent on; --with
        requires some string that had to be in the message; --regexp requires
        a regular expression the message must match; --nolimit returns all
        the messages that can be found.  By default, the channel this command is
        given in is searched.
        """
        predicates = {}
        nolimit = False
        skipfirst = True
        if ircutils.isChannel(msg.args[0]):
            predicates['in'] = lambda m: ircutils.strEqual(
                m.args[0], msg.args[0])
        else:
            skipfirst = False
        for (option, arg) in optlist:
            if option == 'from':

                def f(m, arg=arg):
                    return ircutils.hostmaskPatternEqual(arg, m.nick)

                predicates['from'] = f
            elif option == 'in':

                def f(m, arg=arg):
                    return ircutils.strEqual(m.args[0], arg)

                predicates['in'] = f
                if arg != msg.args[0]:
                    skipfirst = False
            elif option == 'on':

                def f(m, arg=arg):
                    return m.receivedOn == arg

                predicates['on'] = f
            elif option == 'with':

                def f(m, arg=arg):
                    return arg.lower() in m.args[1].lower()

                predicates.setdefault('with', []).append(f)
            elif option == 'without':

                def f(m, arg=arg):
                    return arg.lower() not in m.args[1].lower()

                predicates.setdefault('without', []).append(f)
            elif option == 'regexp':

                def f(m, arg=arg):
                    if ircmsgs.isAction(m):
                        return arg.search(ircmsgs.unAction(m))
                    else:
                        return arg.search(m.args[1])

                predicates.setdefault('regexp', []).append(f)
            elif option == 'nolimit':
                nolimit = True
        iterable = ifilter(self._validLastMsg, reversed(irc.state.history))
        if skipfirst:
            # Drop the first message only if our current channel is the same as
            # the channel we've been instructed to look at.
            iterable.next()
        predicates = list(utils.iter.flatten(predicates.itervalues()))

        # Make sure the user can't get messages from channels they aren't in
        def userInChannel(m):
            return m.args[0] in irc.state.channels \
                    and msg.nick in irc.state.channels[m.args[0]].users

        predicates.append(userInChannel)

        # Make sure the user can't get messages from a +s channel unless
        # they're calling the command from that channel or from a query
        def notSecretMsg(m):
            return not irc.isChannel(msg.args[0]) \
                    or msg.args[0] == m.args[0] \
                    or (m.args[0] in irc.state.channels \
                        and 's' not in irc.state.channels[m.args[0]].modes)

        predicates.append(notSecretMsg)
        resp = []
        if irc.nested and not \
          self.registryValue('last.nested.includeTimestamp'):
            tsf = None
        else:
            tsf = self.registryValue('timestampFormat')
        if irc.nested and not self.registryValue('last.nested.includeNick'):
            showNick = False
        else:
            showNick = True
        for m in iterable:
            for predicate in predicates:
                if not predicate(m):
                    break
            else:
                if nolimit:
                    resp.append(
                        ircmsgs.prettyPrint(m,
                                            timestampFormat=tsf,
                                            showNick=showNick))
                else:
                    irc.reply(
                        ircmsgs.prettyPrint(m,
                                            timestampFormat=tsf,
                                            showNick=showNick))
                    return
        if not resp:
            irc.error('I couldn\'t find a message matching that criteria in '
                      'my history of %s messages.' % len(irc.state.history))
        else:
            irc.reply(format('%L', resp))
Example #31
0
    def last(self, irc, msg, args, optlist):
        """[--{from,in,on,with,without,regexp} <value>] [--nolimit]

        Returns the last message matching the given criteria.  --from requires
        a nick from whom the message came; --in requires a channel the message
        was sent to; --on requires a network the message was sent on; --with
        requires some string that had to be in the message; --regexp requires
        a regular expression the message must match; --nolimit returns all
        the messages that can be found.  By default, the channel this command is
        given in is searched.
        """
        predicates = {}
        nolimit = False
        skipfirst = True
        if ircutils.isChannel(msg.args[0]):
            predicates['in'] = lambda m: ircutils.strEqual(m.args[0],
                                                           msg.args[0])
        else:
            skipfirst = False
        for (option, arg) in optlist:
            if option == 'from':
                def f(m, arg=arg):
                    return ircutils.hostmaskPatternEqual(arg, m.nick)
                predicates['from'] = f
            elif option == 'in':
                def f(m, arg=arg):
                    return ircutils.strEqual(m.args[0], arg)
                predicates['in'] = f
                if arg != msg.args[0]:
                    skipfirst = False
            elif option == 'on':
                def f(m, arg=arg):
                    return m.receivedOn == arg
                predicates['on'] = f
            elif option == 'with':
                def f(m, arg=arg):
                    return arg.lower() in m.args[1].lower()
                predicates.setdefault('with', []).append(f)
            elif option == 'without':
                def f(m, arg=arg):
                    return arg.lower() not in m.args[1].lower()
                predicates.setdefault('without', []).append(f)
            elif option == 'regexp':
                def f(m, arg=arg):
                    def f1(s, arg):
                        """Since we can't enqueue match objects into the multiprocessing queue,
                        we'll just wrap the function to return bools."""
                        if arg.search(s) is not None:
                            return True
                        else:
                            return False
                    if ircmsgs.isAction(m):
                        m1 = ircmsgs.unAction(m)
                    else:
                        m1 = m.args[1]
                    return regexp_wrapper(m1, reobj=arg, timeout=0.1,
                                          plugin_name=self.name(),
                                          fcn_name='last')
                predicates.setdefault('regexp', []).append(f)
            elif option == 'nolimit':
                nolimit = True
        iterable = filter(self._validLastMsg, reversed(irc.state.history))
        if skipfirst:
            # Drop the first message only if our current channel is the same as
            # the channel we've been instructed to look at.
            next(iterable)
        predicates = list(utils.iter.flatten(predicates.itervalues()))
        # Make sure the user can't get messages from channels they aren't in
        def userInChannel(m):
            return m.args[0] in irc.state.channels \
                    and msg.nick in irc.state.channels[m.args[0]].users
        predicates.append(userInChannel)
        # Make sure the user can't get messages from a +s channel unless
        # they're calling the command from that channel or from a query
        def notSecretMsg(m):
            return not irc.isChannel(msg.args[0]) \
                    or msg.args[0] == m.args[0] \
                    or (m.args[0] in irc.state.channels \
                        and 's' not in irc.state.channels[m.args[0]].modes)
        predicates.append(notSecretMsg)
        resp = []
        if irc.nested and not \
          self.registryValue('last.nested.includeTimestamp'):
            tsf = None
        else:
            tsf = self.registryValue('timestampFormat')
        if irc.nested and not self.registryValue('last.nested.includeNick'):
            showNick = False
        else:
            showNick = True
        for m in iterable:
            for predicate in predicates:
                try:
                    if not predicate(m):
                        break
                except RegexpTimeout:
                    irc.error(_('The regular expression timed out.'))
                    return
            else:
                if nolimit:
                    resp.append(ircmsgs.prettyPrint(m,
                                                    timestampFormat=tsf,
                                                    showNick=showNick))
                else:
                    irc.reply(ircmsgs.prettyPrint(m,
                                                  timestampFormat=tsf,
                                                  showNick=showNick))
                    return
        if not resp:
            irc.error(_('I couldn\'t find a message matching that criteria in '
                      'my history of %s messages.') % len(irc.state.history))
        else:
            irc.reply(format('%L', resp))
Example #32
0
    def last(self, irc, msg, args, optlist):
        """[--{from,in,on,with,without,regexp} <value>] [--nolimit]

        Returns the last message matching the given criteria.  --from requires
        a nick from whom the message came; --in requires a channel the message
        was sent to; --on requires a network the message was sent on; --with
        requires some string that had to be in the message; --regexp requires
        a regular expression the message must match; --nolimit returns all
        the messages that can be found.  By default, the channel this command is
        given in is searched.
        """
        predicates = {}
        nolimit = False
        skipfirst = True
        if msg.channel:
            predicates['in'] = lambda m: ircutils.strEqual(
                m.args[0], msg.channel)
        else:
            skipfirst = False
        for (option, arg) in optlist:
            if option == 'from':

                def f(m, arg=arg):
                    return ircutils.hostmaskPatternEqual(arg, m.nick)

                predicates['from'] = f
            elif option == 'in':

                def f(m, arg=arg):
                    return ircutils.strEqual(m.args[0], arg)

                predicates['in'] = f
                if arg != msg.channel:
                    skipfirst = False
            elif option == 'on':

                def f(m, arg=arg):
                    return m.receivedOn == arg

                predicates['on'] = f
            elif option == 'with':

                def f(m, arg=arg):
                    return arg.lower() in m.args[1].lower()

                predicates.setdefault('with', []).append(f)
            elif option == 'without':

                def f(m, arg=arg):
                    return arg.lower() not in m.args[1].lower()

                predicates.setdefault('without', []).append(f)
            elif option == 'regexp':

                def f(m, arg=arg):
                    def f1(s, arg):
                        """Since we can't enqueue match objects into the multiprocessing queue,
                        we'll just wrap the function to return bools."""
                        if process(arg.search, s, timeout=0.1) is not None:
                            return True
                        else:
                            return False

                    if ircmsgs.isAction(m):
                        m1 = ircmsgs.unAction(m)
                    else:
                        m1 = m.args[1]
                    return regexp_wrapper(m1,
                                          reobj=arg,
                                          timeout=0.1,
                                          plugin_name=self.name(),
                                          fcn_name='last')

                predicates.setdefault('regexp', []).append(f)
            elif option == 'nolimit':
                nolimit = True
        iterable = filter(functools.partial(self._validLastMsg, irc),
                          reversed(irc.state.history))
        if skipfirst:
            # Drop the first message only if our current channel is the same as
            # the channel we've been instructed to look at.
            next(iterable)
        predicates = list(utils.iter.flatten(predicates.values()))

        # Make sure the user can't get messages from channels they aren't in
        def userInChannel(m):
            return m.args[0] in irc.state.channels \
                    and msg.nick in irc.state.channels[m.args[0]].users

        predicates.append(userInChannel)

        # Make sure the user can't get messages from a +s channel unless
        # they're calling the command from that channel or from a query
        # TODO: support statusmsg, but be careful about leaking scopes.
        def notSecretMsg(m):
            return not irc.isChannel(msg.args[0]) \
                    or msg.args[0] == m.args[0] \
                    or (m.args[0] in irc.state.channels \
                        and 's' not in irc.state.channels[m.args[0]].modes)

        predicates.append(notSecretMsg)
        resp = []
        if irc.nested and not \
          self.registryValue('last.nested.includeTimestamp'):
            tsf = None
        else:
            tsf = self.registryValue('timestampFormat')
        if irc.nested and not self.registryValue('last.nested.includeNick'):
            showNick = False
        else:
            showNick = True
        for m in iterable:
            for predicate in predicates:
                try:
                    if not predicate(m):
                        break
                except RegexpTimeout:
                    irc.error(_('The regular expression timed out.'))
                    return
            else:
                if nolimit:
                    resp.append(
                        ircmsgs.prettyPrint(m,
                                            timestampFormat=tsf,
                                            showNick=showNick))
                else:
                    irc.reply(
                        ircmsgs.prettyPrint(m,
                                            timestampFormat=tsf,
                                            showNick=showNick))
                    return
        if not resp:
            irc.error(
                _('I couldn\'t find a message matching that criteria in '
                  'my history of %s messages.') % len(irc.state.history))
        else:
            irc.reply(format('%L', resp))