Exemple #1
0
    def doPrivmsg(self, irc, msg):
        """ Handle everything.

        The name is misleading.  This hook actually gets called for all
        IRC activity in every channel.
        """
        # We don't handle this if we've been addressed because invalidCommand
        # will handle it for us.  This prevents us from accessing the db twice
        # and therefore crashing.
        if (msg.addressed or msg.repliedTo):
            return

        channel = msg.args[0]
        if irc.isChannel(channel) and self.allow_unaddressed_karma:
            irc = callbacks.SimpleProxy(irc, msg)
            agent = msg.nick
            line = msg.args[1].strip()

            # First try to handle karma commands
            words = line.split()
            for word in words:
                if word[-2:] in self.karma_tokens:
                    self._do_karma(
                        irc, channel, agent, word, line, explicit=False)

        blacklist = self.registryValue('naked_ping_channel_blacklist')
        if irc.isChannel(channel) and not channel in blacklist:
            # Also, handle naked pings for
            # https://github.com/fedora-infra/supybot-fedora/issues/26
            pattern = '\w* ?[:,] ?ping\W*$'
            if re.match(pattern, line):
                admonition = self.registryValue('naked_ping_admonition')
                irc.reply(admonition)
Exemple #2
0
 def doPrivmsg(self, irc, msg):
     if ircmsgs.isCtcp(msg) and not ircmsgs.isAction(msg):
         return
     irc = callbacks.SimpleProxy(irc, msg)
     if msg.channel:
         payload = msg.args[1]
         words = self.registryValue('randomGrabber.minimumWords',
                                    msg.channel, irc.network)
         length = self.registryValue('randomGrabber.minimumCharacters',
                                     msg.channel, irc.network)
         grabTime = \
         self.registryValue('randomGrabber.averageTimeBetweenGrabs',
                            msg.channel, irc.network)
         channel = plugins.getChannel(msg.channel)
         if self.registryValue('randomGrabber', msg.channel, irc.network):
             if len(payload) > length and len(payload.split()) > words:
                 try:
                     last = int(self.db.select(channel, msg.nick))
                 except dbi.NoRecordError:
                     self._grab(channel, irc, msg, irc.prefix)
                     self._sendGrabMsg(irc, msg)
                 else:
                     elapsed = int(time.time()) - last
                     if (random.random() * elapsed) > (grabTime / 2):
                         self._grab(channel, irc, msg, irc.prefix)
                         self._sendGrabMsg(irc, msg)
 def __call__(self, irc, msg):
     self.__parent.__call__(irc, msg)
     irc = callbacks.SimpleProxy(irc, msg)
     newFeeds = {}
     for channel in irc.state.channels:
         feeds = self.registryValue('announce', channel)
         for name in feeds:
             commandName = callbacks.canonicalName(name)
             if self.isCommandMethod(commandName):
                 url = self.feedNames[commandName][0]
             else:
                 url = name
             if self.willGetNewFeed(url):
                 newFeeds.setdefault((url, name), []).append(channel)
     for ((url, name), channels) in newFeeds.iteritems():
         # We check if we can acquire the lock right here because if we
         # don't, we'll possibly end up spawning a lot of threads to get
         # the feed, because this thread may run for a number of bytecodes
         # before it switches to a thread that'll get the lock in
         # _newHeadlines.
         if self.acquireLock(url, blocking=False):
             try:
                 t = threading.Thread(target=self._newHeadlines,
                                      name=format('Fetching %u', url),
                                      args=(irc, channels, name, url))
                 self.log.info('Checking for announcements at %u', url)
                 world.threadsSpawned += 1
                 t.setDaemon(True)
                 t.start()
             finally:
                 self.releaseLock(url)
                 time.sleep(0.1)  # So other threads can run.
Exemple #4
0
    def testHashing(self):
        irc = getTestIrc()
        msg = ircmsgs.ping('0')
        irc._tagMsg(msg)
        irc = irclib.Irc('test')
        proxy = callbacks.SimpleProxy(irc, msg)
        # First one way...
        self.assertFalse(proxy != irc)
        self.assertTrue(proxy == irc)
        self.assertEqual(hash(proxy), hash(irc))
        # Then the other!
        self.assertFalse(irc != proxy)
        self.assertTrue(irc == proxy)
        self.assertEqual(hash(irc), hash(proxy))

        # And now dictionaries...
        d = {}
        d[irc] = 'foo'
        self.assertTrue(len(d) == 1)
        self.assertTrue(d[irc] == 'foo')
        self.assertTrue(d[proxy] == 'foo')
        d[proxy] = 'bar'
        self.assertTrue(len(d) == 1)
        self.assertTrue(d[irc] == 'bar')
        self.assertTrue(d[proxy] == 'bar')
        d[irc] = 'foo'
        self.assertTrue(len(d) == 1)
        self.assertTrue(d[irc] == 'foo')
        self.assertTrue(d[proxy] == 'foo')
Exemple #5
0
 def _notify(self, irc, msg, repeatedly=False):
     irc = callbacks.SimpleProxy(irc, msg)
     try:
         to = ircdb.users.getUserId(msg.prefix)
     except KeyError:
         return
     ids = self.db.getUnnotifiedIds(to)
     if len(ids) <= self.registryValue('notify.autoSend'):
         for id in ids:
             irc.reply(self._formatNote(self.db.get(id), to), private=True)
             self.db.setRead(id)
         return
     unnotifiedIds = ['#%s' % nid for nid in ids]
     unnotified = len(unnotifiedIds)
     if unnotified or repeatedly:
         unreadIds = ['#%s' % nid for nid in self.db.getUnreadIds(to)]
         unread = len(unreadIds)
         s = format('You have %n; %i that I haven\'t told you about '
                    'before now.  %L %b still unread.',
                    (unread, 'unread', 'note'), unnotified,
                    unreadIds, unread)
         # Later we'll have a user value for allowing this to be a NOTICE.
         irc.reply(s, private=True)
         for nid in unnotifiedIds:
             id = int(nid[1:])
             self.db.setNotified(id)
Exemple #6
0
    def testHashing(self):
        msg = ircmsgs.ping('0')
        irc = irclib.Irc('test')
        proxy = callbacks.SimpleProxy(irc, msg)
        # First one way...
        self.failIf(proxy != irc)
        self.failUnless(proxy == irc)
        self.assertEqual(hash(proxy), hash(irc))
        # Then the other!
        self.failIf(irc != proxy)
        self.failUnless(irc == proxy)
        self.assertEqual(hash(irc), hash(proxy))

        # And now dictionaries...
        d = {}
        d[irc] = 'foo'
        self.failUnless(len(d) == 1)
        self.failUnless(d[irc] == 'foo')
        self.failUnless(d[proxy] == 'foo')
        d[proxy] = 'bar'
        self.failUnless(len(d) == 1)
        self.failUnless(d[irc] == 'bar')
        self.failUnless(d[proxy] == 'bar')
        d[irc] = 'foo'
        self.failUnless(len(d) == 1)
        self.failUnless(d[irc] == 'foo')
        self.failUnless(d[proxy] == 'foo')
 def doPrivmsg(self, irc, msg):
     if (irc.isChannel(msg.args[0])):
         channel = plugins.getChannel(msg.args[0])
         canSpeak = False
         now = time.time()
         throttle = self.registryValue('randomSpeaking.throttleTime',
                                       channel)
         prob = self.registryValue('randomSpeaking.probability', channel)
         delay = self.registryValue('randomSpeaking.maxDelay', channel)
         irc = callbacks.SimpleProxy(irc, msg)
         if now > self.lastSpoke + throttle:
             canSpeak = True
         if canSpeak and random.random() < prob:
             #f = self._markov(channel, irc, prefixNick=False, to=channel, Random=True)
             reply = self.db.buildReply(channel, None)
             if (reply is None):
                 return
             irc.reply(reply, prefixNick=False, to=channel)
             #self._markov(channel, irc, prefixNick=False, to=channel, Random=True)
             #schedule.addEvent(lambda: self.q.enqueue(f), now+delay)
             self.lastSpoke = now + delay
         words = self.tokenize(msg)
         if not words or len(words) == 3:
             return
         if (self.registryValue('ignoreBotCommands', channel)
                 and callbacks.addressed(irc.nick, msg)):
             return
         self.db.addPair(channel, None, words[0])
         self.db.addPair(channel, words[-1], None)
         for (first, second) in utils.seq.window(words, 2):
             self.db.addPair(channel, first, second)
