def _wrap(f, specList=[], name=None, checkDoc=True, **kw): name = name or f.func_name assert (not checkDoc) or (hasattr(f, '__doc__') and f.__doc__), \ 'Command %r has no docstring.' % name f = internationalizeDocstring(f) spec = Spec(specList, **kw) def newf(self, irc, msg, args, **kwargs): state = spec(irc, msg, args, stateAttrs={'cb': self, 'log': self.log}) self.log.debug('State before call: %s', state) if state.errored: self.log.debug('Refusing to call %s due to state.errored.', f) else: try: f(self, irc, msg, args, *state.args, **state.kwargs) except TypeError: self.log.error('Spec: %s', specList) self.log.error('Received args: %s', args) code = f.func_code funcArgs = inspect.getargs(code)[0][len(self.commandArgs):] self.log.error('Extra args: %s', funcArgs) self.log.debug('Make sure you did not wrap a wrapped ' 'function ;)') raise return utils.python.changeFunctionName(newf, name, f.__doc__)
def _wrap(f, specList=[], name=None, **kw): assert hasattr(f, '__doc__') f = internationalizeDocstring(f) name = name or f.func_name spec = Spec(specList, **kw) def newf(self, irc, msg, args, **kwargs): state = spec(irc, msg, args, stateAttrs={'cb': self, 'log': self.log}) self.log.debug('State before call: %s', state) if state.errored: self.log.debug('Refusing to call %s due to state.errored.', f) else: try: f(self, irc, msg, args, *state.args, **state.kwargs) except TypeError: self.log.error('Spec: %s', specList) self.log.error('Received args: %s', args) code = f.func_code funcArgs = inspect.getargs(code)[0][len(self.commandArgs):] self.log.error('Extra args: %s', funcArgs) self.log.debug('Make sure you did not wrap a wrapped ' 'function ;)') raise return utils.python.changeFunctionName(newf, name, f.__doc__)
from supybot.i18n import PluginInternationalization, internationalizeDocstring _ = PluginInternationalization('Dunno') class Dunno(plugins.ChannelIdDatabasePlugin): """This plugin was written initially to work with MoobotFactoids, the two of them to provide a similar-to-moobot-and-blootbot interface for factoids. Basically, it replaces the standard 'Error: <x> is not a valid command.' messages with messages kept in a database, able to give more personable responses.""" callAfter = ['MoobotFactoids', 'Factoids', 'Infobot'] def invalidCommand(self, irc, msg, tokens): channel = msg.args[0] if irc.isChannel(channel): dunno = self.db.random(channel) if dunno is not None: dunno = dunno.text prefixNick = self.registryValue('prefixNick', channel) env = {'command': tokens[0]} dunno = ircutils.standardSubstitute(irc, msg, dunno, env=env) irc.reply(dunno, prefixNick=prefixNick) Dunno = internationalizeDocstring(Dunno) Class = Dunno # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
url = self.registryValue('feeds.%s' % url) except registry.NonExistentRegistryEntry: pass feed = self.getFeed(url) conv = self._getConverter(feed) info = feed.get('feed') if not info: irc.error(_('I couldn\'t retrieve that RSS feed.')) return # check the 'modified_parsed' key, if it's there, convert it here first if 'modified' in info: seconds = time.mktime(info['modified_parsed']) now = time.mktime(time.gmtime()) when = utils.timeElapsed(now - seconds) + ' ago' else: when = 'time unavailable' title = conv(info.get('title', 'unavailable')) desc = conv(info.get('description', 'unavailable')) link = conv(info.get('link', 'unavailable')) # The rest of the entries are all available in the channel key response = format(_('Title: %s; URL: %u; ' 'Description: %s; Last updated: %s.'), title, link, desc, when) irc.reply(utils.str.normalizeWhitespace(response)) info = wrap(info, [first('url', 'feedName')]) RSS = internationalizeDocstring(RSS) Class = RSS # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
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: 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.repliedTo = old_repliedto def _formatNote(self, when, whence, note): return _('Sent %s: <%s> %s') % (self._timestamp(when), whence, note) def doJoin(self, irc, msg): if self.registryValue('tellOnJoin'): self.doPrivmsg(irc, msg) Later = internationalizeDocstring(Later) Class = Later # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
irc.noReply() def _enforceLimit(self, irc, channel): if self.registryValue('enable', channel): maximum = self.registryValue('maximumExcess', channel) minimum = self.registryValue('minimumExcess', channel) assert maximum > minimum currentUsers = len(irc.state.channels[channel].users) currentLimit = irc.state.channels[channel].modes.get('l', 0) if currentLimit - currentUsers < minimum: self._enforce(irc, ircmsgs.limit(channel,currentUsers+maximum)) elif currentLimit - currentUsers > maximum: self._enforce(irc, ircmsgs.limit(channel,currentUsers+minimum)) def doJoin(self, irc, msg): if not ircutils.strEqual(msg.nick, irc.nick): irc = callbacks.SimpleProxy(irc, msg) self._enforceLimit(irc, msg.args[0]) doPart = doJoin doKick = doJoin def doQuit(self, irc, msg): for channel in irc.state.channels: self._enforceLimit(irc, channel) Limiter = internationalizeDocstring(Limiter) Class = Limiter # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
feed = Feed(url, url, True) self.update_feed_if_needed(feed) info = feed.data if not info: irc.error(_('I couldn\'t retrieve that RSS feed.')) return # check the 'modified_parsed' key, if it's there, convert it here first if 'modified' in info: seconds = time.mktime(info['modified_parsed']) now = time.mktime(time.gmtime()) when = utils.timeElapsed(now - seconds) + ' ago' else: when = _('time unavailable') title = info.get('title', _('unavailable')) desc = info.get('description', _('unavailable')) link = info.get('link', _('unavailable')) # The rest of the entries are all available in the channel key response = format( _('Title: %s; URL: %u; ' 'Description: %s; Last updated: %s.'), title, link, desc, when) irc.reply(utils.str.normalizeWhitespace(response)) info = wrap(info, [first('url', 'feedName')]) RSS = internationalizeDocstring(RSS) Class = RSS # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
"""<text> Returns <text> rotated 180 degrees. Only really works for ASCII printable characters. """ turned = [] tlen = 0 for c in text: if c in self._uniudMap: tmp = self._uniudMap[c] if not len(tmp): tmp = '\ufffd' turned.append(tmp) tlen += 1 elif c == '\t': tablen = 8 - tlen % 8 turned.append(' ' * tablen) tlen += tablen elif ord(c) >= 32: turned.append(c) tlen += 1 s = '%s \x02 \x02' % ''.join(reversed(turned)) irc.reply(s) uniud = wrap(uniud, ['text']) Filter = internationalizeDocstring(Filter) Class = Filter # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
internationalizeDocstring = lambda x:x def configure(advanced): from supybot.questions import output, expect, anything, something, yn conf.registerPlugin('LinkRelay', True) class ColorNumber(registry.String): """Value must be a valid color number (01, 02, 03, 04, ..., 16)""" def set(self, s): if s not in ('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16'): self.error() return self.setValue(s) ColorNumber = internationalizeDocstring(ColorNumber) LinkRelay = conf.registerPlugin('LinkRelay') conf.registerChannelValue(LinkRelay, 'color', registry.Boolean(False, _("""Determines whether the bot will color Relayed PRIVMSGs so as to make the messages easier to read."""))) conf.registerChannelValue(LinkRelay, 'topicSync', registry.Boolean(True, _("""Determines whether the bot will synchronize topics between networks in the channels it Relays."""))) conf.registerChannelValue(LinkRelay, 'hostmasks', registry.Boolean(False, _("""Determines whether the bot will Relay the hostmask of the person joining or parting the channel when he or she joins or parts."""))) conf.registerChannelValue(LinkRelay, 'nicks', registry.Boolean(True, _("""Determines whether the bot will relay the
conf.registerPlugin("AttackProtector", True) class XpY(registry.String): """Value must be in the format <number>p<seconds>.""" _re = re.compile("(?P<number>[0-9]+)p(?P<seconds>[0-9]+)") def setValue(self, v): if self._re.match(v): registry.String.setValue(self, v) else: self.error() XpY = internationalizeDocstring(XpY) class Punishment(registry.String): """Value must be a valid punishment ('ban', 'kick', 'kban', 'mode+X', 'mode-X', 'command XXX', ...)""" def set(self, s): if ( s not in ("ban", "kick", "kban") and not s.startswith("mode+") and not s.startswith("mode-") and not s.startswith("command ") ): self.error() return
def _sendIson(self, irc, nick): self.log.info('Checking if %s ISON %s.', nick, irc.network) irc.queueMsg(ircmsgs.ison(nick)) def _sendNick(self, irc, nick): self.log.info('Attempting to switch to nick %s on %s.', nick, irc.network) irc.sendMsg(ircmsgs.nick(nick)) def doQuit(self, irc, msg): nick = self._getNick(irc.network) if ircutils.strEqual(msg.nick, nick): self._sendNick(irc, nick) def doNick(self, irc, msg): nick = self._getNick(irc.network) if ircutils.strEqual(msg.nick, nick): self._sendNick(irc, nick) def do303(self, irc, msg): """This is returned by the ISON command.""" if not msg.args[1]: nick = self._getNick(irc.network) if nick: self._sendNick(irc, nick) NickCapture = internationalizeDocstring(NickCapture) Class = NickCapture # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
(target, reason) = (text, '') if ircutils.strEqual(target, irc.nick): target = 'itself' if id is not None: try: praise = self.db.get(channel, id) except KeyError: irc.error(format(_('There is no praise with id #%i.'), id)) return else: praise = self.db.random(channel) if not praise: irc.error(format(_('There are no praises in my database ' \ 'for %s.'), channel)) return text = self._replaceFirstPerson(praise.text, msg.nick) reason = self._replaceFirstPerson(reason, msg.nick) target = self._replaceFirstPerson(target, msg.nick) text = text.replace('$who', target) if reason: text += _(' for ') + reason if self.registryValue('showIds', channel): text += format(' (#%i)', praise.id) irc.reply(text, action=True) praise = wrap(praise, ['channeldb', optional('id'), 'text']) Praise = internationalizeDocstring(Praise) Class = Praise # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
def __call__(self): ret = pluginSelf.db.random(dynamic.msg.args[0]) if ret is None: try: self.__class__ = pluginSelf.originalClass ret = self() finally: self.__class__ = MySuccessClass else: ret = ret.text return ret def get(self, attr): if irc.isChannel(attr): pluginSelf.target = attr return self conf.supybot.replies.success.__class__ = MySuccessClass def die(self): self.__parent.die() conf.supybot.replies.success.__class__ = self.originalClass Success = internationalizeDocstring(Success) Class = Success # vim:set shiftwidth=4 softtabstop=8 expandtab textwidth=78:
maximum = self.registryValue('maximumExcess', channel) minimum = self.registryValue('minimumExcess', channel) assert maximum > minimum currentUsers = len(irc.state.channels[channel].users) currentLimit = irc.state.channels[channel].modes.get('l', 0) if currentLimit - currentUsers < minimum: self._enforce(irc, ircmsgs.limit(channel, currentUsers + maximum)) elif currentLimit - currentUsers > maximum: self._enforce(irc, ircmsgs.limit(channel, currentUsers + minimum)) def doJoin(self, irc, msg): if not ircutils.strEqual(msg.nick, irc.nick): irc = callbacks.SimpleProxy(irc, msg) self._enforceLimit(irc, msg.args[0]) doPart = doJoin doKick = doJoin def doQuit(self, irc, msg): for channel in irc.state.channels: self._enforceLimit(irc, channel) Limiter = internationalizeDocstring(Limiter) Class = Limiter # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
irc.reply(", ".join(s)) rank = wrap(rank, ['channelOrGlobal']) @internationalizeDocstring def vacuum(self, irc, msg, args, channel): """[<channel>|global] Vacuums the database for <channel>. See SQLite vacuum doc here: http://www.sqlite.org/lang_vacuum.html <channel> is only necessary if the message isn't sent in the channel itself. First check if user has the required capability specified in plugin config requireVacuumCapability. """ capability = self.registryValue('requireVacuumCapability') if capability: if not ircdb.checkCapability(msg.prefix, capability): irc.errorNoCapability(capability, Raise=True) db = self.getDb(channel) cursor = db.cursor() cursor.execute("""VACUUM""") db.commit() irc.replySuccess() vacuum = wrap(vacuum, ['channelOrGlobal']) MessageParser = internationalizeDocstring(MessageParser) Class = MessageParser # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
def do303(self, irc, msg): """This is returned by the ISON command.""" if not msg.args[1]: nick = self._getNick(irc.network) if nick: self._sendNick(irc, nick) def do731(self, irc, msg): """This is sent by the MONITOR when a nick goes offline.""" nick = self._getNick(irc.network) for target in msg.args[1].split(','): if nick == target: self._sendNick(irc, nick) self.monitoring.remove(irc) irc.unmonitor(nick) break def do437(self, irc, msg): """Nick/channel is temporarily unavailable""" if irc.isChannel(msg.args[1]): return self.log.info('Nick %s is unavailable; attempting NickServ release ' 'on %s.' % (msg.args[1], irc.network)) irc.sendMsg(ircmsgs.privmsg('NickServ', 'release %s' % msg.args[1])) NickCapture = internationalizeDocstring(NickCapture) Class = NickCapture # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
irc.error(_('Unable to react, %s\'s last message does not have ' 'a message id.') % nick, Raise=True) self.log.info('Reacting with %q in %s due to %s.', reaction, channel, msg.prefix) reaction_msg = ircmsgs.IrcMsg(command='TAGMSG', args=(channel, ), server_tags={ '+draft/reply': react_to_msgid, '+draft/react': reaction }) irc.queueMsg(reaction_msg) react = wrap(react, ['inChannel', 'somethingWithoutSpaces', 'nickInChannel']) def _validLastMsg(self, irc, msg): return msg.prefix and \ msg.command == 'PRIVMSG' and \ msg.channel Anonymous = internationalizeDocstring(Anonymous) Class = Anonymous # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
conf.registerPlugin('AttackProtector', True) class XpY(registry.String): """Value must be in the format <number>p<seconds>.""" _re = re.compile('(?P<number>[0-9]+)p(?P<seconds>[0-9]+)') def setValue(self, v): if self._re.match(v): registry.String.setValue(self, v) else: self.error() try: XpY = internationalizeDocstring(XpY) except TypeError: # Pypy pass class Punishment(registry.String): """Value must be a valid punishment ('ban', 'kick', 'kban', 'mode+X', 'mode-X', 'umode+X', 'umode-X', 'mmode+X', 'mmode-X', 'command XXX', ...)""" def set(self, s): if s not in ('ban', 'kick', 'kban') and not s.startswith('mode+') and \ not s.startswith('mode-') and not s.startswith('umode-') and \ not s.startswith('umode+') and \ not s.startswith('mmode+') and not s.startswith('mmode-') and \ not s.startswith('command ') and \
@internationalizeDocstring def info(self, irc, msg, args, repository, plugin): """<repository> <plugin> Displays informations on the <plugin> in the <repository>.""" global repositories if repository not in repositories: irc.error( _('This repository does not exist or is not known by ' 'this bot.')) elif plugin not in repositories[repository].getPluginList(): irc.error(_('This plugin does not exist in this repository.')) else: info = repositories[repository].getInfo(plugin) if info is None: irc.error(_('No README found for this plugin.')) else: if info.startswith('Insert a description of your plugin here'): irc.error(_('This plugin has no description.')) else: info = info.split('\n\n')[0] irc.reply(info.replace('\n', ' ')) info = wrap(info, ['something', optional('something')]) PluginDownloader = internationalizeDocstring(PluginDownloader) Class = PluginDownloader # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
Replies with <text> in a notice. Use nested commands to your benefit here. If you want a private notice, nest the private command. """ irc.reply(text, notice=True) notice = wrap(notice, ['text']) @internationalizeDocstring def reply(self, irc, msg, args, text): """<text> Replies with <text>. Equivalent to the alias, 'echo $nick: $1'. """ irc.reply(text, prefixNick=True) reply = wrap(reply, ['text']) @internationalizeDocstring def replies(self, irc, msg, args, strings): """<str> [<str> ...] Replies with each of its arguments <str> in separate replies, depending the configuration of supybot.reply.oneToOne. """ irc.replies(strings) replies = wrap(replies, [many('something')]) Reply = internationalizeDocstring(Reply) Class = Reply # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
import supybot.ircutils as ircutils from supybot.i18n import PluginInternationalization, internationalizeDocstring _ = PluginInternationalization('Dunno') class Dunno(plugins.ChannelIdDatabasePlugin): """This plugin was written initially to work with MoobotFactoids, the two of them to provide a similar-to-moobot-and-blootbot interface for factoids. Basically, it replaces the standard 'Error: <x> is not a valid command.' messages with messages kept in a database, able to give more personable responses.""" callAfter = ['MoobotFactoids', 'Factoids', 'Infobot'] def invalidCommand(self, irc, msg, tokens): channel = msg.args[0] if irc.isChannel(channel): dunno = self.db.random(channel) if dunno is not None: dunno = dunno.text prefixNick = self.registryValue('prefixNick', channel) env = {'command': tokens[0]} self.log.info('Issuing "dunno" answer, %s is not a command.' % tokens[0]) dunno = ircutils.standardSubstitute(irc, msg, dunno, env=env) irc.reply(dunno, prefixNick=prefixNick) Dunno = internationalizeDocstring(Dunno) Class = Dunno # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
nick, cb.name()) authorInfo = contributorNicks[lnick] contributions = contributors[authorInfo] fullName = authorInfo.format(short=True) if contributions: return format(_('%s contributed the following to %s: %s'), fullName, cb.name(), ', '.join(contributions)) else: return _( '%s did not list any specific contributions to the %s ' 'plugin.') % (fullName, cb.name()) # First we need to check and see if the requested plugin is loaded module = cb.classModule if not nick: irc.reply(buildPeopleString(module)) else: nick = ircutils.toLower(nick) irc.reply(buildPersonString(module)) contributors = wrap(contributors, ['plugin', additional('text')]) Plugin = internationalizeDocstring(Plugin) Class = Plugin # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
for link in links: irc.reply('http://economy.erepublik.com/en/company/%s' % link) land = wrap(land, []) @internationalizeDocstring def fight(self, irc, msg, args, name): """<name|id> Shows how many damages you can make in one hit.""" citizen = getCitizen(irc, name) if citizen is None: return irc.reply(_('damages: %i') % citizen.fightCalcStr(100.0)) @internationalizeDocstring def kamikaze(self, irc, msg, args, name): """<name|id> Shows how many damages you can make in one hit.""" citizen = getCitizen(irc, name) if citizen is None: return irc.reply(_('kamikaze attack with full food: %i') % citizen.fightCalcStr(100.0)) ERepublik = internationalizeDocstring(ERepublik) Class = ERepublik # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
Deletes the factoid with the given key. <channel> is only necessary if the message isn't sent in the channel itself. """ _ = self._getFactoid(irc, channel, key) self._checkNotLocked(irc, channel, key) self.db.removeFactoid(channel, key) irc.replySuccess() remove = wrap(remove, ['channeldb', 'user', 'text']) @internationalizeDocstring def random(self, irc, msg, args, channel): """[<channel>] Displays a random factoid (along with its key) from the database. <channel> is only necessary if the message isn't sent in the channel itself. """ results = self.db.randomFactoid(channel) if not results: irc.error(_('No factoids in the database.')) return (fact, key) = results irc.reply(format('Random factoid: %q is %q', key, fact)) random = wrap(random, ['channeldb']) MoobotFactoids = internationalizeDocstring(MoobotFactoids) Class = MoobotFactoids # vim:set shiftwidth=4 softtabstop=8 expandtab textwidth=78:
def reply(self2, s, *args, **kwargs): replies.append(s) def error(self2, s, Raise=False, *args, **kwargs): errors.append(s) if Raise: raise ArgumentError def _callInvalidCommands(self2): errors.append(InvalidCommand(self2.args)) def evalArgs(self2): # We don't want the replies in the nested command to # be stored here. super(ErrorReportingProxy, self2).evalArgs(withClass=self.Proxy) try: ErrorReportingProxy(irc.irc, msg, tokens) except callbacks.ArgumentError as e: pass # TODO: do something with the results if errors: irc.reply('true') else: irc.reply('false') cerror = wrap(cerror, ['something']) Condition = internationalizeDocstring(Conditional) Class = Conditional # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
else: self.registryValue('nicks').add(nick) config.registerNick(nick, password) irc.replySuccess() password = wrap(password, [('checkCapability', 'admin'), 'private', 'nick', 'text']) @internationalizeDocstring def nicks(self, irc, msg, args): """takes no arguments Returns the nicks that this plugin is configured to identify and ghost with. """ L = list(self.registryValue('nicks')) if L: utils.sortBy(ircutils.toLower, L) irc.reply(format('%L', L)) else: irc.reply(_('I\'m not currently configured for any nicks.')) nicks = wrap(nicks, [('checkCapability', 'admin')]) Services = internationalizeDocstring(Services) Class = Services # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
banmaskstyle = conf.supybot.protocols.irc.banmask banmask = banmaskstyle.makeBanmask(prefix) if punishment == 'kick': msg = ircmsgs.kick(channel, nick, reason) irc.queueMsg(msg) elif punishment == 'ban': msg = ircmsgs.ban(channel, banmask) irc.queueMsg(msg) elif punishment == 'kban': msg = ircmsgs.ban(channel, banmask) irc.queueMsg(msg) msg = ircmsgs.kick(channel, nick, reason) irc.queueMsg(msg) elif punishment.startswith('mode'): msg = ircmsgs.mode(channel, punishment[len('mode'):]) irc.queueMsg(msg) elif punishment.startswith('umode'): msg = ircmsgs.mode(channel, (punishment[len('umode'):], nick)) irc.queueMsg(msg) elif punishment.startswith('command '): tokens = callbacks.tokenize(punishment[len('command '):]) self.Proxy(irc, msg, tokens) AttackProtector = internationalizeDocstring(AttackProtector) Class = AttackProtector # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
def hexip(self, irc, msg, args, ip): """<ip> Returns the hexadecimal IP for that IP. """ ret = "" if utils.net.isIPV4(ip): quads = ip.split('.') for quad in quads: i = int(quad) ret += '%02X' % i else: octets = ip.split(':') for octet in octets: if octet: i = int(octet, 16) ret += '%04X' % i else: missing = (8 - len(octets)) * 4 ret += '0' * missing irc.reply(ret) hexip = wrap(hexip, ['ip']) Internet = internationalizeDocstring(Internet) Class = Internet # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
@internationalizeDocstring def vacuum(self, irc, msg, args, channel): """[<channel>|global] Vacuums the database for <channel>. See SQLite vacuum doc here: http://www.sqlite.org/lang_vacuum.html <channel> is only necessary if the message isn't sent in the channel itself. First check if user has the required capability specified in plugin config requireVacuumCapability. """ capability = self.registryValue('requireVacuumCapability') if capability: if not ircdb.checkCapability(msg.prefix, capability): irc.errorNoCapability(capability, Raise=True) db = self.getDb(channel) cursor = db.cursor() cursor.execute("""VACUUM""") db.commit() irc.replySuccess() vacuum = wrap(vacuum, ['channelOrGlobal']) MessageParser = internationalizeDocstring(MessageParser) Class = MessageParser # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
irc.replySuccess() except KeyError: irc.error(_('That nick was not configured with a password.')) return else: self.registryValue('nicks').add(nick) config.registerNick(nick, password) irc.replySuccess() password = wrap(password, [('checkCapability', 'admin'), 'private', 'nick', 'text']) @internationalizeDocstring def nicks(self, irc, msg, args): """takes no arguments Returns the nicks that this plugin is configured to identify and ghost with. """ L = list(self.registryValue('nicks')) if L: utils.sortBy(ircutils.toLower, L) irc.reply(format('%L', L)) else: irc.reply(_('I\'m not currently configured for any nicks.')) nicks = wrap(nicks, [('checkCapability', 'admin')]) Services = internationalizeDocstring(Services) Class = Services # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
_ = self._getFactoid(irc, channel, key) self._checkNotLocked(irc, channel, key) self.db.removeFactoid(channel, key) irc.replySuccess() remove = wrap(remove, ['channeldb', 'user', 'text']) @internationalizeDocstring def random(self, irc, msg, args, channel): """[<channel>] Displays a random factoid (along with its key) from the database. <channel> is only necessary if the message isn't sent in the channel itself. """ results = self.db.randomFactoid(channel) if not results: irc.error(_('No factoids in the database.')) return (fact, key) = results irc.reply(format('Random factoid: %q is %q', key, fact)) random = wrap(random, ['channeldb']) MoobotFactoids = internationalizeDocstring(MoobotFactoids) Class = MoobotFactoids # vim:set shiftwidth=4 softtabstop=8 expandtab textwidth=78:
pass punishment = self.registryValue('%s.punishment' % kind, channel) reason = _('%s flood detected') % kind if punishment == 'kick': msg = ircmsgs.kick(channel, nick, reason) irc.queueMsg(msg) elif punishment == 'ban': msg = ircmsgs.ban(channel, prefix) irc.queueMsg(msg) elif punishment == 'kban': msg = ircmsgs.ban(channel, prefix) irc.queueMsg(msg) msg = ircmsgs.kick(channel, nick, reason) irc.queueMsg(msg) elif punishment.startswith('mode'): msg = ircmsgs.mode(channel, punishment[len('mode'):]) irc.queueMsg(msg) elif punishment.startswith('umode'): msg = ircmsgs.mode(channel, (punishment[len('umode'):], nick)) irc.queueMsg(msg) elif punishment.startswith('command '): tokens = callbacks.tokenize(punishment[len('command '):]) self.Proxy(irc, msg, tokens) AttackProtector = internationalizeDocstring(AttackProtector) Class = AttackProtector # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
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 _formatNote(self, when, whence, note): return _('Sent %s: <%s> %s') % (self._timestamp(when), whence, note) def doJoin(self, irc, msg): if self.registryValue('tellOnJoin'): self.doPrivmsg(irc, msg) Later = internationalizeDocstring(Later) Class = Later # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
s = utils.str.pluralize(s) results.append(format(_('the %L %s'), commands, s)) if nonCommands: results.append(format(_('the %L'), nonCommands)) if results and isAuthor: return format( _('%s wrote the %s plugin and also contributed %L.'), (fullName, cb.name(), results)) elif results and not isAuthor: return format(_('%s contributed %L to the %s plugin.'), fullName, results, cb.name()) elif isAuthor and not results: return _('%s wrote the %s plugin') % (fullName, cb.name()) # XXX Does this ever actually get reached? else: return _('%s has no listed contributions for the %s ' 'plugin.') % (fullName, cb.name()) # First we need to check and see if the requested plugin is loaded module = cb.classModule if not nick: irc.reply(buildPeopleString(module)) else: nick = ircutils.toLower(nick) irc.reply(buildPersonString(module)) contributors = wrap(contributors, ['plugin', additional('nick')]) Plugin = internationalizeDocstring(Plugin) Class = Plugin # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
def info(self, irc, msg, args, repository, plugin): """<repository> <plugin> Displays informations on the <plugin> in the <repository>.""" global repositories if repository not in repositories: irc.error(_("This repository does not exist or is not known by " "this bot.")) elif plugin not in repositories[repository].getPluginList(): irc.error(_("This plugin does not exist in this repository.")) else: info = repositories[repository].getInfo(plugin) if info is None: irc.error(_("No README found for this plugin")) else: if info.startswith("Insert a description of your plugin here"): irc.error(_("This plugin has no description.")) else: info = info.split("\n\n")[0] for line in info.split("\n"): if line != "": irc.reply(line) info = wrap(info, ["something", optional("something")]) PluginDownloader = internationalizeDocstring(PluginDownloader) Class = PluginDownloader # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
class SupyML(callbacks.Plugin): """SupyML is a plugin that read SupyML scripts. This scripts (Supybot Markup Language) are script written in a XML-based language.""" #threaded = True def eval(self, irc, msg, args, optlist, code): """[--warnings] <SupyML script> Executes the <SupyML script>""" parser = SupyMLParser(self, irc, msg, code, self.registryValue('maxnodes') + 2) for item in optlist: if ('warnings', True) == item and len(parser.warnings) != 0: irc.error(' & '.join(parser.warnings)) if parser.rawData is not None: irc.queueMsg(parser.rawData) else: irc.reply(parser.data) eval = wrap(eval, [getopts({'warnings': ''}), 'text']) SupyML = internationalizeDocstring(SupyML) Class = SupyML # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
@internationalizeDocstring def hexip(self, irc, msg, args, ip): """<ip> Returns the hexadecimal IP for that IP. """ ret = "" if utils.net.isIPV4(ip): quads = ip.split('.') for quad in quads: i = int(quad) ret += '%02X' % i else: octets = ip.split(':') for octet in octets: if octet: i = int(octet, 16) ret += '%04X' % i else: missing = (8 - len(octets)) * 4 ret += '0' * missing irc.reply(ret) hexip = wrap(hexip, ['ip']) Internet = internationalizeDocstring(Internet) Class = Internet # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
def say(self, irc, msg, args, target, text): """<channel|nick> <text> Sends <text> to <channel|nick>. Can only send to <nick> if supybot.plugins.Anonymous.allowPrivateTarget is True. """ self._preCheck(irc, msg, target, 'say') self.log.info('Saying %q to %s due to %s.', text, target, msg.prefix) irc.reply(text, to=target, prefixNick=False, private=not ircutils.isChannel(target)) say = wrap(say, [first('nick', 'inChannel'), 'text']) @internationalizeDocstring def do(self, irc, msg, args, channel, text): """<channel> <action> Performs <action> in <channel>. """ self._preCheck(irc, msg, channel, 'do') self.log.info('Performing %q in %s due to %s.', text, channel, msg.prefix) irc.reply(text, action=True, to=channel) do = wrap(do, ['inChannel', 'text']) Anonymous = internationalizeDocstring(Anonymous) Class = Anonymous # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
try: self.__class__ = pluginSelf.originalClass ret = self() finally: self.__class__ = MySuccessClass else: ret = ret.text return ret def get(self, attr): if ircutils.isChannel(attr): pluginSelf.target = attr return self conf.supybot.replies.success.__class__ = MySuccessClass def die(self): self.__parent.die() conf.supybot.replies.success.__class__ = self.originalClass def inFilter(self, irc, msg): # We need the target, but we need it before Owner.doPrivmsg is called, # so this seems like the only way to do it. self.target = msg.args[0] return msg Success = internationalizeDocstring(Success) Class = Success # vim:set shiftwidth=4 softtabstop=8 expandtab textwidth=78:
self.warnings.append('Variable name shouldn\'t contain ' 'special chars (%s)' % variableName) class SupyML(callbacks.Plugin): """SupyML is a plugin that read SupyML scripts. This scripts (Supybot Markup Language) are script written in a XML-based language.""" #threaded = True def eval(self, irc, msg, args, optlist, code): """[--warnings] <SupyML script> Executes the <SupyML script>""" parser = SupyMLParser(self, irc, msg, code, self.registryValue('maxnodes')+2) for item in optlist: if ('warnings', True) == item and len(parser.warnings) != 0: irc.error(' & '.join(parser.warnings)) if parser.rawData is not None: irc.queueMsg(parser.rawData) else: irc.reply(parser.data) eval=wrap(eval, [getopts({'warnings':''}), 'text']) SupyML = internationalizeDocstring(SupyML) Class = SupyML # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: