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)
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.
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')
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)
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)
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)
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()
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))
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)
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)
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)
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)
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)
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()
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)
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)
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)
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)
def doJoin(self, irc, msg): if not ircutils.strEqual(msg.nick, irc.nick): irc = callbacks.SimpleProxy(irc, msg) self._enforceLimit(irc, msg.args[0])
def __call__(self, irc, msg): irc = callbacks.SimpleProxy(irc, msg) self.lastIrc = irc self.lastMsg = msg
def __call__(self, irc, msg): self.__parent.__call__(irc, msg) irc = callbacks.SimpleProxy(irc, msg)