Exemple #8
0
 def doPrivmsg(self, irc, msg):
     print "InternalKarma:doPrivmsg: %s" % msg
     irc = callbacks.SimpleProxy(irc, msg)
     thing = msg.args[1].rstrip()
     if thing[-2:] in ('++', '--'):
         irc.reply(
             "hey, karma is appreciated but we track that over in #katello on Freenode",
             prefixNick=True)
Exemple #9
0
 def __call__(self, irc, msg):
     super(Twitter, self).__call__(irc, msg)
     irc = callbacks.SimpleProxy(irc, msg)
     for channel in irc.state.channels:
         if self.registryValue('announce.interval', channel) != 0 and \
                 channel not in self._runningAnnounces:
             threading.Thread(target=self._fetchTimeline,
                              args=(irc, channel)).start()
Exemple #10
0
 def assertState(self, spec, given, expected, target='test', **kwargs):
     msg = ircmsgs.privmsg(target, 'foo')
     realIrc = getTestIrc()
     realIrc.nick = 'test'
     realIrc.state.supported['chantypes'] = '#'
     irc = callbacks.SimpleProxy(realIrc, msg)
     myspec = Spec(spec, **kwargs)
     state = myspec(irc, msg, given)
     self.assertEqual(state.args, expected,
                      'Expected %r, got %r' % (expected, state.args))
Exemple #11
0
 def __call__(self, irc, msg):
     self.__parent.__call__(irc, msg)
     now = time.time()
     wait = self.registryValue('waitPeriod')
     if now - self.last_request > wait:
         self.last_request = now
         irc = callbacks.SimpleProxy(irc, msg)
         responses = self._get_mentions(maxAge=7200)
         if len(responses) > 0:
             irc.reply(' ; '.join(responses),
                       to='#code4lib',
                       prefixNick=False)
Exemple #12
0
 def doPrivmsg(self, irc, msg):
     # We don't handle this if we've been addressed because invalidCommand
     # will handle it for us.  This prevents us from accessing the db twice
     # and therefore crashing.
     if not (msg.addressed or msg.repliedTo):
         channel = msg.args[0]
         if irc.isChannel(channel) and \
            not ircmsgs.isCtcp(msg) and \
            self.registryValue('allowUnaddressedKarma', channel):
             irc = callbacks.SimpleProxy(irc, msg)
             thing = msg.args[1].rstrip()
             self._doKarma(irc, msg, channel, thing)
Exemple #13
0
 def __call__(self, irc, msg):
     self.__parent.__call__(irc, msg)
     now = int(time.time())
     wait = self.registryValue('waitPeriod')
     if now - self.last_request > wait:
         logger.info("looking for new questions since %s" % now)
         irc = callbacks.SimpleProxy(irc, msg)
         questions = get_questions(self.last_request)
         self.last_request = now
         if len(questions) > 0:
             n = ["%s - %s" % (q['title'], q['url']) for q in questions]
             logger.info("found questions: %s" % n)
             irc.reply('[library stackexchange] ' + ' ; '.join(n),
                       to='#code4lib',
                       prefixNick=False)
