def testIsNickNeverAllowsSpaces(self): try: original = conf.supybot.protocols.irc.strictRfc() conf.supybot.protocols.irc.strictRfc.setValue(True) self.failIf(ircutils.isNick('foo bar')) conf.supybot.protocols.irc.strictRfc.setValue(False) self.failIf(ircutils.isNick('foo bar')) finally: conf.supybot.protocols.irc.strictRfc.setValue(original)
def tell(self, irc, msg, args, target, text): """<nick> <text> Tells the <nick> whatever <text> is. Use nested commands to your benefit here. """ if irc.nested: irc.error("This command cannot be nested.", Raise=True) if target.lower() == "me": target = msg.nick if ircutils.isChannel(target): irc.error("Dude, just give the command. No need for the tell.") return if not ircutils.isNick(target): irc.errorInvalid("nick", target) if ircutils.nickEqual(target, irc.nick): irc.error("You just told me, why should I tell myself?", Raise=True) if target not in irc.state.nicksToHostmasks and not ircdb.checkCapability(msg.prefix, "owner"): # We'll let owners do this. s = "I haven't seen %s, I'll let you do the telling." % target irc.error(s, Raise=True) if irc.action: irc.action = False text = "* %s %s" % (irc.nick, text) s = "%s wants me to tell you: %s" % (msg.nick, text) irc.replySuccess() irc.reply(s, to=target, private=True)
def tell(self, irc, msg, args, target, text): """<nick> <text> Tells the <nick> whatever <text> is. Use nested commands to your benefit here. """ if irc.nested: irc.error('This command cannot be nested.', Raise=True) if target.lower() == 'me': target = msg.nick if ircutils.isChannel(target): irc.error('Dude, just give the command. No need for the tell.') return if not ircutils.isNick(target): irc.errorInvalid('nick', target) if ircutils.nickEqual(target, irc.nick): irc.error('You just told me, why should I tell myself?',Raise=True) if target not in irc.state.nicksToHostmasks and \ not ircdb.checkCapability(msg.prefix, 'owner'): # We'll let owners do this. s = 'I haven\'t seen %s, I\'ll let you do the telling.' % target irc.error(s, Raise=True) if irc.action: irc.action = False text = '* %s %s' % (irc.nick, text) s = '%s wants me to tell you: %s' % (msg.nick, text) irc.replySuccess() irc.reply(s, to=target, private=True)
def tell(self, irc, msg, args, target, text): """<nick> <text> Tells the <nick> whatever <text> is. Use nested commands to your benefit here. """ if target.lower() == 'me': target = msg.nick if ircutils.isChannel(target): irc.error('Dude, just give the command. No need for the tell.') return if not ircutils.isNick(target): irc.errorInvalid('nick', target) if ircutils.nickEqual(target, irc.nick): irc.error('You just told me, why should I tell myself?',Raise=True) if target not in irc.state.nicksToHostmasks and \ not ircdb.checkCapability(msg.prefix, 'owner'): # We'll let owners do this. s = 'I haven\'t seen %s, I\'ll let you do the telling.' % target irc.error(s, Raise=True) if irc.action: irc.action = False text = '* %s %s' % (irc.nick, text) s = '%s wants me to tell you: %s' % (msg.nick, text) irc.reply(s, to=target, private=True)
def getNick(irc, msg, args, state): if ircutils.isNick(args[0], conf.supybot.protocols.irc.strictRfc()): if "nicklen" in irc.state.supported: if len(args[0]) > irc.state.supported["nicklen"]: state.errorInvalid(_("nick"), args[0], _("That nick is too long for this server.")) state.args.append(args.pop(0)) else: state.errorInvalid(_("nick"), args[0])
def replacer(self, irc, msg, regex): if not self.registryValue('enable', msg.args[0]): return iterable = reversed(irc.state.history) msg.tag('Replacer') try: (pattern, replacement, count) = self._unpack_sed(msg.args[1]) except (ValueError, re.error) as e: self.log.warning(_("Replacer error: %s"), e) if self.registryValue('displayErrors', msg.args[0]): irc.error(_("Replacer error: %s" % e), Raise=True) return next(iterable) for m in iterable: if m.command in ('PRIVMSG', 'NOTICE') and \ m.args[0] == msg.args[0]: target = regex.group('nick') if not ircutils.isNick(str(target), strictRfc=True): return if target and m.nick != target: continue # Don't snarf ignored users' messages unless specifically # told to. if ircdb.checkIgnored(m.prefix) and not target: continue # When running substitutions, ignore the "* nick" part of any actions. action = ircmsgs.isAction(m) if action: text = ircmsgs.unAction(m) else: text = m.args[1] if self.registryValue('ignoreRegex', msg.args[0]) and \ m.tagged('Replacer'): continue if m.nick == msg.nick: messageprefix = msg.nick else: messageprefix = '%s thinks %s' % (msg.nick, m.nick) if regexp_wrapper(text, pattern, timeout=0.05, plugin_name=self.name(), fcn_name='replacer'): if self.registryValue('boldReplacementText', msg.args[0]): replacement = ircutils.bold(replacement) subst = process(pattern.sub, replacement, text, count, timeout=0.05) if action: # If the message was an ACTION, prepend the nick back. subst = '* %s %s' % (m.nick, subst) irc.reply(_("%s meant to say: %s") % (messageprefix, subst), prefixNick=False) return self.log.debug(_("Replacer: Search %r not found in the last %i messages of %s."), msg.args[1], len(irc.state.history), msg.args[0]) if self.registryValue("displayErrors", msg.args[0]): irc.error(_("Search not found in the last %i messages.") % len(irc.state.history), Raise=True)
def getNick(irc, msg, args, state): if ircutils.isNick(args[0]): if 'nicklen' in irc.state.supported: if len(args[0]) > irc.state.supported['nicklen']: state.errorInvalid('nick', args[0], 'That nick is too long for this server.') state.args.append(args.pop(0)) else: state.errorInvalid('nick', args[0])
def getNick(irc, msg, args, state): if ircutils.isNick(args[0], conf.supybot.protocols.irc.strictRfc()): if 'nicklen' in irc.state.supported: if len(args[0]) > irc.state.supported['nicklen']: state.errorInvalid(_('nick'), args[0], _('That nick is too long for this server.')) state.args.append(args.pop(0)) else: state.errorInvalid(_('nick'), args[0])
def addNick(self, network, nick): """Adds a nick to the user's registered nicks on the network.""" global users assert isinstance(network, basestring) assert ircutils.isNick(nick), 'got %s' % nick if users.getUserFromNick(network, nick) is not None: raise KeyError if network not in self.nicks: self.nicks[network] = [] if nick not in self.nicks[network]: self.nicks[network].append(nick)
def replacer(self, irc, msg, regex): if not self.registryValue('enable', msg.channel, irc.network): return self.log.debug("SedRegex: running on %s/%s for %s", irc.network, msg.channel, regex) iterable = reversed(irc.state.history) msg.tag(TAG_IS_REGEX) try: (pattern, replacement, count, flags) = self._unpack_sed(msg.args[1]) except Exception as e: self.log.warning(_("SedRegex parser error: %s"), e, exc_info=True) if self.registryValue('displayErrors', msg.channel, irc.network): irc.error('%s.%s: %s' % (e.__class__.__module__, e.__class__.__name__, e)) return next(iterable) if 's' in flags: # Special 's' flag lets the bot only look at self messages target = msg.nick else: target = regex.group('nick') if not ircutils.isNick(str(target)): return regex_timeout = self.registryValue('processTimeout') try: message = process(self._replacer_process, irc, msg, target, pattern, replacement, count, iterable, timeout=regex_timeout, pn=self.name(), cn='replacer') except ProcessTimeoutError: irc.error(_("Search timed out.")) except SearchNotFoundError: irc.error( _("Search not found in the last %i IRC messages on this network." ) % len(irc.state.history)) except Exception as e: self.log.warning(_("SedRegex replacer error: %s"), e, exc_info=True) if self.registryValue('displayErrors', msg.channel, irc.network): irc.error('%s.%s: %s' % (e.__class__.__module__, e.__class__.__name__, e)) else: irc.reply(message, prefixNick=False)
def username(self, irc, msg, args, hostmask): """<hostmask|nick> Returns the username of the user specified by <hostmask> or <nick> if the user is registered. """ if ircutils.isNick(hostmask): try: hostmask = irc.state.nickToHostmask(hostmask) except KeyError: irc.error(_('I haven\'t seen %s.') % hostmask, Raise=True) try: user = ircdb.users.getUser(hostmask) irc.reply(user.name) except KeyError: irc.error(_('I don\'t know who that is.'))
def invalidCommand(self, irc, msg, tokens): if irc.isChannel(msg.args[0]): channel = msg.args[0] if self.registryValue('replyWhenInvalidCommand', channel): redirect_nick=None # we're looking for @factoid | nick if "|" in tokens and tokens.index("|") == len(tokens) - 2: # get the nick redirect_nick = tokens.pop() c = irc.state.channels[channel] if not ircutils.isNick(redirect_nick) or \ redirect_nick not in c.users: irc.error('No such user.') return # don't want to talk to myself if redirect_nick == irc.nick: redirect_nick = None # and get rid of the | character tokens.pop() key = ' '.join(tokens) factoids = self._lookupFactoid(channel, key) self._replyFactoids(irc, msg, key, factoids, error=False) to=redirect_nick)
def _tell(self, irc, msg, args, target, text, notice): if irc.nested: irc.error('This command cannot be nested.', Raise=True) if target.lower() == 'me': target = msg.nick if ircutils.isChannel(target): irc.error(_('Hey, just give the command. No need for the tell.')) return if not ircutils.isNick(target): irc.errorInvalid('nick', target) if ircutils.nickEqual(target, irc.nick): irc.error(_('You just told me, why should I tell myself?'), Raise=True) if target not in irc.state.nicksToHostmasks and \ not ircdb.checkCapability(msg.prefix, 'owner'): # We'll let owners do this. s = _('I haven\'t seen %s, I\'ll let you do the telling.') % target irc.error(s, Raise=True) if irc.action: irc.action = False text = '* %s %s' % (irc.nick, text) s = _('%s wants me to tell you: %s') % (msg.nick, text) irc.replySuccess() irc.reply(s, to=target, private=True, notice=notice)
def reviewBans(self, irc=None): reviewTime = int(self.registryValue('request.review') * 86400) if not reviewTime: # time is zero, do nothing return now = time.mktime(time.gmtime()) lastreview = self.pendingReviews.time self.pendingReviews.time = now # update last time reviewed if not lastreview: # initialize last time reviewed timestamp lastreview = now - reviewTime for channel, bans in self.bans.iteritems(): if not self.registryValue('enabled', channel) \ or not self.registryValue('request', channel): continue for ban in bans: if guessBanType(ban.mask) in ('quiet', 'removal'): # skip mutes and kicks continue banAge = now - ban.when reviewWindow = lastreview - ban.when #self.log.debug('review ban: %s ban %s by %s (%s/%s/%s %s)', channel, ban.mask, # ban.who, reviewWindow, reviewTime, banAge, reviewTime - reviewWindow) if reviewWindow <= reviewTime < banAge: # ban is old enough, and inside the "review window" try: # ban.who should be a user hostmask nick = ircutils.nickFromHostmask(ban.who) host = ircutils.hostFromHostmask(ban.who) except: if ircutils.isNick(ban.who, strictRfc=True): # ok, op's nick, use it nick = ban.who host = None else: # probably a ban restored by IRC server in a netsplit # XXX see if something can be done about this continue if nickMatch(nick, self.registryValue('request.ignore', channel)): # in the ignore list continue if not ban.id: ban.id = self.get_banId(ban.mask, channel) if nickMatch(nick, self.registryValue('request.forward', channel)): s = "Hi, please somebody review the ban '%s' set by %s on %s in"\ " %s, link: %s/bans.cgi?log=%s" %(ban.mask, nick, ban.ascwhen, channel, self.registryValue('bansite'), ban.id) self._sendForward(irc, s, channel) else: s = "Hi, please review the ban '%s' that you set on %s in %s, link:"\ " %s/bans.cgi?log=%s" %(ban.mask, ban.ascwhen, channel, self.registryValue('bansite'), ban.id) msg = ircmsgs.privmsg(nick, s) if host in self.pendingReviews \ and (nick, msg) not in self.pendingReviews[host]: self.pendingReviews[host].append((nick, msg)) else: self.pendingReviews[host] = [(nick, msg)] elif banAge < reviewTime: # since we made sure bans are sorted by time, the bans left are more recent break
def replacer(self, irc, msg, regex): if not self.registryValue('enable', msg.args[0]): return iterable = reversed(irc.state.history) msg.tag('Replacer') try: (pattern, replacement, count, flags) = self._unpack_sed(msg.args[1]) except (ValueError, re.error) as e: self.log.warning(_("SedRegex error: %s"), e) if self.registryValue('displayErrors', msg.args[0]): irc.error('%s.%s: %s' % (e.__class__.__module__, e.__class__.__name__, e)) return next(iterable) if 's' in flags: # Special 's' flag lets the bot only look at self messages target = msg.nick else: target = regex.group('nick') if not ircutils.isNick(str(target), strictRfc=True): return for m in iterable: if m.command in ('PRIVMSG', 'NOTICE') and \ m.args[0] == msg.args[0] and m.tagged('receivedBy') == irc: if target and m.nick != target: continue # Don't snarf ignored users' messages unless specifically # told to. if ircdb.checkIgnored(m.prefix) and not target: continue # When running substitutions, ignore the "* nick" part of any actions. action = ircmsgs.isAction(m) if action: text = ircmsgs.unAction(m) else: text = m.args[1] if self.registryValue('ignoreRegex', msg.args[0]) and \ m.tagged('Replacer'): continue if m.nick == msg.nick: messageprefix = msg.nick else: messageprefix = '%s thinks %s' % (msg.nick, m.nick) try: regex_timeout = self.registryValue('processTimeout') if regexp_wrapper(text, pattern, timeout=regex_timeout, plugin_name=self.name(), fcn_name='replacer'): if self.registryValue('boldReplacementText', msg.args[0]): replacement = ircutils.bold(replacement) subst = process(pattern.sub, replacement, text, count, timeout=0.05) if action: # If the message was an ACTION, prepend the nick back. subst = '* %s %s' % (m.nick, subst) subst = axe_spaces(subst) irc.reply(_("%s meant to say: %s") % (messageprefix, subst), prefixNick=False) return except (ValueError, re.error) as e: if self.registryValue('displayErrors', msg.args[0]): irc.error('%s.%s: %s' % (e.__class__.__module__, e.__class__.__name__, e)) return self.log.debug(_("SedRegex: Search %r not found in the last %i messages of %s."), msg.args[1], len(irc.state.history), msg.args[0]) if self.registryValue("displayErrors", msg.args[0]): irc.error(_("Search not found in the last %i messages.") % len(irc.state.history), Raise=True)
def setValue(self, v): if v and not ircutils.isNick(v): raise registry.InvalidRegistryValue( 'Value must be a valid nick or the empty string.') registry.String.setValue(self, v)
def set(self, s): if not ircutils.isNick(s): self.error() registry.String.set(self, s)
def setValue(self, v): if v and not ircutils.isNick(v): raise registry.InvalidRegistryValue, \ 'Value must be a valid nick or the empty string.' registry.String.setValue(self, v)
def setValue(self, v): if not (ircutils.isNick(v) or ircutils.isChannel(v)): self.error() registry.String.setValue(self, v)
def testIsNick(self): try: original = conf.supybot.protocols.irc.strictRfc() conf.supybot.protocols.irc.strictRfc.setValue(True) self.failUnless(ircutils.isNick("jemfinch")) self.failUnless(ircutils.isNick("jemfinch0")) self.failUnless(ircutils.isNick("[0]")) self.failUnless(ircutils.isNick("{jemfinch}")) self.failUnless(ircutils.isNick("[jemfinch]")) self.failUnless(ircutils.isNick("jem|finch")) self.failUnless(ircutils.isNick("\\```")) self.failUnless(ircutils.isNick("`")) self.failUnless(ircutils.isNick("A")) self.failIf(ircutils.isNick("")) self.failIf(ircutils.isNick("8foo")) self.failIf(ircutils.isNick("10")) self.failIf(ircutils.isNick("-")) self.failIf(ircutils.isNick("-foo")) conf.supybot.protocols.irc.strictRfc.setValue(False) self.failUnless(ircutils.isNick("*****@*****.**")) finally: conf.supybot.protocols.irc.strictRfc.setValue(original)
def testIsNick(self): try: original = conf.supybot.protocols.irc.strictRfc() conf.supybot.protocols.irc.strictRfc.setValue(True) self.failUnless(ircutils.isNick('jemfinch')) self.failUnless(ircutils.isNick('jemfinch0')) self.failUnless(ircutils.isNick('[0]')) self.failUnless(ircutils.isNick('{jemfinch}')) self.failUnless(ircutils.isNick('[jemfinch]')) self.failUnless(ircutils.isNick('jem|finch')) self.failUnless(ircutils.isNick('\\```')) self.failUnless(ircutils.isNick('`')) self.failUnless(ircutils.isNick('A')) self.failIf(ircutils.isNick('')) self.failIf(ircutils.isNick('8foo')) self.failIf(ircutils.isNick('10')) self.failIf(ircutils.isNick('-')) self.failIf(ircutils.isNick('-foo')) conf.supybot.protocols.irc.strictRfc.setValue(False) self.failUnless(ircutils.isNick('*****@*****.**')) finally: conf.supybot.protocols.irc.strictRfc.setValue(original)
def setValue(self, v): if not ircutils.isNick(v): self.error() else: registry.String.setValue(self, v)