def invalidCommand(self,irc,msg,tokens): try: self.log.debug('Channel is: "+str(irc.isChannel(msg.args[0]))') self.log.debug("Message is: "+str(msg.args)) except: self.log.error("message not retrievable.") if irc.isChannel(msg.args[0]) and self.registryValue('react',msg.args[0]): channel = msg.args[0] self.log.debug("Fetching response...") reply = self.getResponse(irc,msg,ircutils.stripFormatting(msg.args[1]).strip()) self.log.debug("Got response!") if reply is not None: self.log.debug("Reply is: "+str(reply)) if self.registryValue('enable', channel): irc.reply(reply) else: irc.reply("My AI is down, sorry! :( I couldn't process what you said... blame it on a brain fart. :P") elif (msg.args[0] == irc.nick) and self.registryValue('reactprivate',msg.args[0]): err = "" self.log.debug("Fetching response...") reply = self.getResponse(irc,msg,ircutils.stripFormatting(msg.args[1]).strip()) self.log.debug("Got response!") if reply is not None: self.log.debug("Reply is: "+str(reply)) if self.registryValue('enable', channel): irc.reply(reply) else: irc.reply("My AI is down, sorry! :( I couldn't process what you said... blame it on a brain fart. :P", err, None, True, None, None)
def testStripFormatting(self): self.assertEqual(ircutils.stripFormatting(ircutils.bold('foo')), 'foo') self.assertEqual(ircutils.stripFormatting(ircutils.reverse('foo')), 'foo') self.assertEqual(ircutils.stripFormatting(ircutils.underline('foo')), 'foo') self.assertEqual( ircutils.stripFormatting('\x02bold\x0302,04foo\x03' 'bar\x0f'), 'boldfoobar') s = ircutils.mircColor('[', 'blue') + ircutils.bold('09:21') self.assertEqual(ircutils.stripFormatting(s), '[09:21')
def testStripFormatting(self): self.assertEqual(ircutils.stripFormatting(ircutils.bold('foo')), 'foo') self.assertEqual(ircutils.stripFormatting(ircutils.reverse('foo')), 'foo') self.assertEqual(ircutils.stripFormatting(ircutils.underline('foo')), 'foo') self.assertEqual(ircutils.stripFormatting('\x02bold\x0302,04foo\x03' 'bar\x0f'), 'boldfoobar') s = ircutils.mircColor('[', 'blue') + ircutils.bold('09:21') self.assertEqual(ircutils.stripFormatting(s), '[09:21')
def doNickservNotice(self, irc, msg): nick = self._getNick() s = ircutils.stripFormatting(msg.args[1].lower()) on = 'on %s' % irc.network networkGroup = conf.supybot.networks.get(irc.network) if 'incorrect' in s or 'denied' in s: log = 'Received "Password Incorrect" from NickServ %s. ' \ 'Resetting password to empty.' % on self.log.warning(log) self.sentGhost = time.time() self._setNickServPassword(nick, '') elif self._ghosted(s): self.log.info('Received "GHOST succeeded" from NickServ %s.', on) self.sentGhost = None self.identified = False irc.queueMsg(ircmsgs.nick(nick)) elif 'is not registered' in s: self.log.info('Received "Nick not registered" from NickServ %s.', on) elif 'currently' in s and 'isn\'t' in s or 'is not' in s: # The nick isn't online, let's change our nick to it. self.sentGhost = None irc.queueMsg(ircmsgs.nick(nick)) elif ('owned by someone else' in s) or \ ('nickname is registered and protected' in s) or \ ('nick belongs to another user' in s): # freenode, arstechnica, chatjunkies # oftc, zirc.org # sorcery self.log.info('Received "Registered nick" from NickServ %s.', on) elif '/msg' in s and 'id' in s and 'password' in s: # Usage info for identify command; ignore. self.log.debug('Got usage info for identify command %s.', on) elif ('please choose a different nick' in s): # oftc, part 3 # This is a catch-all for redundant messages from nickserv. pass elif ('now recognized' in s) or \ ('already identified' in s) or \ ('password accepted' in s) or \ ('now identified' in s): # freenode, oftc, arstechnica, zirc, .... # sorcery self.log.info('Received "Password accepted" from NickServ %s.', on) self.identified = True for channel in irc.state.channels.keys(): self.checkPrivileges(irc, channel) for channel in self.channels: irc.queueMsg(networkGroup.channels.join(channel)) if self.waitingJoins: for m in self.waitingJoins: irc.sendMsg(m) self.waitingJoins = [] elif 'not yet authenticated' in s: # zirc.org has this, it requires an auth code. email = s.split()[-1] self.log.warning('Received "Nick not yet authenticated" from ' 'NickServ %s. Check email at %s and send the ' 'auth command to NickServ.', on, email) else: self.log.debug('Unexpected notice from NickServ %s: %q.', on, s)
def worldtime(self, irc, msg, args, opts, location): """[--nick <nick] [<location>] Query GAPIs for <location> and attempt to figure out local time. [<location>] is only required if you have not yet set a location for yourself using the 'set' command. If --nick is given, try looking up the location for <nick>. """ opts = dict(opts) if not location: try: if "nick" in opts: host = irc.state.nickToHostmask(opts["nick"]) else: host = msg.prefix ih = host.split("!")[1] location = self.db[ih] except KeyError: irc.error( "No location for %s is set. Use the 'set' command " "to set a location for your current hostmask, or call 'worldtime' " "with <location> as an argument." % ircutils.bold("*!" + ih), Raise=True, ) # first, grab lat and long for user location gc = self._getlatlng(location) if not gc: irc.error( "I could not find the location for: {0}. Bad location? " "Spelled wrong?".format(location), Raise=True, ) # next, lets grab the localtime for that location w/lat+long. ll = self._gettime(gc["ll"]) if not ll: irc.error( "I could not find the local timezone for: {0}. Bad location? " "Spelled wrong?".format(location), Raise=True, ) # if we're here, we have localtime zone. lt = self._converttz(msg, ll["timeZoneId"]) if lt: # make sure we get it back. if sys.version_info[0] <= 2: s = "{0} :: Current local time is: {1} ({2})".format( ircutils.bold(gc["place"].encode("utf-8")), lt, ll["timeZoneName"].encode("utf-8"), ) else: s = "{0} :: Current local time is: {1} ({2})".format( ircutils.bold(gc["place"]), lt, ll["timeZoneName"]) if self.registryValue("disableANSI", msg.args[0]): s = ircutils.stripFormatting(s) irc.reply(s) else: irc.error( "Something went wrong during conversion to timezone. Check the logs.", Raise=True, )
def answer(self, msg): correct = False for ans in self.a: dist = self.DL( ircutils.stripFormatting(str.lower(msg.args[1])), str.lower(ans)) flexibility = self.registryValue('flexibility', self.channel) if dist <= len(ans) / flexibility: correct = True #if self.registryValue('debug'): # self.reply('Distance: %d' % dist) if correct: if not msg.nick in self.scores: self.scores[msg.nick] = 0 self.scores[msg.nick] += 1 if not msg.nick in self.roundscores: self.roundscores[msg.nick] = 0 self.roundscores[msg.nick] += 1 self.unanswered = 0 self.reply( _('%s got it! The full answer was: %s. Points: %d') % (msg.nick, self.a[0], self.scores[msg.nick])) schedule.removeEvent('next_%s' % self.channel) self.writeScores() self.newquestion()
def combine(msgs, reverse=True, stamps=False, nicks=True, compact=True, joiner=r' \ ', nocolor=False): """ Formats and returns a list of IrcMsg objects (<msgs>) as a string. <reverse>, if True, prints messages from last to first. <stamps>, if True, appends timestamps to messages. <reverse>, if True, orders messages by earliest to most recent. <compact>, if False, append nicks to consecutive messages <joiner>, the character joining lines together (default: ' \ '). <nocolor>, if True, strips color from messages. Sample output: <bigman> DUNK \ <bigbitch> \ bluh \ bluh """ output = [] lastnick = '' for msg in reversed(msgs) if reverse else msgs: isaction = ircmsgs.isAction(msg) if isaction: text = '[%s %s]' % (msg.nick, ircmsgs.unAction(msg)) else: if compact and ircutils.nickEqual(msg.nick, lastnick) or not nicks: text = msg.args[1] else: lastnick = msg.nick text = '<%s> %s' % (msg.nick, msg.args[1]) if stamps: stampfmt = '%d-%m-%y %H:%M:%S' stamp = time.strftime(stampfmt, time.localtime(msg.receivedAt)) text = '[{0}] {1}'.format(stamp, text) output.append(ircutils.stripFormatting(text)) return joiner.join(output)
def tp(self, irc, msg, args, text): """tp <text> Translates <text> through multiple rounds of Google Translate to get amusing results. """ outlang = self.registryValue('language', msg.args[0]) if outlang not in self.langs: irc.error("Unrecognized output language. Please set " "'config plugins.wte.language' correctly.", Raise=True) # Randomly choose 4 to 8 languages from the list of supported languages. # The amount can be adjusted if you really wish - 4 to 8 is reasonable # in that it gives interesting results but doesn't spam Google's API # (and risk getting blocked) too much. ll = random.sample(self.langs.keys(), random.randint(4,8)) self.log.debug(format("TranslateParty: Using %i languages: %L " "(outlang %s)", len(ll), ll, outlang)) # For every language in this list, translate the text given from # auto-detect into the target language, and replace the original text # with it. for targetlang in ll: text = self.getTranslation(irc, "auto", targetlang, text) text = self.getTranslation(irc, "auto", outlang, text) text = ircutils.stripFormatting(text) text = text.strip() if self.registryValue("verbose", msg.args[0]): # Verbose output was requested, show the language codes AND # names that we translated through. languages = [ircutils.bold("%s [%s]" % (self.langs[lang], lang)) for lang in ll] irc.reply(format("Translated through \x02%i\x02 languages: %L " "(output language %s)", len(ll), languages, outlang)) irc.reply(text)
def msgtotext(msg): """ Returns only the message text from an IrcMsg (<msg>). """ isaction = ircmsgs.isAction(msg) text = ircmsgs.unAction(msg) if isaction else msg.args[1] return ircutils.stripFormatting(text), isaction
def soccerformation(self, irc, msg, args): """ Display a random lineup for channel users. """ if not ircutils.isChannel(msg.args[0]): # make sure its run in a channel. irc.reply("ERROR: Must be run from a channel.") return # now make sure we have more than 9 users. users = [i for i in irc.state.channels[msg.args[0]].users] if len(users) < 11: # need >9 users. irc.reply("Sorry, I can only run this in a channel with more than 9 users.") return # now that we're good.. formations = {'4-4-2':['(GK)', '(RB)', '(CB)', '(CB)', '(LB)', '(RM)', '(LM)', '(CM)', '(CM)', '(FW)', '(FW)'], '4-4-1-1':['(GK)', '(RB)', '(CB)', '(CB)', '(LB)', '(RM)', '(LM)', '(CM)', '(CM)', '(ST)', '(FW)'], '4-5-1':['(GK)', '(RB)', '(CB)', '(CB)', '(LB)', '(RM)', '(LM)', '(CM)', '(CM)', '(CM)', '(ST)'], '3-5-1-1':['(GK)', '(CB)', '(CB)', '(SW)', '(RM)', '(CM)', '(LM)', '(CM)', '(CM)', '(FW)', '(ST)'], '10-1 (CHELSEA)':['(GK)', '(LB)', '(CB)', '(RB)', '(CB)', '(CB)', '(CB)', '(CB)', '(CB)', '(CB)', '(DROGBA)'], '8-1-1 (PARK THE BUS)':['(GK)', '(LB)', '(CB)', '(RB)', '(CB)', '(CB)', '(CB)', '(CB)', '(CB)', '(CM)', '(ST)'] } formation = random.choice(formations.keys()) random.shuffle(formations[formation]) # shuffle. lineup = [] # list for output. for position in formations[formation]: # iterate through and highlight. a = random.choice(users) # pick a random user. users.remove(a) # remove so its unique. append below. lineup.append("{0}{1}".format(ircutils.bold(a), position)) # now output. output = "{0} ALL-STAR LINEUP ({1}) :: {2}".format(ircutils.mircColor(msg.args[0], 'red'), formation, ", ".join(lineup)) if not self.registryValue('disableANSI', msg.args[0]): # display color or not? irc.reply(output) else: irc.reply(ircutils.stripFormatting(output))
def doLog(self, irc, channel, notice, nick, s, *args): ''' notice: Boolean. True if message should be styled as a notice. ''' if not self.registryValue('enable', channel): return s = format(s, *args) channel = self.normalizeChannel(irc, channel) log = self.getLog(irc, channel) row_classes = row_class if notice: row_classes = row_class + " " + notice_class log.write('<p class="%s">' % row_classes) if self.registryValue('timestamp', channel): log.write('<span class="%s">' % timestamp_class) self.timestamp(log) log.write('</span>') if nick != None: log.write('<span class="%s">' % nick_class) log.write(html_escape("<%s> " %nick)) log.write('</span>') if self.registryValue('stripFormatting', channel): s = ircutils.stripFormatting(s) log.write('<span class="%s">' % message_class) log.write(self.linkify(html_escape(s))) log.write('</span>') log.write('</p>\n') if self.registryValue('flushImmediately'): log.flush()
def inFilter(self, irc, msg): self.filtering = True # We need to check for bad words here rather than in doPrivmsg because # messages don't get to doPrivmsg if the user is ignored. if msg.command == 'PRIVMSG': channel = msg.args[0] self.updateRegexp(channel) s = ircutils.stripFormatting(msg.args[1]) if ircutils.isChannel(channel) and self.registryValue('kick', channel): if self.words and self.regexp.search(s): c = irc.state.channels[channel] cap = ircdb.makeChannelCapability(channel, 'op') if c.isHalfopPlus(irc.nick): if c.isHalfopPlus(msg.nick) or \ ircdb.checkCapability(msg.prefix, cap): self.log.debug("Not kicking %s from %s, because " "they are halfop+ or can't be " "kicked.", msg.nick, channel) else: message = self.registryValue('kick.message', channel) irc.queueMsg(ircmsgs.kick(channel, msg.nick, message)) else: self.log.warning('Should kick %s from %s, but not opped.', msg.nick, channel) return msg
def tp(self, irc, msg, args, text): """tp <text> Translates <text> through multiple rounds of Google Translate to get amusing results. """ outlang = self.registryValue('language', msg.args[0]) if outlang not in self.langs: irc.error("Unrecognized output language. Please set " "'config plugins.wte.language' correctly.", Raise=True) # Randomly choose 4 to 8 languages from the list of supported languages. # The amount can be adjusted if you really wish - 4 to 8 is reasonable # in that it gives interesting results but doesn't spam Google's API # (and risk getting blocked) too much. ll = random.sample(self.langs.keys(), random.randint(4,8)) self.log.debug(format("TranslateParty: Using %i languages: %L " "(outlang %s)", len(ll), ll, outlang)) text = ircutils.stripFormatting(text) # For every language in this list, translate the text given from # auto-detect into the target language, and replace the original text # with it. for targetlang in ll: text = self.getTranslation(irc, "auto", targetlang, text) text = self.getTranslation(irc, "auto", outlang, text) text = text.strip() if self.registryValue("verbose", msg.args[0]): # Verbose output was requested, show the language codes AND # names that we translated through. languages = [ircutils.bold("%s [%s]" % (self.langs[lang], lang)) for lang in ll] irc.reply(format("Translated through \x02%i\x02 languages: %L " "(output language %s)", len(ll), languages, outlang)) irc.reply(text)
def inFilter(self, irc, msg): self.filtering = True # We need to check for bad words here rather than in doPrivmsg because # messages don't get to doPrivmsg if the user is ignored. if msg.command == 'PRIVMSG' and self.words(): channel = msg.args[0] self.updateRegexp(channel) s = ircutils.stripFormatting(msg.args[1]) if irc.isChannel(channel) and self.registryValue('kick', channel): if self.regexp.search(s): c = irc.state.channels[channel] cap = ircdb.makeChannelCapability(channel, 'op') if c.isHalfopPlus(irc.nick): if c.isHalfopPlus(msg.nick) or \ ircdb.checkCapability(msg.prefix, cap): self.log.debug( "Not kicking %s from %s, because " "they are halfop+ or can't be " "kicked.", msg.nick, channel) else: message = self.registryValue( 'kick.message', channel) irc.queueMsg( ircmsgs.kick(channel, msg.nick, message)) else: self.log.warning( 'Should kick %s from %s, but not opped.', msg.nick, channel) return msg
def inFilter(self, irc, msg): if ircutils.isChannel(msg.args[0]): if self.registryValue('enabled', msg.args[0]) and \ len(msg.args) > 1: s = ircutils.stripFormatting(msg.args[1]) msg = ircmsgs.privmsg(msg.args[0], s, msg=msg) return msg return msg
def doPrivmsg(self, irc, msg): if ircmsgs.isCtcp(msg) and not ircmsgs.isAction(msg): return if ircutils.isChannel(msg.args[0]) and self._is_voting_enabled(irc, msg): channel = msg.args[0] message = ircutils.stripFormatting(msg.args[1]) match = self.regexp.match(message) if match and match.group(1) in irc.state.channels[channel].users: self._gegen(irc, msg, match.group(1))
def _cleantext(self, text): """Clean-up text for input into corpus.""" text = self._decode_irc(text) text = ircutils.stripFormatting(text) text = text.strip() text = re.sub("[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890@.!?;:/%\$§\-_ ]", " ", text) text = utils.str.normalizeWhitespace(text) return text
def doBounce(self, irc, s, channel, **kw): channel = self.normalizeChannel(irc, channel) s = ircutils.stripFormatting(s) for t in self.targets: if ircutils.isChannel(channel): inreply = channel else: inreply = kw['nick'] t.sendReply(s.strip(), source='bnc', inreply=inreply, **kw)
def doLog(self, irc, channel, s): if not self.registryValue('enabled', channel): return channel = ircutils.toLower(channel) if channel not in self.logs.keys(): self.logs[channel] = [] format = conf.supybot.log.timestampFormat() if format: s = time.strftime(format, time.gmtime()) + " " + ircutils.stripFormatting(s) self.logs[channel] = self.logs[channel][-199:] + [s.strip()]
def _addRelayMsg(self, msg): channel = msg.args[0] if channel in self.lastRelayMsgs: q = self.lastRelayMsgs[channel] else: q = TimeoutQueue(60) # XXX Make this configurable. self.lastRelayMsgs[channel] = q unformatted = ircutils.stripFormatting(msg.args[1]) normalized = utils.str.normalizeWhitespace(unformatted) q.enqueue(normalized)
def outFilter(self, irc, msg): if self.filtering and msg.command == 'PRIVMSG': self.updateRegexp() s = msg.args[1] if self.registryValue('stripFormatting'): s = ircutils.stripFormatting(s) t = self.regexp.sub(self.sub, s) if t != s: msg = ircmsgs.privmsg(msg.args[0], t, msg=msg) return msg
def _checkRelayMsg(self, msg): channel = msg.args[0] if channel in self.lastRelayMsgs: q = self.lastRelayMsgs[channel] unformatted = ircutils.stripFormatting(msg.args[1]) normalized = utils.str.normalizeWhitespace(unformatted) for s in q: if s in normalized: return True return False
def outFilter(self, irc, msg): if self.filtering and msg.command == 'PRIVMSG': if self.lastModified < self.words.lastModified: self.makeRegexp(self.words()) self.lastModified = time.time() s = msg.args[1] if self.registryValue('stripFormatting'): s = ircutils.stripFormatting(s) s = self.regexp.sub(self.sub, s) msg = ircmsgs.privmsg(msg.args[0], s, msg=msg) return msg
def _ircToSkype(self, s): """Converts mIRC format chars to Skype HTML""" s = html.escape(s) s = re.sub("\x02(.*?)(\x02|\x0f|$)", lambda m: SkypeMsg.bold(m.group(1)), s) s = re.sub("\x1d(.*?)(\x1d|\x0f|$)", lambda m: SkypeMsg.italic(m.group(1)), s) # remove other formatting s = ircutils.stripFormatting(s) return s
def outFilter(self, irc, msg): if self.filtering and msg.command == 'PRIVMSG' \ and (self.words() or self.phrases()): channel = msg.channel self.updateRegexp(channel, irc.network) s = msg.args[1] if self.registryValue('stripFormatting'): s = ircutils.stripFormatting(s) t = self.regexp.sub(self.sub, s) if t != s: msg = ircmsgs.privmsg(msg.args[0], t, msg=msg) return msg
def _cleanText(self, text): """Internal method for cleaning text of imperfections.""" text = ircutils.stripFormatting( text) # Strip IRC formatting from the string. text = text.strip( ) # Strip whitespace from beginning and the end of the string. if len(text) > 1: # So we don't get an error if the text is too small text = text[0].upper() + text[ 1:] # Capitalize first letter of the string. text = utils.str.normalizeWhitespace( text) # Normalize the whitespace in the string. return text
def doLog(self, s, *args): ## the actual logging that calls this function is inherited from the BaseLog text = format(s, *args) if self.getCurrentLogName() != self.CurrentLogName: self.LogFile.close() self.LogFile = open(self.getCurrentLogName(),'a') if self.config.registryValue('File.timestamp', self.channel): self.timestamp() if self.config.registryValue('stripFormatting', self.channel): text = ircutils.stripFormatting(text) self.LogFile.write(text) if self.config.registryValue('File.flushImmediately'): self.flush()
def paste(self, irc, msg, args, opts, text): """[--c=<comment>] <text> Pastes <text> to sprunge.us. --c adds a comment to the post. """ comment = None for o, a in opts: if o == 'c': comment = a header = stamp(irc.network, msg.args[0], msg.nick, time.localtime()) text = ircutils.stripFormatting(text).strip() self._paste(irc, msg.args[0], header, text, comment)
def doLog(self, irc, channel, s, *args): if not self.registryValue('enable', channel): return s = format(s, *args) channel = self.normalizeChannel(irc, channel) log = self.getLog(irc, channel) if self.registryValue('timestamp', channel): self.timestamp(log) if self.registryValue('stripFormatting', channel): s = ircutils.stripFormatting(s) log.write(s) if self.registryValue('flushImmediately'): log.flush()
def normalize(self, s, bot, nick): s = ircutils.stripFormatting(s) s = s.strip() # After stripFormatting for formatted spaces. s = utils.str.normalizeWhitespace(s) s = self._iAm[0].sub(self._iAm[1] % nick, s) s = self._my[0].sub(self._my[1] % nick, s) s = self._your[0].sub(self._your[1] % bot, s) contractions = [('what\'s', 'what is'), ('where\'s', 'where is'), ('who\'s', 'who is'), ('wtf\'s', 'wtf is'),] for (contraction, replacement) in contractions: if s.startswith(contraction): s = replacement + s[len(contraction):] return s
def invalidCommand(self, irc, msg, tokens): try: self.log.debug('Channel is: "+str(irc.isChannel(msg.args[0]))') self.log.debug("Message is: " + str(msg.args)) except: self.log.error("message not retrievable.") if irc.isChannel(msg.args[0]) and self.registryValue( 'react', msg.args[0]): channel = msg.args[0] self.log.debug("Fetching response...") reply = self.getResponse( irc, msg, ircutils.stripFormatting(msg.args[1]).strip()) self.log.debug("Got response!") if reply is not None: self.log.debug("Reply is: " + str(reply)) if self.registryValue('enable', channel): irc.reply(reply) else: irc.reply( "My AI is down, sorry! :( I couldn't process what you said... blame it on a brain fart. :P" ) elif (msg.args[0] == irc.nick) and self.registryValue( 'reactprivate', msg.args[0]): err = "" self.log.debug("Fetching response...") reply = self.getResponse( irc, msg, ircutils.stripFormatting(msg.args[1]).strip()) self.log.debug("Got response!") if reply is not None: self.log.debug("Reply is: " + str(reply)) if self.registryValue('enable', channel): irc.reply(reply) else: irc.reply( "My AI is down, sorry! :( I couldn't process what you said... blame it on a brain fart. :P", err, None, True, None, None)
def testStripFormatting(self): self.assertEqual(ircutils.stripFormatting(ircutils.bold("foo")), "foo") self.assertEqual(ircutils.stripFormatting(ircutils.italic("foo")), "foo") self.assertEqual(ircutils.stripFormatting(ircutils.reverse("foo")), "foo") self.assertEqual(ircutils.stripFormatting(ircutils.underline("foo")), "foo") self.assertEqual(ircutils.stripFormatting("\x02bold\x0302,04foo\x03" "bar\x0f"), "boldfoobar") s = ircutils.mircColor("[", "blue") + ircutils.bold("09:21") self.assertEqual(ircutils.stripFormatting(s), "[09:21")
def _cleanText(self, text): """Internal method for cleaning text of imperfections.""" text = self._decodeIRCMessage(text) # Decode the string. text = ircutils.stripFormatting(text) # Strip IRC formatting from the string. text = text.strip() # Strip whitespace from beginning and the end of the string. if len(text) > 1: # So we don't get an error if the text is too small text = text[0].upper() + text[1:] # Capitalize first letter of the string. text = utils.str.normalizeWhitespace(text) # Normalize the whitespace in the string. return text
def inFilter(self, irc, msg): self.filtering = True # We need to check for bad words here rather than in doPrivmsg because # messages don't get to doPrivmsg is the user is ignored. if msg.command == 'PRIVMSG': self.updateRegexp() s = ircutils.stripFormatting(msg.args[1]) channel = msg.args[0] if ircutils.isChannel(channel) and self.registryValue( 'kickban', channel): if self.regexp.search(s): if irc.nick in irc.state.channels[channel].ops: message = self.registryValue('kickban.message', channel) bannedHostmask = irc.state.nickToHostmask(msg.nick) banmaskstyle = conf.supybot.protocols.irc.banmask banmask = banmaskstyle.makeBanmask(bannedHostmask) irc.queueMsg(ircmsgs.ban(channel, banmask)) irc.queueMsg(ircmsgs.kick(channel, msg.nick, message)) expiry = self.registryValue('kickban.banexpire', channel) if expiry > 0: def f(): if channel in irc.state.channels and \ banmask in irc.state.channels[channel].bans: irc.queueMsg( ircmsgs.unban(channel, banmask)) schedule.addEvent(f, time.time() + expiry) else: self.log.warning( 'Should kickban %s from %s, but not opped.', msg.nick, channel) else: if ircutils.isChannel(channel) and self.registryValue( 'kick', channel): if self.regexp.search(s): if irc.nick in irc.state.channels[channel].ops: message = self.registryValue( 'kick.message', channel) irc.queueMsg( ircmsgs.kick(channel, msg.nick, message)) else: self.log.warning( 'Should kick %s from %s, but not opped.', msg.nick, channel) return msg
def cheat(self, irc, msg, args, num, action): """<number of votes> <action> Sets the number of votes for <action> to a certain amount, perfect for rigged elections! This will also reset the list of hosts that have voted for <action>, allowing everyone to vote again.""" if not self.registryValue("allowCheat"): irc.error("This command is disabled; please set config plugins." "voteserv.allowCheat accordingly.", Raise=True) action = ircutils.stripFormatting(action.lower()).strip() if not action: irc.error("You must specify a proper action!", Raise=True) self.votedb[action] = [num] irc.replySuccess()
def doLog(self, irc, channel, s, *args): if not self.registryValue('enable', channel, irc.network): return s = format(s, *args) channel = self.normalizeChannel(irc, channel) log = self.getLog(irc, channel) if self.registryValue('timestamp', channel, irc.network): self.timestamp(log) if self.registryValue('stripFormatting', channel, irc.network): s = ircutils.stripFormatting(s) if minisix.PY2: s = s.decode('utf8', 'ignore') log.write(s) if self.registryValue('flushImmediately'): log.flush()
def doChanservNotice(self, irc, msg): if self.disabled(irc): return s = msg.args[1].lower() channel = None m = self._chanRe.search(s) networkGroup = conf.supybot.networks.get(irc.network) on = 'on %s' % irc.network if m is not None: channel = m.group(1) if 'all bans' in s or 'unbanned from' in s or \ ('unbanned %s' % irc.nick.lower()) in \ ircutils.stripFormatting(s): # All bans removed (old freenode?) # You have been unbanned from (oftc, anope) # "Unbanned \x02someuser\x02 from \x02#channel\x02 (\x02N\x02 # ban(s) removed)" (atheme 7.x) irc.sendMsg(networkGroup.channels.join(channel)) elif 'isn\'t registered' in s: self.log.warning( 'Received "%s isn\'t registered" from ChanServ %s', channel, on) elif 'this channel has been registered' in s: self.log.debug('Got "Registered channel" from ChanServ %s.', on) elif 'already opped' in s: # This shouldn't happen, Services.op should refuse to run if # we already have ops. self.log.debug('Got "Already opped" from ChanServ %s.', on) elif 'access level' in s and 'is required' in s: self.log.warning('Got "Access level required" from ChanServ %s.', on) elif 'inviting' in s: self.log.debug('Got "Inviting to channel" from ChanServ %s.', on) elif s.startswith('['): chanTypes = irc.state.supported['CHANTYPES'] if re.match(r'^\[[%s]' % re.escape(chanTypes), s): self.log.debug('Got entrymsg from ChanServ %s.', on) elif irc.isChannel(msg.args[0]): # Atheme uses channel-wide notices for alerting channel access # changes if the FANTASY or VERBOSE setting is on; we can suppress # these 'unexpected notice' warnings since they're not really # important. pass else: self.log.warning('Got unexpected notice from ChanServ %s: %r.', on, msg)
def lart(self, irc, msg, args, channel, id, text): """[<channel>] [<id>] <who|what> [for <reason>] Uses the Luser Attitude Readjustment Tool on <who|what> (for <reason>, if given). If <id> is given, uses that specific lart. <channel> is only necessary if the message isn't sent in the channel itself. """ if not self.registryValue('enabled', msg.args[0]): return if ' for ' in text: (target, reason) = map(str.strip, text.split(' for ', 1)) else: (target, reason) = (text, '') if id is not None: try: lart = self.db.get(channel, id) except KeyError: irc.error(format('There is no lart with id #%i.', id)) return else: lart = self.db.random(channel) if not lart: irc.error(format('There are no larts in my database ' 'for %s.', channel)) return text = self._replaceFirstPerson(lart.text, msg.nick) formatText = ircutils.stripFormatting(target).lower() if (ircutils.strEqual(target, irc.nick) or 'Evilrockbot' in formatText) and random.uniform(0,100) < 25: target = msg.nick reason = '' elif 'stdin' in formatText or 'tsimpson' in formatText: target = msg.nick reason = '' else: target = self._replaceFirstPerson(target, msg.nick) reason = self._replaceFirstPerson(reason, msg.nick) if target.endswith('.'): target = target.rstrip('.') text = text.replace('$who', target) text = text.replace('$chan', msg.args[0]) if reason: text += ' for ' + reason if self.registryValue('showIds', channel): text += format(' (#%i)', lart.id) irc.reply(text, action=True)
def cheat(self, irc, msg, args, num, action): """<number of votes> <action> Sets the number of votes for <action> to a certain amount, perfect for rigged elections! This will also reset the list of hosts that have voted for <action>, allowing everyone to vote again.""" if not self.registryValue("allowCheat"): irc.error( "This command is disabled; please set config plugins." "voteserv.allowCheat accordingly.", Raise=True) action = ircutils.stripFormatting(action.lower()).strip() if not action: irc.error("You must specify a proper action!", Raise=True) self.votedb[action] = [num] irc.replySuccess()
def parseexpr(expr, nick=''): """ Parses an expression string (<expr>) and returns its parts. If a nick is not specified in the expression string, <nick> will be used. """ parts = [] expr = re.split(r'^(\S*?): *', ircutils.stripFormatting(expr.strip()), 1) if len(expr) != 1: nick = expr[1] for i, v in enumerate((nick, expr[-1])): orig = v if re.match(r'[sSmM]?[%s\t]' % DELIMS, v): isre = True v = fixexpr(v) o = v[0].isalpha() delim = v[o] v = v[o+1:].rsplit(delim, 2) #v = re.rsplit(delim, v[0+1:]) v += [''] * (3 - len(v)) else: isre = False delim = "\t" v = [v, '', ''] single = True offset = 0 for i, f in enumerate(v[-1]): if f in ('#', ' '): break elif f == 'g': single = False elif f == 'i': v[0] = r'(?i)%s' % v[0] elif f == 'w': v[0] = r'\b%s\b' % v[0] elif f == 'd': v[0] = r'%s.*' % v[0] elif f == 'o': try: offset = int(re.sub(r'\D*$', '', v[-1][i+1:])) except ValueError: pass items = zip(EXPRKEYS, v + [isre, delim, single, offset, orig]) parts.append({key: value for key, value in items}) return parts[0], parts[1]
def normalize(self, s, bot, nick): s = ircutils.stripFormatting(s) s = s.strip() # After stripFormatting for formatted spaces. s = utils.str.normalizeWhitespace(s) s = self._iAm[0].sub(self._iAm[1] % nick, s) s = self._my[0].sub(self._my[1] % nick, s) s = self._your[0].sub(self._your[1] % bot, s) contractions = [ ('what\'s', 'what is'), ('where\'s', 'where is'), ('who\'s', 'who is'), ('wtf\'s', 'wtf is'), ] for (contraction, replacement) in contractions: if s.startswith(contraction): s = replacement + s[len(contraction):] return s
def inFilter(self, irc, msg): self.filtering = True # We need to check for bad words here rather than in doPrivmsg because # messages don't get to doPrivmsg is the user is ignored. if msg.command == 'PRIVMSG': self.updateRegexp() s = ircutils.stripFormatting(msg.args[1]) channel = msg.args[0] if ircutils.isChannel(channel) and self.registryValue('kick', channel): if self.regexp.search(s): if irc.nick in irc.state.channels[channel].ops: message = self.registryValue('kick.message', channel) irc.queueMsg(ircmsgs.kick(channel, msg.nick, message)) else: self.log.warning('Should kick %s from %s, but not opped.', msg.nick, channel) return msg
def doChanservNotice(self, irc, msg): if self.disabled(irc): return s = msg.args[1].lower() channel = None m = self._chanRe.search(s) networkGroup = conf.supybot.networks.get(irc.network) on = 'on %s' % irc.network if m is not None: channel = m.group(1) if 'all bans' in s or 'unbanned from' in s or \ ('unbanned %s' % irc.nick.lower()) in \ ircutils.stripFormatting(s): # All bans removed (old freenode?) # You have been unbanned from (oftc, anope) # "Unbanned \x02someuser\x02 from \x02#channel\x02 (\x02N\x02 # ban(s) removed)" (atheme 7.x) irc.sendMsg(networkGroup.channels.join(channel)) elif 'isn\'t registered' in s: self.log.warning('Received "%s isn\'t registered" from ChanServ %s', channel, on) elif 'this channel has been registered' in s: self.log.debug('Got "Registered channel" from ChanServ %s.', on) elif 'already opped' in s: # This shouldn't happen, Services.op should refuse to run if # we already have ops. self.log.debug('Got "Already opped" from ChanServ %s.', on) elif 'access level' in s and 'is required' in s: self.log.warning('Got "Access level required" from ChanServ %s.', on) elif 'inviting' in s: self.log.debug('Got "Inviting to channel" from ChanServ %s.', on) elif s.startswith('['): chanTypes = irc.state.supported['CHANTYPES'] if re.match(r'^\[[%s]' % re.escape(chanTypes), s): self.log.debug('Got entrymsg from ChanServ %s.', on) elif ircutils.isChannel(msg.args[0]): # Atheme uses channel-wide notices for alerting channel access # changes if the FANTASY or VERBOSE setting is on; we can suppress # these 'unexpected notice' warnings since they're not really # important. pass else: self.log.warning('Got unexpected notice from ChanServ %s: %r.', on, msg)
def vote(self, irc, msg, args, action): """<something> Votes for something. It doesn't actually perform any actions directly, but could be an interesting way to get user feedback.""" action = ircutils.stripFormatting(action.lower()).strip() override = self.registryValue("allowAdminOverride") and \ ircdb.checkCapability(msg.prefix, 'admin') if not action: # It must be just whitespace or formatting codes irc.error("You must specify a proper action!", Raise=True) try: if self._lazyhostmask(msg.prefix) in self.votedb[action] and not override: irc.error("You have already voted to %s." % action, Raise=True) except KeyError: self.votedb[action] = [0] self.votedb[action][0] += 1 irc.reply("%s voted to %s" % (msg.nick,self._formatAction(action))) self.votedb[action].append(self._lazyhostmask(msg.prefix))
def vote(self, irc, msg, args, action): """<something> Votes for something. It doesn't actually perform any actions directly, but could be an interesting way to get user feedback.""" action = ircutils.stripFormatting(action.lower()).strip() override = self.registryValue("allowAdminOverride") and \ ircdb.checkCapability(msg.prefix, 'admin') if not action: # It must be just whitespace or formatting codes irc.error("You must specify a proper action!", Raise=True) try: votedhosts = map(self._lazyhostmask, self.votedb[action][1:]) if self._lazyhostmask(msg.prefix) in votedhosts and not override: irc.error("You have already voted to %r." % action, Raise=True) except KeyError: self.votedb[action] = [0] self.votedb[action][0] += 1 irc.reply("%s voted to %s" % (msg.nick, self._formatAction(action))) self.votedb[action].append(msg.prefix)
def _processText(self, channel, text): match = False ignore = self.registryValue("ignorePattern", channel) strip = self.registryValue("stripPattern", channel) text = ircutils.stripFormatting(text) if self.registryValue('stripRelayedNick', channel): text = MATCH_MESSAGE_STRIPNICK.match(text).group('message') if ignore: match = re.search(ignore, text) if match: log.debug("Cobe: %s matches ignorePattern for %s" % (text, channel)) return if strip: match = re.findall(strip, text) if match: for x in match: text = text.replace(x, '') log.debug( "Cobe: %s matches stripPattern for %s. New text text: %s" % (x, channel, text)) if self.registryValue('stripURL', channel): new_text = re.sub( r'(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))', '', text) if new_text != text: log.debug( "Cobe: url(s) stripped from text for %s. New text text: %s" % (channel, new_text)) text = new_text text = text.strip( ) # Strip whitespace from beginning and the end of the string. if len(text) > 1: # So we don't get an error if the text is too small text = text[0].upper() + text[ 1:] # Capitalize first letter of the string. text = utils.str.normalizeWhitespace( text) # Normalize the whitespace in the string. if text and len(text) > 1 and not text.isspace(): return text else: return None
def inFilter(self, irc, msg): if msg.command == 'PRIVMSG' and self.active: channel = msg.args[0] s = ircutils.stripFormatting(msg.args[1]) if ircutils.isChannel(channel) and self.registryValue( 'kick', channel): if confusables.is_mixed_script(s): c = irc.state.channels[channel] cap = ircdb.makeChannelCapability(channel, 'op') u = msg.nick t = time.time() self.thresh[u].append(t) self.thresh[u] = [ item for item in self.thresh[u] if item > (t - self.registryValue('slw')) ] self.log.warning( "Detected mixed <%s>, threshold" "for user %s is now %s", s, u, len(self.thresh[u])) if len(self.thresh[u]) > self.registryValue('rep'): self.log.warning( "Threshold reached, trying to kick %s", u) if c.isHalfopPlus(irc.nick): if c.isHalfopPlus(u) or \ ircdb.checkCapability(msg.prefix, cap): self.log.warning( "Not kicking %s from %s, because " "they are halfop+ or can't be " "kicked.", u, channel) else: message = self.registryValue( 'kick.message', channel) irc.queueMsg(ircmsgs.kick(channel, u, message)) self.log.warning("Kicked %s from %s", u, channel) else: self.log.warning( 'Should kick %s from %s, but not opped.', u, channel) return msg
def votes(self, irc, msg, args, opts, action): """[--hosts] [--number] <action> Returns the amount of people that have voted for <action>. If --hosts is given, also show the hosts that have voted for <action>. If --number is given, only returns the number of people who has voted for <action> (useful for nested commands).""" action = ircutils.stripFormatting(action.lower()).strip() if not action: irc.error("You must specify a proper action!", Raise=True) try: n, hosts = self.votedb[action][0], self.votedb[action][1:] except KeyError: n, hosts = 0, None opts = dict(opts) if 'number' in opts: irc.reply(n) else: s = '\x02%s\x02 %s voted to %s' % \ (n, 'person has' if n == 1 else 'people have', \ self._formatAction(action)) if 'hosts' in opts and n: s += format(" [%L]", list(set(hosts))) irc.reply(s)
def _sf(self, string): """Returns a string with stripped formatting.""" return ircutils.stripFormatting(string)
def stripformatting(self, irc, msg, args, text): """<text> Strips bold, underline, and colors from <text>.""" irc.reply(ircutils.stripFormatting(text))