Exemple #14
0
    def doJoin(self, irc, msg):
        if ircutils.strEqual(irc.nick, msg.nick):
            return  # It's us.
        if msg.nick in self.splitters:
            self.log.debug('Not heralding %s, recent split.', msg.nick)
            return  # Recently split.
        channel = msg.args[0]
        irc = callbacks.SimpleProxy(irc, msg)
        if self.registryValue('heralding', channel):
            try:
                id = ircdb.users.getUserId(msg.prefix)
                heraldAll = self.db['#ALL', id]
            except KeyError:
                heraldAll = ""

            try:
                id = ircdb.users.getUserId(msg.prefix)
                if id in self.splitters:
                    self.log.debug('Not heralding id #%s, recent split.', id)
                    return
                herald = self.db[channel, id]
            except KeyError:
                if heraldAll == "":
                    default = self.registryValue('default', channel)
                    if default:
                        default = ircutils.standardSubstitute(
                            irc, msg, default)
                        msgmaker = ircmsgs.privmsg
                        if self.registryValue('default.notice', channel):
                            msgmaker = ircmsgs.notice
                        target = msg.nick
                        if self.registryValue('default.public', channel):
                            target = channel
                        irc.queueMsg(msgmaker(target, default))
                    return
                else:
                    herald = heraldAll

            now = time.time()
            throttle = self.registryValue('throttle', channel)
            if now - self.lastHerald.get((channel, id), 0) > throttle:
                if (channel, id) in self.lastParts:
                    i = self.registryValue('throttle.afterPart', channel)
                    if now - self.lastParts[channel, id] < i:
                        return
                self.lastHerald[channel, id] = now
                herald = ircutils.standardSubstitute(irc, msg, herald)
                irc.reply(herald, prefixNick=False)
Exemple #15
0
 def doPrivmsg(self, irc, msg):
     # We don't handle this if we've been addressed because invalidCommand
     # will handle it for us.  This prevents us from accessing the db twice
     # and therefore crashing.
     if not (msg.addressed or msg.repliedTo):
         channel = msg.args[0]
         if irc.isChannel(channel) and \
            self.registryValue('allowUnaddressedKarma', channel):
             irc = callbacks.SimpleProxy(irc, msg)
             #                thing = msg.args[1].rstrip()
             #                if thing[-2:] in ('++', '--'):
             #                    self._doKarma(irc, channel, thing)
             # same here as above in invalidCommand
             #for token in msg.args[1].split():
             for token in smart_split(msg.args[1]):
                 self._doKarma(irc, channel, token)
Exemple #16
0
 def doPrivmsg(self, irc, msg):
     notes = self._notes.pop(msg.nick, [])
     # Let's try wildcards.
     removals = []
     for wildcard in self.wildcards:
         if ircutils.hostmaskPatternEqual(wildcard, msg.nick):
             removals.append(wildcard)
             notes.extend(self._notes.pop(wildcard))
         for removal in removals:
             self.wildcards.remove(removal)
     if notes:
         irc = callbacks.SimpleProxy(irc, msg)
         private = self.registryValue('private')
         for (when, whence, note) in notes:
             s = self._formatNote(when, whence, note)
             irc.reply(s, private=private)
         self._flushNotes()
Exemple #17
0
 def doPrivmsg(self, irc, msg):
     if ircmsgs.isCtcp(msg) and not ircmsgs.isAction(msg):
         return
     notes = self._notes.pop(msg.nick, [])
     # Let's try wildcards.
     removals = []
     for wildcard in self.wildcards:
         if ircutils.hostmaskPatternEqual(wildcard, msg.prefix):
             removals.append(wildcard)
             notes.extend(self._notes.pop(wildcard))
         for removal in removals:
             self.wildcards.remove(removal)
     if notes:
         old_repliedto = msg.repliedTo
         irc = callbacks.SimpleProxy(irc, msg)
         private = self.registryValue('private')
         for (when, whence, note) in notes:
             s = self._formatNote(when, whence, note)
             irc.reply(s, private=private, prefixNick=not private)
         self._flushNotes()
         msg.tag('repliedTo', old_repliedto)
Exemple #18
0
    def doJoin(self, irc, msg):
        channel = msg.args[0]

        if not self.registryValue('enable', channel):
            return

        delay = self.registryValue('delay', channel)

        if not ircutils.strEqual(msg.nick, irc.nick):
            irc = callbacks.SimpleProxy(irc, msg)

            def voice():
                if msg.nick not in irc.state.channels[channel].users:
                    self.log.warn('%s is no longer in %s, cannot voice'
                                  % (msg.nick, channel))
                    return

                self.log.info('Removing muzzle from %s in %s'
                              % (msg.nick, channel))
                irc.queueMsg(ircmsgs.voice(channel, msg.nick))

            schedule.addEvent(voice, time() + delay)
Exemple #19
0
 def doPrivmsg(self, irc, msg):
     irc = callbacks.SimpleProxy(irc, msg)
     if irc.isChannel(msg.args[0]):
         (channel, payload) = msg.args
         words = self.registryValue('randomGrabber.minimumWords', channel)
         length = self.registryValue('randomGrabber.minimumCharacters',
                                     channel)
         grabTime = \
         self.registryValue('randomGrabber.averageTimeBetweenGrabs',
                            channel)
         if self.registryValue('randomGrabber', channel):
             if len(payload) > length and len(payload.split()) > words:
                 try:
                     last = int(self.db.select(channel, msg.nick))
                 except dbi.NoRecordError:
                     self._grab(irc, msg, irc.prefix)
                     self._sendGrabMsg(irc, msg)
                 else:
                     elapsed = int(time.time()) - last
                     if random.random() * elapsed > grabTime / 2:
                         self._grab(irc, msg, irc.prefix)
                         self._sendGrabMsg(irc, msg)
Exemple #20
0
    def doPrivmsg(self, irc, msg):
        if irc.isChannel(msg.args[0]):
            channel = plugins.getChannel(msg.args[0])
            canSpeak = False
            now = time.time()
            throttle = self.registryValue('randomSpeaking.throttleTime',
                                          channel)
            prob = self.registryValue('randomSpeaking.probability', channel)
            delay = self.registryValue('randomSpeaking.maxDelay', channel)
            irc = callbacks.SimpleProxy(irc, msg)
            if now > self.lastSpoke + throttle:
                canSpeak = True
            if canSpeak and random.random() < prob:
                f = self._markov(channel,
                                 irc,
                                 prefixNick=False,
                                 to=channel,
                                 Random=True)
                schedule.addEvent(lambda: self.q.enqueue(f), now + delay)
                self.lastSpoke = now + delay
            words = self.tokenize(msg)
            words.insert(0, '\n')
            words.insert(0, '\n')
            words.append('\n')
            # This shouldn't happen often (CTCP messages being the possible exception)
            if not words or len(words) == 3:
                return
            if self.registryValue('ignoreBotCommands', channel) and \
                    callbacks.addressed(irc.nick, msg):
                return

            def doPrivmsg(db):
                for (first, second, follower) in utils.seq.window(words, 3):
                    db.addPair(channel, first, second, follower)

            self.q.enqueue(doPrivmsg)
Exemple #21
0
 def doJoin(self, irc, msg):
     if not ircutils.strEqual(msg.nick, irc.nick):
         irc = callbacks.SimpleProxy(irc, msg)
         self._enforceLimit(irc, msg.args[0])
Exemple #22
0
 def __call__(self, irc, msg):
     irc = callbacks.SimpleProxy(irc, msg)
     self.lastIrc = irc
     self.lastMsg = msg
Exemple #23
0
 def __call__(self, irc, msg):
     self.__parent.__call__(irc, msg)
     irc = callbacks.SimpleProxy(irc, msg)