Merge branch 'i18n' into l10n-fr

This commit is contained in:
Valentin Lorentz 2010-10-20 09:40:07 +02:00
commit 7d0d1ad09a
51 changed files with 2921 additions and 306 deletions

View File

@ -30,6 +30,8 @@
import supybot.conf as conf
import supybot.registry as registry
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('RSS')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -45,37 +47,37 @@ class FeedNames(registry.SpaceSeparatedListOfStrings):
RSS = conf.registerPlugin('RSS')
conf.registerChannelValue(RSS, 'bold', registry.Boolean(
True, """Determines whether the bot will bold the title of the feed when it
announces new news."""))
True, _("""Determines whether the bot will bold the title of the feed when
it announces new news.""")))
conf.registerChannelValue(RSS, 'headlineSeparator',
registry.StringSurroundedBySpaces(' || ', """Determines what string is used
to separate headlines in new feeds."""))
registry.StringSurroundedBySpaces(' || ', _("""Determines what string is
used to separate headlines in new feeds.""")))
conf.registerChannelValue(RSS, 'announcementPrefix',
registry.StringWithSpaceOnRight('New news from ', """Determines what prefix
is prepended (if any) to the new news item announcements made in the
channel."""))
registry.StringWithSpaceOnRight('New news from ', _("""Determines what
prefix is prepended (if any) to the new news item announcements made in the
channel.""")))
conf.registerChannelValue(RSS, 'announce',
registry.SpaceSeparatedSetOfStrings([], """Determines which RSS feeds
registry.SpaceSeparatedSetOfStrings([], _("""Determines which RSS feeds
should be announced in the channel; valid input is a list of strings
(either registered RSS feeds or RSS feed URLs) separated by spaces."""))
(either registered RSS feeds or RSS feed URLs) separated by spaces.""")))
conf.registerGlobalValue(RSS, 'waitPeriod',
registry.PositiveInteger(1800, """Indicates how many seconds the bot will
registry.PositiveInteger(1800, _("""Indicates how many seconds the bot will
wait between retrieving RSS feeds; requests made within this period will
return cached results."""))
return cached results.""")))
conf.registerGlobalValue(RSS, 'feeds',
FeedNames([], """Determines what feeds should be accessible as
commands."""))
FeedNames([], _("""Determines what feeds should be accessible as
commands.""")))
conf.registerChannelValue(RSS, 'showLinks',
registry.Boolean(False, """Determines whether the bot will list the link
registry.Boolean(False, _("""Determines whether the bot will list the link
along with the title of the feed when the rss command is called.
supybot.plugins.RSS.announce.showLinks affects whether links will be
listed when a feed is automatically announced."""))
listed when a feed is automatically announced.""")))
conf.registerGroup(RSS, 'announce')
conf.registerChannelValue(RSS.announce, 'showLinks',
registry.Boolean(False, """Determines whether the bot will list the link
registry.Boolean(False, _("""Determines whether the bot will list the link
along with the title of the feed when a feed is automatically
announced."""))
announced.""")))

164
plugins/RSS/messages.pot Normal file
View File

@ -0,0 +1,164 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-19 19:27+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:50
msgid ""
"Determines whether the bot will bold the title of the feed when it\n"
" announces new news."
msgstr ""
#: config.py:53
msgid ""
"Determines what string is used\n"
" to separate headlines in new feeds."
msgstr ""
#: config.py:56
msgid ""
"Determines what prefix\n"
" is prepended (if any) to the new news item announcements made in the\n"
" channel."
msgstr ""
#: config.py:60
msgid ""
"Determines which RSS feeds\n"
" should be announced in the channel; valid input is a list of strings\n"
" (either registered RSS feeds or RSS feed URLs) separated by spaces."
msgstr ""
#: config.py:64
msgid ""
"Indicates how many seconds the bot will\n"
" wait between retrieving RSS feeds; requests made within this period will\n"
" return cached results."
msgstr ""
#: config.py:68
msgid ""
"Determines what feeds should be accessible as\n"
" commands."
msgstr ""
#: config.py:71
msgid ""
"Determines whether the bot will list the link\n"
" along with the title of the feed when the rss command is called.\n"
" supybot.plugins.RSS.announce.showLinks affects whether links will be\n"
" listed when a feed is automatically announced."
msgstr ""
#: config.py:78
msgid ""
"Determines whether the bot will list the link\n"
" along with the title of the feed when a feed is automatically\n"
" announced."
msgstr ""
#: plugin.py:63
#, docstring
msgid ""
"This plugin is useful both for announcing updates to RSS feeds in a\n"
" channel, and for retrieving the headlines of RSS feeds via command. Use\n"
" the \"add\" command to add feeds to this plugin, and use the \"announce\"\n"
" command to determine what feeds should be announced in a given channel."
msgstr ""
#: plugin.py:311
#, docstring
msgid ""
"<name> <url>\n"
"\n"
" Adds a command to this plugin that will look up the RSS feed at the\n"
" given URL.\n"
" "
msgstr ""
#: plugin.py:322
#, docstring
msgid ""
"<name>\n"
"\n"
" Removes the command for looking up RSS feeds at <name> from\n"
" this plugin.\n"
" "
msgstr ""
#: plugin.py:328
msgid "That's not a valid RSS feed command name."
msgstr ""
#: plugin.py:346
msgid "I am currently not announcing any feeds."
msgstr ""
#: plugin.py:351
#, docstring
msgid ""
"[<channel>] <name|url> [<name|url> ...]\n"
"\n"
" Adds the list of feeds to the current list of announced feeds in\n"
" <channel>. Valid feeds include the names of registered feeds as\n"
" well as URLs for RSS feeds. <channel> is only necessary if the\n"
" message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:369
#, docstring
msgid ""
"[<channel>] <name|url> [<name|url> ...]\n"
"\n"
" Removes the list of feeds from the current list of announced feeds\n"
" in <channel>. Valid feeds include the names of registered feeds as\n"
" well as URLs for RSS feeds. <channel> is only necessary if the\n"
" message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:387
#, docstring
msgid ""
"<url> [<number of headlines>]\n"
"\n"
" Gets the title components of the given RSS feed.\n"
" If <number of headlines> is given, return only that many headlines.\n"
" "
msgstr ""
#: plugin.py:400
msgid "Couldn't get RSS feed."
msgstr ""
#: plugin.py:413
#, docstring
msgid ""
"<url|feed>\n"
"\n"
" Returns information from the given RSS feed, namely the title,\n"
" URL, description, and last update date, if available.\n"
" "
msgstr ""
#: plugin.py:426
msgid "I couldn't retrieve that RSS feed."
msgstr ""
#: plugin.py:439
msgid "Title: %s; URL: %u; Description: %s; Last updated: %s."
msgstr ""

View File

@ -41,6 +41,8 @@ from supybot.commands import *
import supybot.ircutils as ircutils
import supybot.registry as registry
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('RSS')
try:
feedparser = utils.python.universalImport('feedparser', 'local.feedparser')
@ -56,6 +58,7 @@ def getFeedName(irc, msg, args, state):
state.args.append(callbacks.canonicalName(args.pop(0)))
addConverter('feedName', getFeedName)
@internationalizeDocstring
class RSS(callbacks.Plugin):
"""This plugin is useful both for announcing updates to RSS feeds in a
channel, and for retrieving the headlines of RSS feeds via command. Use
@ -280,6 +283,7 @@ class RSS(callbacks.Plugin):
headlines.append((title, None))
return headlines
@internationalizeDocstring
def makeFeedCommand(self, name, url):
docstring = format("""[<number of headlines>]
@ -302,6 +306,7 @@ class RSS(callbacks.Plugin):
self.feedNames[name] = (url, f)
self._registerFeed(name, url)
@internationalizeDocstring
def add(self, irc, msg, args, name, url):
"""<name> <url>
@ -312,6 +317,7 @@ class RSS(callbacks.Plugin):
irc.replySuccess()
add = wrap(add, ['feedName', 'url'])
@internationalizeDocstring
def remove(self, irc, msg, args, name):
"""<name>
@ -319,7 +325,7 @@ class RSS(callbacks.Plugin):
this plugin.
"""
if name not in self.feedNames:
irc.error('That\'s not a valid RSS feed command name.')
irc.error(_('That\'s not a valid RSS feed command name.'))
return
del self.feedNames[name]
conf.supybot.plugins.RSS.feeds().remove(name)
@ -327,6 +333,7 @@ class RSS(callbacks.Plugin):
irc.replySuccess()
remove = wrap(remove, ['feedName'])
@internationalizeDocstring
class announce(callbacks.Commands):
def list(self, irc, msg, args, channel):
"""[<channel>]
@ -336,9 +343,10 @@ class RSS(callbacks.Plugin):
"""
announce = conf.supybot.plugins.RSS.announce
feeds = format('%L', list(announce.get(channel)()))
irc.reply(feeds or 'I am currently not announcing any feeds.')
irc.reply(feeds or _('I am currently not announcing any feeds.'))
list = wrap(list, ['channel',])
@internationalizeDocstring
def add(self, irc, msg, args, channel, feeds):
"""[<channel>] <name|url> [<name|url> ...]
@ -356,6 +364,7 @@ class RSS(callbacks.Plugin):
add = wrap(add, [('checkChannelCapability', 'op'),
many(first('url', 'feedName'))])
@internationalizeDocstring
def remove(self, irc, msg, args, channel, feeds):
"""[<channel>] <name|url> [<name|url> ...]
@ -373,6 +382,7 @@ class RSS(callbacks.Plugin):
remove = wrap(remove, [('checkChannelCapability', 'op'),
many(first('url', 'feedName'))])
@internationalizeDocstring
def rss(self, irc, msg, args, url, n):
"""<url> [<number of headlines>]
@ -387,7 +397,7 @@ class RSS(callbacks.Plugin):
channel = None
headlines = self.getHeadlines(feed)
if not headlines:
irc.error('Couldn\'t get RSS feed.')
irc.error(_('Couldn\'t get RSS feed.'))
return
headlines = self.buildHeadlines(headlines, channel, 'showLinks')
if n:
@ -398,6 +408,7 @@ class RSS(callbacks.Plugin):
irc.replies(headlines, joiner=sep)
rss = wrap(rss, ['url', additional('int')])
@internationalizeDocstring
def info(self, irc, msg, args, url):
"""<url|feed>
@ -412,7 +423,7 @@ class RSS(callbacks.Plugin):
conv = self._getConverter(feed)
info = feed.get('feed')
if not info:
irc.error('I couldn\'t retrieve that RSS feed.')
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:
@ -425,8 +436,8 @@ class RSS(callbacks.Plugin):
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.',
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')])

View File

@ -30,14 +30,16 @@
import supybot.conf as conf
import supybot.ircutils as ircutils
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Relay')
def configure(advanced):
from supybot.questions import output, expect, anything, something, yn
conf.registerPlugin('Relay', True)
if yn('Would you like to relay between any channels?'):
channels = anything('What channels? Separated them by spaces.')
if yn(_('Would you like to relay between any channels?')):
channels = anything(_('What channels? Separated them by spaces.'))
conf.supybot.plugins.Relay.channels.set(channels)
if yn('Would you like to use color to distinguish between nicks?'):
if yn(_('Would you like to use color to distinguish between nicks?')):
conf.supybot.plugins.Relay.color.setValue(True)
output("""Right now there's no way to configure the actual connection to
the server. What you'll need to do when the bot finishes starting up is
@ -54,36 +56,36 @@ class Networks(registry.SpaceSeparatedListOf):
Relay = conf.registerPlugin('Relay')
conf.registerChannelValue(Relay, 'color',
registry.Boolean(False, """Determines whether the bot will color relayed
PRIVMSGs so as to make the messages easier to read."""))
registry.Boolean(False, _("""Determines whether the bot will color relayed
PRIVMSGs so as to make the messages easier to read.""")))
conf.registerChannelValue(Relay, 'topicSync',
registry.Boolean(True, """Determines whether the bot will synchronize
topics between networks in the channels it relays."""))
registry.Boolean(True, _("""Determines whether the bot will synchronize
topics between networks in the channels it relays.""")))
conf.registerChannelValue(Relay, 'hostmasks',
registry.Boolean(False, """Determines whether the bot will relay the
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."""))
or parts.""")))
conf.registerChannelValue(Relay, 'includeNetwork',
registry.Boolean(True, """Determines whether the bot will include the
registry.Boolean(True, _("""Determines whether the bot will include the
network in relayed PRIVMSGs; if you're only relaying between two networks,
it's somewhat redundant, and you may wish to save the space."""))
it's somewhat redundant, and you may wish to save the space.""")))
conf.registerChannelValue(Relay, 'punishOtherRelayBots',
registry.Boolean(False, """Determines whether the bot will detect other
bots relaying and respond by kickbanning them."""))
registry.Boolean(False, _("""Determines whether the bot will detect other
bots relaying and respond by kickbanning them.""")))
conf.registerGlobalValue(Relay, 'channels',
conf.SpaceSeparatedSetOfChannels([], """Determines which channels the bot
will relay in."""))
conf.SpaceSeparatedSetOfChannels([], _("""Determines which channels the bot
will relay in.""")))
conf.registerChannelValue(Relay.channels, 'joinOnAllNetworks',
registry.Boolean(True, """Determines whether the bot
registry.Boolean(True, _("""Determines whether the bot
will always join the channel(s) it relays for on all networks the bot is
connected to."""))
connected to.""")))
conf.registerChannelValue(Relay, 'ignores',
Ignores([], """Determines what hostmasks will not be relayed on a
channel."""))
Ignores([], _("""Determines what hostmasks will not be relayed on a
channel.""")))
conf.registerChannelValue(Relay, 'noticeNonPrivmsgs',
registry.Boolean(False, """Determines whether the bot will used NOTICEs
registry.Boolean(False, _("""Determines whether the bot will used NOTICEs
rather than PRIVMSGs for non-PRIVMSG relay messages (i.e., joins, parts,
nicks, quits, modes, etc.)"""))
nicks, quits, modes, etc.)""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

215
plugins/Relay/messages.pot Normal file
View File

@ -0,0 +1,215 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-19 19:27+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:39
msgid "Would you like to relay between any channels?"
msgstr ""
#: config.py:40
msgid "What channels? Separated them by spaces."
msgstr ""
#: config.py:42
msgid "Would you like to use color to distinguish between nicks?"
msgstr ""
#: config.py:59
msgid ""
"Determines whether the bot will color relayed\n"
" PRIVMSGs so as to make the messages easier to read."
msgstr ""
#: config.py:62
msgid ""
"Determines whether the bot will synchronize\n"
" topics between networks in the channels it relays."
msgstr ""
#: config.py:65
msgid ""
"Determines whether the bot will relay the\n"
" hostmask of the person joining or parting the channel when he or she joins\n"
" or parts."
msgstr ""
#: config.py:69
msgid ""
"Determines whether the bot will include the\n"
" network in relayed PRIVMSGs; if you're only relaying between two networks,\n"
" it's somewhat redundant, and you may wish to save the space."
msgstr ""
#: config.py:73
msgid ""
"Determines whether the bot will detect other\n"
" bots relaying and respond by kickbanning them."
msgstr ""
#: config.py:76
msgid ""
"Determines which channels the bot\n"
" will relay in."
msgstr ""
#: config.py:79
msgid ""
"Determines whether the bot\n"
" will always join the channel(s) it relays for on all networks the bot is\n"
" connected to."
msgstr ""
#: config.py:83
msgid ""
"Determines what hostmasks will not be relayed on a\n"
" channel."
msgstr ""
#: config.py:86
msgid ""
"Determines whether the bot will used NOTICEs\n"
" rather than PRIVMSGs for non-PRIVMSG relay messages (i.e., joins, parts,\n"
" nicks, quits, modes, etc.)"
msgstr ""
#: plugin.py:99
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Starts relaying between the channel <channel> on all networks. If on a\n"
" network the bot isn't in <channel>, he'll join. This commands is\n"
" required even if the bot is in the channel on both networks; he won't\n"
" relay between those channels unless he's told to join both\n"
" channels. If <channel> is not given, starts relaying on the channel\n"
" the message was sent in.\n"
" "
msgstr ""
#: plugin.py:118
#, docstring
msgid ""
"<channel>\n"
"\n"
" Ceases relaying between the channel <channel> on all networks. The bot\n"
" will part from the channel on all networks in which it is on the\n"
" channel.\n"
" "
msgstr ""
#: plugin.py:133
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Returns the nicks of the people in the channel on the various networks\n"
" the bot is connected to. <channel> is only necessary if the message\n"
" isn't sent on the channel itself.\n"
" "
msgstr ""
#: plugin.py:223
msgid "is an op on %L"
msgstr ""
#: plugin.py:225
msgid "is a halfop on %L"
msgstr ""
#: plugin.py:227
msgid "is voiced on %L"
msgstr ""
#: plugin.py:230
msgid "is also on %L"
msgstr ""
#: plugin.py:232
msgid "is on %L"
msgstr ""
#: plugin.py:234
msgid "isn't on any non-secret channels"
msgstr ""
#: plugin.py:241 plugin.py:242 plugin.py:246
msgid "<unknown>"
msgstr ""
#: plugin.py:248
msgid " %s is away: %s."
msgstr ""
#: plugin.py:253
msgid " identified"
msgstr ""
#: plugin.py:258
msgid "%s (%s) has been%s on server %s since %s (idle for %s) and %s.%s"
msgstr ""
#: plugin.py:273
msgid "There is no %s on %s."
msgstr ""
#: plugin.py:342
msgid "You seem to be relaying, punk."
msgstr ""
#: plugin.py:395
msgid "%s%s has joined on %s"
msgstr ""
#: plugin.py:410
msgid "%s%s has left on %s (%s)"
msgstr ""
#: plugin.py:413
msgid "%s%s has left on %s"
msgstr ""
#: plugin.py:423
msgid "mode change by %s on %s: %s"
msgstr ""
#: plugin.py:435
msgid "%s was kicked by %s on %s (%s)"
msgstr ""
#: plugin.py:438
msgid "%s was kicked by %s on %s"
msgstr ""
#: plugin.py:447
msgid "nick change by %s to %s on %s"
msgstr ""
#: plugin.py:477
msgid "topic change by %s on %s: %s"
msgstr ""
#: plugin.py:486
msgid "%s has quit %s (%s)"
msgstr ""
#: plugin.py:488
msgid "%s has quit %s."
msgstr ""
#: plugin.py:498
msgid "disconnected from %s: %s"
msgstr ""

View File

@ -39,6 +39,8 @@ import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
from supybot.utils.structures import MultiSet, TimeoutQueue
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Relay')
class Relay(callbacks.Plugin):
noIgnore = True
@ -92,6 +94,7 @@ class Relay(callbacks.Plugin):
irc.queueMsg(ircmsgs.who(channel))
irc.queueMsg(ircmsgs.names(channel))
@internationalizeDocstring
def join(self, irc, msg, args, channel):
"""[<channel>]
@ -110,6 +113,7 @@ class Relay(callbacks.Plugin):
irc.replySuccess()
join = wrap(join, ['channel', 'admin'])
@internationalizeDocstring
def part(self, irc, msg, args, channel):
"""<channel>
@ -124,6 +128,7 @@ class Relay(callbacks.Plugin):
irc.replySuccess()
part = wrap(part, ['channel', 'admin'])
@internationalizeDocstring
def nicks(self, irc, msg, args, channel):
"""[<channel>]
@ -215,43 +220,43 @@ class Relay(callbacks.Plugin):
normal.append(channel)
L = []
if ops:
L.append(format('is an op on %L', ops))
L.append(format(_('is an op on %L'), ops))
if halfops:
L.append(format('is a halfop on %L', halfups))
L.append(format(_('is a halfop on %L'), halfups))
if voices:
L.append(format('is voiced on %L', voices))
L.append(format(_('is voiced on %L'), voices))
if normal:
if L:
L.append(format('is also on %L', normal))
L.append(format(_('is also on %L'), normal))
else:
L.append(format('is on %L', normal))
L.append(format(_('is on %L'), normal))
else:
L = ['isn\'t on any non-secret channels']
L = [_('isn\'t on any non-secret channels')]
channels = format('%L', L)
if '317' in d:
idle = utils.timeElapsed(d['317'].args[2])
signon = time.strftime(conf.supybot.reply.format.time(),
time.localtime(float(d['317'].args[3])))
else:
idle = '<unknown>'
signon = '<unknown>'
idle = _('<unknown>')
signon = _('<unknown>')
if '312' in d:
server = d['312'].args[2]
else:
server = '<unknown>'
server = _('<unknown>')
if '301' in d:
away = format(' %s is away: %s.', nick, d['301'].args[2])
away = format(_(' %s is away: %s.'), nick, d['301'].args[2])
else:
away = ''
if '320' in d:
if d['320'].args[2]:
identify = ' identified'
identify = _(' identified')
else:
identify = ''
else:
identify = ''
s = format('%s (%s) has been%s on server %s since %s (idle for %s) '
'and %s.%s',
s = format(_('%s (%s) has been%s on server %s since %s (idle for %s) '
'and %s.%s'),
user, hostmask, identify, server, signon, idle,
channels, away)
replyIrc.reply(s)
@ -265,7 +270,7 @@ class Relay(callbacks.Plugin):
return
(replyIrc, replyMsg, d) = self._whois[(irc, loweredNick)]
del self._whois[(irc, loweredNick)]
s = format('There is no %s on %s.', nick, self._getIrcName(irc))
s = format(_('There is no %s on %s.'), nick, self._getIrcName(irc))
replyIrc.reply(s)
do401 = do402
@ -334,7 +339,7 @@ class Relay(callbacks.Plugin):
self.log.info('Punishing %s in %s on %s for relaying.',
who, channel, irc.network)
irc.sendMsg(ircmsgs.ban(channel, who))
kmsg = 'You seem to be relaying, punk.'
kmsg = _('You seem to be relaying, punk.')
irc.sendMsg(ircmsgs.kick(channel, msg.nick, kmsg))
else:
notPunishing(irc, 'not opped')
@ -387,7 +392,7 @@ class Relay(callbacks.Plugin):
hostmask = format(' (%s)', msg.prefix)
else:
hostmask = ''
s = format('%s%s has joined on %s', msg.nick, hostmask, network)
s = format(_('%s%s has joined on %s'), msg.nick, hostmask, network)
m = self._msgmaker(channel, s)
self._sendToOthers(irc, m)
@ -402,10 +407,10 @@ class Relay(callbacks.Plugin):
else:
hostmask = ''
if len(msg.args) > 1:
s = format('%s%s has left on %s (%s)',
s = format(_('%s%s has left on %s (%s)'),
msg.nick, hostmask, network, msg.args[1])
else:
s = format('%s%s has left on %s', msg.nick, hostmask, network)
s = format(_('%s%s has left on %s'), msg.nick, hostmask, network)
m = self._msgmaker(channel, s)
self._sendToOthers(irc, m)
@ -415,7 +420,7 @@ class Relay(callbacks.Plugin):
if channel not in self.registryValue('channels'):
return
network = self._getIrcName(irc)
s = format('mode change by %s on %s: %s',
s = format(_('mode change by %s on %s: %s'),
msg.nick, network, ' '.join(msg.args[1:]))
m = self._msgmaker(channel, s)
self._sendToOthers(irc, m)
@ -427,10 +432,10 @@ class Relay(callbacks.Plugin):
return
network = self._getIrcName(irc)
if len(msg.args) == 3:
s = format('%s was kicked by %s on %s (%s)',
s = format(_('%s was kicked by %s on %s (%s)'),
msg.args[1], msg.nick, network, msg.args[2])
else:
s = format('%s was kicked by %s on %s',
s = format(_('%s was kicked by %s on %s'),
msg.args[1], msg.nick, network)
m = self._msgmaker(channel, s)
self._sendToOthers(irc, m)
@ -439,7 +444,7 @@ class Relay(callbacks.Plugin):
irc = self._getRealIrc(irc)
newNick = msg.args[0]
network = self._getIrcName(irc)
s = format('nick change by %s to %s on %s', msg.nick,newNick,network)
s = format(_('nick change by %s to %s on %s'), msg.nick,newNick,network)
for channel in self.registryValue('channels'):
if channel in irc.state.channels:
if newNick in irc.state.channels[channel].users:
@ -469,7 +474,7 @@ class Relay(callbacks.Plugin):
'can\'t sync topics.',
channel, otherIrc.network)
else:
s = format('topic change by %s on %s: %s',
s = format(_('topic change by %s on %s: %s'),
msg.nick, network, newTopic)
m = self._msgmaker(channel, s)
self._sendToOthers(irc, m)
@ -478,9 +483,9 @@ class Relay(callbacks.Plugin):
irc = self._getRealIrc(irc)
network = self._getIrcName(irc)
if msg.args:
s = format('%s has quit %s (%s)', msg.nick, network, msg.args[0])
s = format(_('%s has quit %s (%s)'), msg.nick, network, msg.args[0])
else:
s = format('%s has quit %s.', msg.nick, network)
s = format(_('%s has quit %s.'), msg.nick, network)
for channel in self.registryValue('channels'):
if channel in self.ircstates[irc].channels:
if msg.nick in self.ircstates[irc].channels[channel].users:
@ -490,7 +495,7 @@ class Relay(callbacks.Plugin):
def doError(self, irc, msg):
irc = self._getRealIrc(irc)
network = self._getIrcName(irc)
s = format('disconnected from %s: %s', network, msg.args[0])
s = format(_('disconnected from %s: %s'), network, msg.args[0])
for channel in self.registryValue('channels'):
m = self._msgmaker(channel, s)
self._sendToOthers(irc, m)

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Reply')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -42,7 +44,7 @@ def configure(advanced):
Reply = conf.registerPlugin('Reply')
# This is where your configuration variables (if any) should go. For example:
# conf.registerGlobalValue(Reply, 'someConfigVariableName',
# registry.Boolean(False, """Help for someConfigVariableName."""))
# registry.Boolean(False, _("""Help for someConfigVariableName.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -0,0 +1,65 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-19 19:27+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: plugin.py:38
#, docstring
msgid ""
"This plugins contains a few commands that construct various types of\n"
" replies. Some bot owners would be wise to not load this plugin because it\n"
" can be easily abused.\n"
" "
msgstr ""
#: plugin.py:44
#, docstring
msgid ""
"<text>\n"
"\n"
" Replies with <text> in private. Use nested commands to your benefit\n"
" here.\n"
" "
msgstr ""
#: plugin.py:54
#, docstring
msgid ""
"<text>\n"
"\n"
" Replies with <text> as an action. use nested commands to your benefit\n"
" here.\n"
" "
msgstr ""
#: plugin.py:67
#, docstring
msgid ""
"<text>\n"
"\n"
" Replies with <text> in a notice. Use nested commands to your benefit\n"
" here. If you want a private notice, nest the private command.\n"
" "
msgstr ""
#: plugin.py:77
#, docstring
msgid ""
"<text>\n"
"\n"
" Replies with <text>. Equivalent to the alias, 'echo $nick: $1'.\n"
" "
msgstr ""

View File

@ -29,13 +29,17 @@
from supybot.commands import *
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Reply')
@internationalizeDocstring
class Reply(callbacks.Plugin):
"""This plugins contains a few commands that construct various types of
replies. Some bot owners would be wise to not load this plugin because it
can be easily abused.
"""
@internationalizeDocstring
def private(self, irc, msg, args, text):
"""<text>
@ -45,6 +49,7 @@ class Reply(callbacks.Plugin):
irc.reply(text, private=True)
private = wrap(private, ['text'])
@internationalizeDocstring
def action(self, irc, msg, args, text):
"""<text>
@ -57,6 +62,7 @@ class Reply(callbacks.Plugin):
raise callbacks.ArgumentError
action = wrap(action, ['text'])
@internationalizeDocstring
def notice(self, irc, msg, args, text):
"""<text>
@ -66,6 +72,7 @@ class Reply(callbacks.Plugin):
irc.reply(text, notice=True)
notice = wrap(notice, ['text'])
@internationalizeDocstring
def reply(self, irc, msg, args, text):
"""<text>

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Scheduler')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -42,7 +44,7 @@ def configure(advanced):
Scheduler = conf.registerPlugin('Scheduler')
# This is where your configuration variables (if any) should go. For example:
# conf.registerGlobalValue(Scheduler, 'someConfigVariableName',
# registry.Boolean(False, """Help for someConfigVariableName."""))
# registry.Boolean(False, _("""Help for someConfigVariableName.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -0,0 +1,81 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-19 19:28+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: plugin.py:47
#, docstring
msgid "Makes a function suitable for scheduling from command."
msgstr ""
#: plugin.py:57
#, docstring
msgid ""
"<seconds> <command>\n"
"\n"
" Schedules the command string <command> to run <seconds> seconds in the\n"
" future. For example, 'scheduler add [seconds 30m] \"echo [cpu]\"' will\n"
" schedule the command \"cpu\" to be sent to the channel the schedule add\n"
" command was given in (with no prefixed nick, a consequence of using\n"
" echo). Do pay attention to the quotes in that example.\n"
" "
msgstr ""
#: plugin.py:69
msgid "Event #%i added."
msgstr ""
#: plugin.py:74
#, docstring
msgid ""
"<id>\n"
"\n"
" Removes the event scheduled with id <id> from the schedule.\n"
" "
msgstr ""
#: plugin.py:88 plugin.py:90
msgid "Invalid event id."
msgstr ""
#: plugin.py:95
#, docstring
msgid ""
"<name> <seconds> <command>\n"
"\n"
" Schedules the command <command> to run every <seconds> seconds,\n"
" starting now (i.e., the command runs now, and every <seconds> seconds\n"
" thereafter). <name> is a name by which the command can be\n"
" unscheduled.\n"
" "
msgstr ""
#: plugin.py:104
msgid "There is already an event with that name, please choose another name."
msgstr ""
#: plugin.py:117
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Lists the currently scheduled events.\n"
" "
msgstr ""
#: plugin.py:128
msgid "There are currently no scheduled commands."
msgstr ""

View File

@ -34,6 +34,8 @@ import supybot.utils as utils
from supybot.commands import *
import supybot.schedule as schedule
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Scheduler')
class Scheduler(callbacks.Plugin):
def __init__(self, irc):
@ -50,6 +52,7 @@ class Scheduler(callbacks.Plugin):
self.Proxy(irc.irc, msg, tokens)
return f
@internationalizeDocstring
def add(self, irc, msg, args, seconds, command):
"""<seconds> <command>
@ -63,9 +66,10 @@ class Scheduler(callbacks.Plugin):
id = schedule.addEvent(f, time.time() + seconds)
f.eventId = id
self.events[str(id)] = command
irc.replySuccess(format('Event #%i added.', id))
irc.replySuccess(format(_('Event #%i added.'), id))
add = wrap(add, ['positiveInt', 'text'])
@internationalizeDocstring
def remove(self, irc, msg, args, id):
"""<id>
@ -81,11 +85,12 @@ class Scheduler(callbacks.Plugin):
schedule.removeEvent(id)
irc.replySuccess()
except KeyError:
irc.error('Invalid event id.')
irc.error(_('Invalid event id.'))
else:
irc.error('Invalid event id.')
irc.error(_('Invalid event id.'))
remove = wrap(remove, ['lowered'])
@internationalizeDocstring
def repeat(self, irc, msg, args, name, seconds, command):
"""<name> <seconds> <command>
@ -96,8 +101,8 @@ class Scheduler(callbacks.Plugin):
"""
name = name.lower()
if name in self.events:
irc.error('There is already an event with that name, please '
'choose another name.', Raise=True)
irc.error(_('There is already an event with that name, please '
'choose another name.'), Raise=True)
self.events[name] = command
f = self._makeCommandFunction(irc, msg, command, remove=False)
id = schedule.addPeriodicEvent(f, seconds, name)
@ -107,6 +112,7 @@ class Scheduler(callbacks.Plugin):
# irc.replySuccess()
repeat = wrap(repeat, ['nonInt', 'positiveInt', 'text'])
@internationalizeDocstring
def list(self, irc, msg, args):
"""takes no arguments
@ -119,7 +125,7 @@ class Scheduler(callbacks.Plugin):
L[i] = format('%s: %q', name, command)
irc.reply(format('%L', L))
else:
irc.reply('There are currently no scheduled commands.')
irc.reply(_('There are currently no scheduled commands.'))
list = wrap(list)

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Seen')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -42,7 +44,7 @@ def configure(advanced):
Seen = conf.registerPlugin('Seen')
# This is where your configuration variables (if any) should go. For example:
# conf.registerGlobalValue(Seen, 'someConfigVariableName',
# registry.Boolean(False, """Help for someConfigVariableName."""))
# registry.Boolean(False, _("""Help for someConfigVariableName.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

118
plugins/Seen/messages.pot Normal file
View File

@ -0,0 +1,118 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 08:52+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: plugin.py:203 plugin.py:284
msgid "%s was last seen in %s %s ago: %s"
msgstr ""
#: plugin.py:210
msgid "%s (%s ago)"
msgstr ""
#: plugin.py:212
msgid "%s could be %L"
msgstr ""
#: plugin.py:212
msgid "or"
msgstr ""
#: plugin.py:214
msgid "I haven't seen anyone matching %s."
msgstr ""
#: plugin.py:216 plugin.py:288
msgid "I have not seen %s."
msgstr ""
#: plugin.py:220
#, docstring
msgid ""
"[<channel>] <nick>\n"
"\n"
" Returns the last time <nick> was seen and what <nick> was last seen\n"
" saying. <channel> is only necessary if the message isn't sent on the\n"
" channel itself.\n"
" "
msgstr ""
#: plugin.py:231
#, docstring
msgid ""
"[<channel>] [--user <name>] [<nick>]\n"
"\n"
" Returns the last time <nick> was seen and what <nick> was last seen\n"
" doing. This includes any form of activity, instead of just PRIVMSGs.\n"
" If <nick> isn't specified, returns the last activity seen in\n"
" <channel>. If --user is specified, looks up name in the user database\n"
" and returns the last time user was active in <channel>. <channel> is\n"
" only necessary if the message isn't sent on the channel itself.\n"
" "
msgstr ""
#: plugin.py:261
msgid "Someone was last seen in %s %s ago: %s"
msgstr ""
#: plugin.py:265
msgid "I have never seen anyone."
msgstr ""
#: plugin.py:269
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Returns the last thing said in <channel>. <channel> is only necessary\n"
" if the message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:292
#, docstring
msgid ""
"[<channel>] <name>\n"
"\n"
" Returns the last time <name> was seen and what <name> was last seen\n"
" saying. This looks up <name> in the user seen database, which means\n"
" that it could be any nick recognized as user <name> that was seen.\n"
" <channel> is only necessary if the message isn't sent in the channel\n"
" itself.\n"
" "
msgstr ""
#: plugin.py:305
#, docstring
msgid ""
"[<channel>] <nick>\n"
"\n"
" Returns the messages since <nick> last left the channel.\n"
" "
msgstr ""
#: plugin.py:312
msgid "You must be in %s to use this command."
msgstr ""
#: plugin.py:333
msgid "I couldn't find in my history of %s messages where %r last left the %s"
msgstr ""
#: plugin.py:342
msgid "Either %s didn't leave, or no messages were sent while %s was gone."
msgstr ""

View File

@ -42,6 +42,8 @@ import supybot.ircmsgs as ircmsgs
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Seen')
class IrcStringAndIntDict(utils.InsensitivePreservingDict):
def key(self, x):
@ -198,21 +200,22 @@ class Seen(callbacks.Plugin):
if len(results) == 1:
(nick, info) = results[0]
(when, said) = info
irc.reply(format('%s was last seen in %s %s ago: %s',
irc.reply(format(_('%s was last seen in %s %s ago: %s'),
nick, channel,
utils.timeElapsed(time.time()-when), said))
elif len(results) > 1:
L = []
for (nick, info) in results:
(when, said) = info
L.append(format('%s (%s ago)', nick,
L.append(format(_('%s (%s ago)'), nick,
utils.timeElapsed(time.time()-when)))
irc.reply(format('%s could be %L', name, (L, 'or')))
irc.reply(format(_('%s could be %L'), name, (L, _('or'))))
else:
irc.reply(format('I haven\'t seen anyone matching %s.', name))
irc.reply(format(_('I haven\'t seen anyone matching %s.'), name))
except KeyError:
irc.reply(format('I have not seen %s.', name))
irc.reply(format(_('I have not seen %s.'), name))
@internationalizeDocstring
def seen(self, irc, msg, args, channel, name):
"""[<channel>] <nick>
@ -223,6 +226,7 @@ class Seen(callbacks.Plugin):
self._seen(irc, channel, name)
seen = wrap(seen, ['channel', 'nick'])
@internationalizeDocstring
def any(self, irc, msg, args, channel, optlist, name):
"""[<channel>] [--user <name>] [<nick>]
@ -254,12 +258,13 @@ class Seen(callbacks.Plugin):
db = self.db
try:
(when, said) = db.seen(channel, '<last>')
irc.reply(format('Someone was last seen in %s %s ago: %s',
irc.reply(format(_('Someone was last seen in %s %s ago: %s'),
channel, utils.timeElapsed(time.time()-when),
said))
except KeyError:
irc.reply('I have never seen anyone.')
irc.reply(_('I have never seen anyone.'))
@internationalizeDocstring
def last(self, irc, msg, args, channel):
"""[<channel>]
@ -276,12 +281,13 @@ class Seen(callbacks.Plugin):
db = self.db
try:
(when, said) = db.seen(channel, user.id)
irc.reply(format('%s was last seen in %s %s ago: %s',
irc.reply(format(_('%s was last seen in %s %s ago: %s'),
user.name, channel,
utils.timeElapsed(time.time()-when), said))
except KeyError:
irc.reply(format('I have not seen %s.', user.name))
irc.reply(format(_('I have not seen %s.'), user.name))
@internationalizeDocstring
def user(self, irc, msg, args, channel, user):
"""[<channel>] <name>
@ -294,6 +300,7 @@ class Seen(callbacks.Plugin):
self._user(irc, channel, user)
user = wrap(user, ['channel', 'otherUser'])
@internationalizeDocstring
def since(self, irc, msg, args, channel, nick):
"""[<channel>] <nick>
@ -302,7 +309,8 @@ class Seen(callbacks.Plugin):
if nick is None:
nick = msg.nick
if nick not in irc.state.channels[channel].users:
irc.error(format('You must be in %s to use this command.', channel))
irc.error(format(_('You must be in %s to use this command.'),
channel))
return
end = None # By default, up until the most recent message.
for (i, m) in utils.seq.renumerate(irc.state.history):
@ -322,8 +330,8 @@ class Seen(callbacks.Plugin):
ircutils.strEqual(m.args[0], channel):
break
else: # I never use this; it only kicks in when the for loop exited normally.
irc.error(format('I couldn\'t find in my history of %s messages '
'where %r last left the %s',
irc.error(format(_('I couldn\'t find in my history of %s messages '
'where %r last left the %s'),
len(irc.state.history), nick, channel))
return
msgs = [m for m in irc.state.history[i:end]
@ -331,8 +339,8 @@ class Seen(callbacks.Plugin):
if msgs:
irc.reply(format('%L', map(ircmsgs.prettyPrint, msgs)))
else:
irc.reply(format('Either %s didn\'t leave, '
'or no messages were sent while %s was gone.', nick, nick))
irc.reply(format(_('Either %s didn\'t leave, '
'or no messages were sent while %s was gone.'), nick, nick))
since = wrap(since, ['channel', additional('nick')])
Class = Seen

View File

@ -31,11 +31,13 @@
import supybot.conf as conf
import supybot.ircutils as ircutils
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Services')
def registerNick(nick, password=''):
p = conf.supybot.plugins.Services.Nickserv.get('password')
h = 'Determines what password the bot will use with NickServ when ' \
'identifying as %s.' % nick
h = _('Determines what password the bot will use with NickServ when ' \
'identifying as %s.') % nick
v = conf.registerGlobalValue(p, nick,
registry.String(password, h, private=True))
if password:
@ -44,10 +46,10 @@ def registerNick(nick, password=''):
def configure(advanced):
from supybot.questions import expect, anything, something, yn, getpass
conf.registerPlugin('Services', True)
nick = something('What is your registered nick?')
password = something('What is your password for that nick?')
chanserv = something('What is your ChanServ named?', default='ChanServ')
nickserv = something('What is your NickServ named?', default='NickServ')
nick = something(_('What is your registered nick?'))
password = something(_('What is your password for that nick?'))
chanserv = something(_('What is your ChanServ named?'), default='ChanServ')
nickserv = something(_('What is your NickServ named?'), default='NickServ')
conf.supybot.plugins.Services.nicks.setValue([nick])
conf.supybot.plugins.Services.NickServ.setValue(nickserv)
registerNick(nick, password)
@ -65,42 +67,42 @@ class ValidNickSet(conf.ValidNicks):
Services = conf.registerPlugin('Services')
conf.registerGlobalValue(Services, 'nicks',
ValidNickSet([], """Determines what nicks the bot will use with
services."""))
ValidNickSet([], _("""Determines what nicks the bot will use with
services.""")))
class Networks(registry.SpaceSeparatedSetOfStrings):
List = ircutils.IrcSet
conf.registerGlobalValue(Services, 'disabledNetworks',
Networks(['QuakeNet'], """Determines what networks this plugin will be
disabled on."""))
Networks(_('QuakeNet').split(), _("""Determines what networks this plugin
will be disabled on.""")))
conf.registerGlobalValue(Services, 'noJoinsUntilIdentified',
registry.Boolean(False, """Determines whether the bot will not join any
registry.Boolean(False, _("""Determines whether the bot will not join any
channels until it is identified. This may be useful, for instances, if
you have a vhost that isn't set until you're identified, or if you're
joining +r channels that won't allow you to join unless you identify."""))
joining +r channels that won't allow you to join unless you identify.""")))
conf.registerGlobalValue(Services, 'ghostDelay',
registry.PositiveInteger(60, """Determines how many seconds the bot will
wait between successive GHOST attempts."""))
registry.PositiveInteger(60, _("""Determines how many seconds the bot will
wait between successive GHOST attempts.""")))
conf.registerGlobalValue(Services, 'NickServ',
ValidNickOrEmptyString('', """Determines what nick the 'NickServ' service
has."""))
ValidNickOrEmptyString('', _("""Determines what nick the 'NickServ' service
has.""")))
conf.registerGroup(Services.NickServ, 'password')
conf.registerGlobalValue(Services, 'ChanServ',
ValidNickOrEmptyString('', """Determines what nick the 'ChanServ' service
has."""))
ValidNickOrEmptyString('', _("""Determines what nick the 'ChanServ' service
has.""")))
conf.registerChannelValue(Services.ChanServ, 'password',
registry.String('', """Determines what password the bot will use with
ChanServ.""", private=True))
registry.String('', _("""Determines what password the bot will use with
ChanServ."""), private=True))
conf.registerChannelValue(Services.ChanServ, 'op',
registry.Boolean(False, """Determines whether the bot will request to get
opped by the ChanServ when it joins the channel."""))
registry.Boolean(False, _("""Determines whether the bot will request to get
opped by the ChanServ when it joins the channel.""")))
conf.registerChannelValue(Services.ChanServ, 'halfop',
registry.Boolean(False, """Determines whether the bot will request to get
half-opped by the ChanServ when it joins the channel."""))
registry.Boolean(False, _("""Determines whether the bot will request to get
half-opped by the ChanServ when it joins the channel.""")))
conf.registerChannelValue(Services.ChanServ, 'voice',
registry.Boolean(False, """Determines whether the bot will request to get
voiced by the ChanServ when it joins the channel."""))
registry.Boolean(False, _("""Determines whether the bot will request to get
voiced by the ChanServ when it joins the channel.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -0,0 +1,235 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 08:55+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:39
msgid "Determines what password the bot will use with NickServ when identifying as %s."
msgstr ""
#: config.py:49
msgid "What is your registered nick?"
msgstr ""
#: config.py:50
msgid "What is your password for that nick?"
msgstr ""
#: config.py:51
msgid "What is your ChanServ named?"
msgstr ""
#: config.py:52
msgid "What is your NickServ named?"
msgstr ""
#: config.py:70
msgid ""
"Determines what nicks the bot will use with\n"
" services."
msgstr ""
#: config.py:77
msgid ""
"Determines what networks this plugin\n"
" will be disabled on."
msgstr ""
#: config.py:77
msgid "QuakeNet"
msgstr ""
#: config.py:81
msgid ""
"Determines whether the bot will not join any\n"
" channels until it is identified. This may be useful, for instances, if\n"
" you have a vhost that isn't set until you're identified, or if you're\n"
" joining +r channels that won't allow you to join unless you identify."
msgstr ""
#: config.py:86
msgid ""
"Determines how many seconds the bot will\n"
" wait between successive GHOST attempts."
msgstr ""
#: config.py:89
msgid ""
"Determines what nick the 'NickServ' service\n"
" has."
msgstr ""
#: config.py:93
msgid ""
"Determines what nick the 'ChanServ' service\n"
" has."
msgstr ""
#: config.py:96
msgid ""
"Determines what password the bot will use with\n"
" ChanServ."
msgstr ""
#: config.py:99
msgid ""
"Determines whether the bot will request to get\n"
" opped by the ChanServ when it joins the channel."
msgstr ""
#: config.py:102
msgid ""
"Determines whether the bot will request to get\n"
" half-opped by the ChanServ when it joins the channel."
msgstr ""
#: config.py:105
msgid ""
"Determines whether the bot will request to get\n"
" voiced by the ChanServ when it joins the channel."
msgstr ""
#: plugin.py:48
#, docstring
msgid ""
"This plugin handles dealing with Services on networks that provide them.\n"
" Basically, you should use the \"password\" command to tell the bot a nick to\n"
" identify with and what password to use to identify with that nick. You can\n"
" use the password command multiple times if your bot has multiple nicks\n"
" registered. Also, be sure to configure the NickServ and ChanServ\n"
" configuration variables to match the NickServ and ChanServ nicks on your\n"
" network. Other commands such as identify, op, etc. should not be\n"
" necessary if the bot is properly configured."
msgstr ""
#: plugin.py:396
msgid "You must set supybot.plugins.Services.ChanServ before I'm able to send the %s command."
msgstr ""
#: plugin.py:402
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Attempts to get opped by ChanServ in <channel>. <channel> is only\n"
" necessary if the message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:408
msgid "I'm already opped in %s."
msgstr ""
#: plugin.py:415
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Attempts to get voiced by ChanServ in <channel>. <channel> is only\n"
" necessary if the message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:421
msgid "I'm already voiced in %s."
msgstr ""
#: plugin.py:438
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Attempts to get unbanned by ChanServ in <channel>. <channel> is only\n"
" necessary if the message isn't sent in the channel itself, but chances\n"
" are, if you need this command, you're not sending it in the channel\n"
" itself.\n"
" "
msgstr ""
#: plugin.py:459
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Attempts to get invited by ChanServ to <channel>. <channel> is only\n"
" necessary if the message isn't sent in the channel itself, but chances\n"
" are, if you need this command, you're not sending it in the channel\n"
" itself.\n"
" "
msgstr ""
#: plugin.py:480
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Identifies with NickServ using the current nick.\n"
" "
msgstr ""
#: plugin.py:489
msgid "I don't have a configured password for my current nick."
msgstr ""
#: plugin.py:492
msgid "You must set supybot.plugins.Services.NickServ before I'm able to do identify."
msgstr ""
#: plugin.py:498
#, docstring
msgid ""
"[<nick>]\n"
"\n"
" Ghosts the bot's given nick and takes it. If no nick is given,\n"
" ghosts the bot's configured nick and takes it.\n"
" "
msgstr ""
#: plugin.py:507
msgid "I cowardly refuse to ghost myself."
msgstr ""
#: plugin.py:512
msgid "You must set supybot.plugins.Services.NickServ before I'm able to ghost a nick."
msgstr ""
#: plugin.py:518
#, docstring
msgid ""
"<nick> [<password>]\n"
"\n"
" Sets the NickServ password for <nick> to <password>. If <password> is\n"
" not given, removes <nick> from the configured nicks.\n"
" "
msgstr ""
#: plugin.py:528
msgid "That nick was not configured with a password."
msgstr ""
#: plugin.py:539
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns the nicks that this plugin is configured to identify and ghost\n"
" with.\n"
" "
msgstr ""
#: plugin.py:549
msgid "I'm not currently configured for any nicks."
msgstr ""

View File

@ -40,7 +40,10 @@ import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils
import supybot.schedule as schedule
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Services')
@internationalizeDocstring
class Services(callbacks.Plugin):
"""This plugin handles dealing with Services on networks that provide them.
Basically, you should use the "password" command to tell the bot a nick to
@ -390,10 +393,11 @@ class Services(callbacks.Plugin):
'supybot.plugins.Services.ChanServ before '
'I can send commands to ChanServ.', command)
else:
irc.error('You must set supybot.plugins.Services.ChanServ '
'before I\'m able to send the %s command.' % command,
irc.error(_('You must set supybot.plugins.Services.ChanServ '
'before I\'m able to send the %s command.') % command,
Raise=True)
@internationalizeDocstring
def op(self, irc, msg, args, channel):
"""[<channel>]
@ -401,11 +405,12 @@ class Services(callbacks.Plugin):
necessary if the message isn't sent in the channel itself.
"""
if irc.nick in irc.state.channels[channel].ops:
irc.error(format('I\'m already opped in %s.', channel))
irc.error(format(_('I\'m already opped in %s.'), channel))
else:
self._chanservCommand(irc, channel, 'op')
op = wrap(op, [('checkChannelCapability', 'op'), 'inChannel'])
@internationalizeDocstring
def voice(self, irc, msg, args, channel):
"""[<channel>]
@ -413,7 +418,7 @@ class Services(callbacks.Plugin):
necessary if the message isn't sent in the channel itself.
"""
if irc.nick in irc.state.channels[channel].voices:
irc.error(format('I\'m already voiced in %s.', channel))
irc.error(format(_('I\'m already voiced in %s.'), channel))
else:
self._chanservCommand(irc, channel, 'voice')
voice = wrap(voice, [('checkChannelCapability', 'op'), 'inChannel'])
@ -428,6 +433,7 @@ class Services(callbacks.Plugin):
self._chanservCommand(irc, channel, 'unban', log=True)
# Success log in doChanservNotice.
@internationalizeDocstring
def unban(self, irc, msg, args, channel):
"""[<channel>]
@ -448,6 +454,7 @@ class Services(callbacks.Plugin):
self.log.info('%s is +i, attempting ChanServ invite %s.', channel, on)
self._chanservCommand(irc, channel, 'invite', log=True)
@internationalizeDocstring
def invite(self, irc, msg, args, channel):
"""[<channel>]
@ -468,6 +475,7 @@ class Services(callbacks.Plugin):
self.log.info('Joining %s, invited by ChanServ %s.', channel, on)
irc.queueMsg(networkGroup.channels.join(channel))
@internationalizeDocstring
def identify(self, irc, msg, args):
"""takes no arguments
@ -478,13 +486,14 @@ class Services(callbacks.Plugin):
self._doIdentify(irc, irc.nick)
irc.replySuccess()
else:
irc.error('I don\'t have a configured password for '
'my current nick.')
irc.error(_('I don\'t have a configured password for '
'my current nick.'))
else:
irc.error('You must set supybot.plugins.Services.NickServ before '
'I\'m able to do identify.')
irc.error(_('You must set supybot.plugins.Services.NickServ before '
'I\'m able to do identify.'))
identify = wrap(identify, [('checkCapability', 'admin')])
@internationalizeDocstring
def ghost(self, irc, msg, args, nick):
"""[<nick>]
@ -495,15 +504,16 @@ class Services(callbacks.Plugin):
if not nick:
nick = self._getNick()
if ircutils.strEqual(nick, irc.nick):
irc.error('I cowardly refuse to ghost myself.')
irc.error(_('I cowardly refuse to ghost myself.'))
else:
self._doGhost(irc, nick=nick)
irc.replySuccess()
else:
irc.error('You must set supybot.plugins.Services.NickServ before '
'I\'m able to ghost a nick.')
irc.error(_('You must set supybot.plugins.Services.NickServ before '
'I\'m able to ghost a nick.'))
ghost = wrap(ghost, [('checkCapability', 'admin'), additional('nick')])
@internationalizeDocstring
def password(self, irc, msg, args, nick, password):
"""<nick> [<password>]
@ -515,7 +525,7 @@ class Services(callbacks.Plugin):
self.registryValue('nicks').remove(nick)
irc.replySuccess()
except KeyError:
irc.error('That nick was not configured with a password.')
irc.error(_('That nick was not configured with a password.'))
return
else:
self.registryValue('nicks').add(nick)
@ -524,6 +534,7 @@ class Services(callbacks.Plugin):
password = wrap(password, [('checkCapability', 'admin'),
'private', 'nick', 'text'])
@internationalizeDocstring
def nicks(self, irc, msg, args):
"""takes no arguments
@ -535,7 +546,7 @@ class Services(callbacks.Plugin):
utils.sortBy(ircutils.toLower, L)
irc.reply(format('%L', L))
else:
irc.reply('I\'m not currently configured for any nicks.')
irc.reply(_('I\'m not currently configured for any nicks.'))
nicks = wrap(nicks, [('checkCapability', 'admin')])

View File

@ -30,13 +30,15 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('ShrinkUrl')
def configure(advanced):
from supybot.questions import output, expect, anything, something, yn
conf.registerPlugin('ShrinkUrl', True)
if yn("""This plugin offers a snarfer that will go retrieve a shorter
if yn(_("""This plugin offers a snarfer that will go retrieve a shorter
version of long URLs that are sent to the channel. Would you
like this snarfer to be enabled?""", default=False):
like this snarfer to be enabled?"""), default=False):
conf.supybot.plugins.ShrinkUrl.shrinkSnarfer.setValue(True)
class ShrinkService(registry.OnlySomeStrings):
@ -66,34 +68,34 @@ class ShrinkCycle(registry.SpaceSeparatedListOfStrings):
ShrinkUrl = conf.registerPlugin('ShrinkUrl')
conf.registerChannelValue(ShrinkUrl, 'shrinkSnarfer',
registry.Boolean(False, """Determines whether the
registry.Boolean(False, _("""Determines whether the
shrink snarfer is enabled. This snarfer will watch for URLs in the
channel, and if they're sufficiently long (as determined by
supybot.plugins.ShrinkUrl.minimumLength) it will post a
smaller URL from either ln-s.net or tinyurl.com, as denoted in
supybot.plugins.ShrinkUrl.default."""))
supybot.plugins.ShrinkUrl.default.""")))
conf.registerChannelValue(ShrinkUrl.shrinkSnarfer, 'showDomain',
registry.Boolean(True, """Determines whether the snarfer will show the
domain of the URL being snarfed along with the shrunken URL."""))
registry.Boolean(True, _("""Determines whether the snarfer will show the
domain of the URL being snarfed along with the shrunken URL.""")))
conf.registerChannelValue(ShrinkUrl, 'minimumLength',
registry.PositiveInteger(48, """The minimum length a URL must be before
the bot will shrink it."""))
registry.PositiveInteger(48, _("""The minimum length a URL must be before
the bot will shrink it.""")))
conf.registerChannelValue(ShrinkUrl, 'nonSnarfingRegexp',
registry.Regexp(None, """Determines what URLs are to be snarfed; URLs
registry.Regexp(None, _("""Determines what URLs are to be snarfed; URLs
matching the regexp given will not be snarfed. Give the empty string if
you have no URLs that you'd like to exclude from being snarfed."""))
you have no URLs that you'd like to exclude from being snarfed.""")))
conf.registerChannelValue(ShrinkUrl, 'outFilter',
registry.Boolean(False, """Determines whether the bot will shrink the URLs
of outgoing messages if those URLs are longer than
supybot.plugins.ShrinkUrl.minimumLength."""))
registry.Boolean(False, _("""Determines whether the bot will shrink the
URLs of outgoing messages if those URLs are longer than
supybot.plugins.ShrinkUrl.minimumLength.""")))
conf.registerChannelValue(ShrinkUrl, 'default',
ShrinkService('ln', """Determines what website the bot will use when
shrinking a URL."""))
ShrinkService('ln', _("""Determines what website the bot will use when
shrinking a URL.""")))
conf.registerGlobalValue(ShrinkUrl, 'bold',
registry.Boolean(True, """Determines whether this plugin will bold certain
portions of its replies."""))
registry.Boolean(True, _("""Determines whether this plugin will bold
certain portions of its replies.""")))
conf.registerChannelValue(ShrinkUrl, 'serviceRotation',
ShrinkCycle([], """If set to a non-empty value, specifies the list of
services to rotate through for the shrinkSnarfer and outFilter."""))
ShrinkCycle([], _("""If set to a non-empty value, specifies the list of
services to rotate through for the shrinkSnarfer and outFilter.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -0,0 +1,119 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 08:55+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:39
msgid ""
"This plugin offers a snarfer that will go retrieve a shorter\n"
" version of long URLs that are sent to the channel. Would you\n"
" like this snarfer to be enabled?"
msgstr ""
#: config.py:45 config.py:49
#, docstring
msgid "Valid values include 'ln', 'tiny', 'xrl', and 'x0'."
msgstr ""
#: config.py:71
msgid ""
"Determines whether the\n"
" shrink snarfer is enabled. This snarfer will watch for URLs in the\n"
" channel, and if they're sufficiently long (as determined by\n"
" supybot.plugins.ShrinkUrl.minimumLength) it will post a\n"
" smaller URL from either ln-s.net or tinyurl.com, as denoted in\n"
" supybot.plugins.ShrinkUrl.default."
msgstr ""
#: config.py:78
msgid ""
"Determines whether the snarfer will show the\n"
" domain of the URL being snarfed along with the shrunken URL."
msgstr ""
#: config.py:81
msgid ""
"The minimum length a URL must be before\n"
" the bot will shrink it."
msgstr ""
#: config.py:84
msgid ""
"Determines what URLs are to be snarfed; URLs\n"
" matching the regexp given will not be snarfed. Give the empty string if\n"
" you have no URLs that you'd like to exclude from being snarfed."
msgstr ""
#: config.py:88
msgid ""
"Determines whether the bot will shrink the\n"
" URLs of outgoing messages if those URLs are longer than\n"
" supybot.plugins.ShrinkUrl.minimumLength."
msgstr ""
#: config.py:92
msgid ""
"Determines what website the bot will use when\n"
" shrinking a URL."
msgstr ""
#: config.py:95
msgid ""
"Determines whether this plugin will bold\n"
" certain portions of its replies."
msgstr ""
#: config.py:98
msgid ""
"If set to a non-empty value, specifies the list of\n"
" services to rotate through for the shrinkSnarfer and outFilter."
msgstr ""
#: plugin.py:169
#, docstring
msgid ""
"<url>\n"
"\n"
" Returns an ln-s.net version of <url>.\n"
" "
msgstr ""
#: plugin.py:194
#, docstring
msgid ""
"<url>\n"
"\n"
" Returns a TinyURL.com version of <url>\n"
" "
msgstr ""
#: plugin.py:222
#, docstring
msgid ""
"<url>\n"
"\n"
" Returns an xrl.us version of <url>.\n"
" "
msgstr ""
#: plugin.py:248
#, docstring
msgid ""
"<url>\n"
"\n"
" Returns an x0.no version of <url>.\n"
" "
msgstr ""

View File

@ -37,6 +37,8 @@ import supybot.ircmsgs as ircmsgs
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('ShrinkUrl')
class CdbShrunkenUrlDB(object):
def __init__(self, filename):
@ -162,6 +164,7 @@ class ShrinkUrl(callbacks.PluginRegexp):
else:
raise ShrinkError, text
@internationalizeDocstring
def ln(self, irc, msg, args, url):
"""<url>
@ -186,6 +189,7 @@ class ShrinkUrl(callbacks.PluginRegexp):
self.db.set('tiny', url, text)
return text
@internationalizeDocstring
def tiny(self, irc, msg, args, url):
"""<url>
@ -213,6 +217,7 @@ class ShrinkUrl(callbacks.PluginRegexp):
self.db.set('xrl', quotedurl, text)
return text
@internationalizeDocstring
def xrl(self, irc, msg, args, url):
"""<url>
@ -238,6 +243,7 @@ class ShrinkUrl(callbacks.PluginRegexp):
self.db.set('x0', url, text)
return text
@internationalizeDocstring
def x0(self, irc, msg, args, url):
"""<url>

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Status')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -41,13 +43,13 @@ def configure(advanced):
Status = conf.registerPlugin('Status')
conf.registerGroup(Status, 'cpu')
conf.registerChannelValue(Status.cpu, 'children',
registry.Boolean(True, """Determines whether the cpu command will list the
time taken by children as well as the bot's process."""))
registry.Boolean(True, _("""Determines whether the cpu command will list
the time taken by children as well as the bot's process.""")))
conf.registerChannelValue(Status.cpu, 'threads',
registry.Boolean(False, """Determines whether the cpu command will provide
the number of threads spawned and active."""))
registry.Boolean(False, _("""Determines whether the cpu command will
provide the number of threads spawned and active.""")))
conf.registerChannelValue(Status.cpu, 'memory',
registry.Boolean(True, """Determines whether the cpu command will report
the amount of memory being used by the bot."""))
registry.Boolean(True, _("""Determines whether the cpu command will report
the amount of memory being used by the bot.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

155
plugins/Status/messages.pot Normal file
View File

@ -0,0 +1,155 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 09:05+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:46
msgid ""
"Determines whether the cpu command will list\n"
" the time taken by children as well as the bot's process."
msgstr ""
#: config.py:49
msgid ""
"Determines whether the cpu command will\n"
" provide the number of threads spawned and active."
msgstr ""
#: config.py:52
msgid ""
"Determines whether the cpu command will report\n"
" the amount of memory being used by the bot."
msgstr ""
#: plugin.py:71
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns the status of the bot.\n"
" "
msgstr ""
#: plugin.py:80
msgid "%s as %L"
msgstr ""
#: plugin.py:81
msgid "I am connected to %L."
msgstr ""
#: plugin.py:83
msgid "I am currently in code profiling mode."
msgstr ""
#: plugin.py:89
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns the current threads that are active.\n"
" "
msgstr ""
#: plugin.py:95
msgid "I have spawned %n; %n %b still currently active: %L."
msgstr ""
#: plugin.py:103
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns some interesting network-related statistics.\n"
" "
msgstr ""
#: plugin.py:111
msgid "an indeterminate amount of time"
msgstr ""
#: plugin.py:112
msgid "I have received %s messages for a total of %s bytes. I have sent %s messages for a total of %s bytes. I have been connected to %s for %s."
msgstr ""
#: plugin.py:121
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns some interesting CPU-related statistics on the bot.\n"
" "
msgstr ""
#: plugin.py:131
msgid "My children have taken %.2f seconds of user time and %.2f seconds of system time for a total of %.2f seconds of CPU time. "
msgstr ""
#: plugin.py:138
msgid "I have taken %.2f seconds of user time and %.2f seconds of system time, for a total of %.2f seconds of CPU time. %s"
msgstr ""
#: plugin.py:160
msgid "Unable to run ps command."
msgstr ""
#: plugin.py:166
msgid " I'm taking up %s kB of memory."
msgstr ""
#: plugin.py:174
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns some interesting command-related statistics.\n"
" "
msgstr ""
#: plugin.py:184
msgid "I offer a total of %n in %n. I have processed %n."
msgstr ""
#: plugin.py:193
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns a list of the commands offered by the bot.\n"
" "
msgstr ""
#: plugin.py:207
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns the amount of time the bot has been running.\n"
" "
msgstr ""
#: plugin.py:211
msgid "I have been running for %s."
msgstr ""
#: plugin.py:218
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns the server the bot is on.\n"
" "
msgstr ""

View File

@ -39,6 +39,8 @@ import supybot.utils as utils
import supybot.world as world
from supybot.commands import *
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Status')
class Status(callbacks.Plugin):
def __init__(self, irc):
@ -64,6 +66,7 @@ class Status(callbacks.Plugin):
def do001(self, irc, msg):
self.connected[irc] = time.time()
@internationalizeDocstring
def status(self, irc, msg, args):
"""takes no arguments
@ -74,13 +77,14 @@ class Status(callbacks.Plugin):
networks.setdefault(Irc.network, []).append(Irc.nick)
networks = networks.items()
networks.sort()
networks = [format('%s as %L', net, nicks) for (net,nicks) in networks]
L = [format('I am connected to %L.', networks)]
networks = [format(_('%s as %L'), net, nicks) for (net,nicks) in networks]
L = [format(_('I am connected to %L.'), networks)]
if world.profiling:
L.append('I am currently in code profiling mode.')
L.append(_('I am currently in code profiling mode.'))
irc.reply(' '.join(L))
status = wrap(status)
@internationalizeDocstring
def threads(self, irc, msg, args):
"""takes no arguments
@ -88,12 +92,13 @@ class Status(callbacks.Plugin):
"""
threads = [t.getName() for t in threading.enumerate()]
threads.sort()
s = format('I have spawned %n; %n %b still currently active: %L.',
s = format(_('I have spawned %n; %n %b still currently active: %L.'),
(world.threadsSpawned, 'thread'),
(len(threads), 'thread'), len(threads), threads)
irc.reply(s)
threads = wrap(threads)
@internationalizeDocstring
def net(self, irc, msg, args):
"""takes no arguments
@ -103,14 +108,15 @@ class Status(callbacks.Plugin):
elapsed = time.time() - self.connected[irc.getRealIrc()]
timeElapsed = utils.timeElapsed(elapsed)
except KeyError:
timeElapsed = 'an indeterminate amount of time'
irc.reply('I have received %s messages for a total of %s bytes. '
timeElapsed = _('an indeterminate amount of time')
irc.reply(_('I have received %s messages for a total of %s bytes. '
'I have sent %s messages for a total of %s bytes. '
'I have been connected to %s for %s.' %
'I have been connected to %s for %s.') %
(self.recvdMsgs, self.recvdBytes,
self.sentMsgs, self.sentBytes, irc.server, timeElapsed))
net = wrap(net)
@internationalizeDocstring
def cpu(self, irc, msg, args):
"""takes no arguments
@ -122,16 +128,16 @@ class Status(callbacks.Plugin):
timeRunning = now - world.startedAt
if self.registryValue('cpu.children', target) and \
user+system < timeRunning+1: # Fudge for FPU inaccuracies.
children = 'My children have taken %.2f seconds of user time ' \
'and %.2f seconds of system time ' \
'for a total of %.2f seconds of CPU time. ' % \
children = _('My children have taken %.2f seconds of user time '
'and %.2f seconds of system time '
'for a total of %.2f seconds of CPU time. ') % \
(childUser, childSystem, childUser+childSystem)
else:
children = ''
activeThreads = threading.activeCount()
response = 'I have taken %.2f seconds of user time and %.2f seconds ' \
'of system time, for a total of %.2f seconds of CPU ' \
'time. %s' % (user, system, user + system, children)
response = _('I have taken %.2f seconds of user time and %.2f seconds '
'of system time, for a total of %.2f seconds of CPU '
'time. %s') % (user, system, user + system, children)
if self.registryValue('cpu.threads', target):
response += format('I have spawned %n; I currently have %i still '
'running.',
@ -151,18 +157,19 @@ class Status(callbacks.Plugin):
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except OSError:
irc.error('Unable to run ps command.', Raise=True)
(out, _) = inst.communicate()
irc.error(_('Unable to run ps command.'), Raise=True)
(out, foo) = inst.communicate()
inst.wait()
mem = out.splitlines()[1]
elif sys.platform.startswith('netbsd'):
mem = '%s kB' % os.stat('/proc/%s/mem' % pid)[7]
response += ' I\'m taking up %s kB of memory.' % mem
response += _(' I\'m taking up %s kB of memory.') % mem
except Exception:
self.log.exception('Uncaught exception in cpu.memory:')
irc.reply(utils.str.normalizeWhitespace(response))
cpu = wrap(cpu)
@internationalizeDocstring
def cmd(self, irc, msg, args):
"""takes no arguments
@ -174,13 +181,14 @@ class Status(callbacks.Plugin):
if isinstance(cb, callbacks.Plugin):
callbacksPlugin += 1
commands += len(cb.listCommands())
s = format('I offer a total of %n in %n. I have processed %n.',
s = format(_('I offer a total of %n in %n. I have processed %n.'),
(commands, 'command'),
(callbacksPlugin, 'command-based', 'plugin'),
(world.commandsProcessed, 'command'))
irc.reply(s)
cmd = wrap(cmd)
@internationalizeDocstring
def commands(self, irc, msg, args):
"""takes no arguments
@ -194,16 +202,18 @@ class Status(callbacks.Plugin):
irc.reply(format('%L', sorted(commands)))
commands = wrap(commands)
@internationalizeDocstring
def uptime(self, irc, msg, args):
"""takes no arguments
Returns the amount of time the bot has been running.
"""
response = 'I have been running for %s.' % \
response = _('I have been running for %s.') % \
utils.timeElapsed(time.time() - world.startedAt)
irc.reply(response)
uptime = wrap(uptime)
@internationalizeDocstring
def server(self, irc, msg, args):
"""takes no arguments

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('String')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -42,13 +44,13 @@ def configure(advanced):
String = conf.registerPlugin('String')
conf.registerGroup(String, 'levenshtein')
conf.registerGlobalValue(String.levenshtein, 'max',
registry.PositiveInteger(256, """Determines the maximum size of a string
registry.PositiveInteger(256, _("""Determines the maximum size of a string
given to the levenshtein command. The levenshtein command uses an O(m*n)
algorithm, which means that with strings of length 256, it can take 1.5
seconds to finish; with strings of length 384, though, it can take 4
seconds to finish, and with strings of much larger lengths, it takes more
and more time. Using nested commands, strings can get quite large, hence
this variable, to limit the size of arguments passed to the levenshtein
command."""))
command.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

168
plugins/String/messages.pot Normal file
View File

@ -0,0 +1,168 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 09:08+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:47
msgid ""
"Determines the maximum size of a string\n"
" given to the levenshtein command. The levenshtein command uses an O(m*n)\n"
" algorithm, which means that with strings of length 256, it can take 1.5\n"
" seconds to finish; with strings of length 384, though, it can take 4\n"
" seconds to finish, and with strings of much larger lengths, it takes more\n"
" and more time. Using nested commands, strings can get quite large, hence\n"
" this variable, to limit the size of arguments passed to the levenshtein\n"
" command."
msgstr ""
#: plugin.py:46
#, docstring
msgid ""
"<letter>\n"
"\n"
" Returns the 8-bit value of <letter>.\n"
" "
msgstr ""
#: plugin.py:55
#, docstring
msgid ""
"<number>\n"
"\n"
" Returns the character associated with the 8-bit value <number>\n"
" "
msgstr ""
#: plugin.py:62
msgid "That number doesn't map to an 8-bit character."
msgstr ""
#: plugin.py:67
#, docstring
msgid ""
"<encoding> <text>\n"
"\n"
" Returns an encoded form of the given text; the valid encodings are\n"
" available in the documentation of the Python codecs module:\n"
" <http://docs.python.org/library/codecs.html#standard-encodings>.\n"
" "
msgstr ""
#: plugin.py:76 plugin.py:90
msgid "encoding"
msgstr ""
#: plugin.py:81
#, docstring
msgid ""
"<encoding> <text>\n"
"\n"
" Returns an un-encoded form of the given text; the valid encodings are\n"
" available in the documentation of the Python codecs module:\n"
" <http://docs.python.org/library/codecs.html#standard-encodings>.\n"
" "
msgstr ""
#: plugin.py:92
msgid "base64 string"
msgstr ""
#: plugin.py:93
msgid "Base64 strings must be a multiple of 4 in length, padded with '=' if necessary."
msgstr ""
#: plugin.py:99
#, docstring
msgid ""
"<string1> <string2>\n"
"\n"
" Returns the levenshtein distance (also known as the \"edit distance\"\n"
" between <string1> and <string2>)\n"
" "
msgstr ""
#: plugin.py:106
msgid "Levenshtein distance is a complicated algorithm, try it with some smaller inputs."
msgstr ""
#: plugin.py:114
#, docstring
msgid ""
"<string> [<length>]\n"
"\n"
" Returns the Soundex hash to a given length. The length defaults to\n"
" 4, since that's the standard length for a soundex hash. For unlimited\n"
" length, use 0.\n"
" "
msgstr ""
#: plugin.py:125
#, docstring
msgid ""
"<text>\n"
"\n"
" Returns the length of <text>.\n"
" "
msgstr ""
#: plugin.py:134
#, docstring
msgid ""
"<regexp> <text>\n"
"\n"
" If <regexp> is of the form m/regexp/flags, returns the portion of\n"
" <text> that matches the regexp. If <regexp> is of the form\n"
" s/regexp/replacement/flags, returns the result of applying such a\n"
" regexp to <text>.\n"
" "
msgstr ""
#: plugin.py:146
msgid "You probably don't want to match the empty string."
msgstr ""
#: plugin.py:156
#, docstring
msgid ""
"<password> <text>\n"
"\n"
" Returns <text> XOR-encrypted with <password>. See\n"
" http://www.yoe.org/developer/xor.html for information about XOR\n"
" encryption.\n"
" "
msgstr ""
#: plugin.py:169
#, docstring
msgid ""
"<text>\n"
"\n"
" Returns the md5 hash of a given string. Read\n"
" http://www.rsasecurity.com/rsalabs/faq/3-6-6.html for more information\n"
" about md5.\n"
" "
msgstr ""
#: plugin.py:180
#, docstring
msgid ""
"<text>\n"
"\n"
" Returns the SHA hash of a given string. Read\n"
" http://www.secure-hash-algorithm-md5-sha-1.co.uk/ for more information\n"
" about SHA.\n"
" "
msgstr ""

View File

@ -36,9 +36,12 @@ from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('String')
class String(callbacks.Plugin):
@internationalizeDocstring
def ord(self, irc, msg, args, letter):
"""<letter>
@ -47,6 +50,7 @@ class String(callbacks.Plugin):
irc.reply(str(ord(letter)))
ord = wrap(ord, ['letter'])
@internationalizeDocstring
def chr(self, irc, msg, args, i):
"""<number>
@ -55,9 +59,10 @@ class String(callbacks.Plugin):
try:
irc.reply(chr(i))
except ValueError:
irc.error('That number doesn\'t map to an 8-bit character.')
irc.error(_('That number doesn\'t map to an 8-bit character.'))
chr = wrap(chr, ['int'])
@internationalizeDocstring
def encode(self, irc, msg, args, encoding, text):
"""<encoding> <text>
@ -68,9 +73,10 @@ class String(callbacks.Plugin):
try:
irc.reply(text.encode(encoding).rstrip('\n'))
except LookupError:
irc.errorInvalid('encoding', encoding)
irc.errorInvalid(_('encoding'), encoding)
encode = wrap(encode, ['something', 'text'])
@internationalizeDocstring
def decode(self, irc, msg, args, encoding, text):
"""<encoding> <text>
@ -81,13 +87,14 @@ class String(callbacks.Plugin):
try:
irc.reply(text.decode(encoding).encode('utf-8'))
except LookupError:
irc.errorInvalid('encoding', encoding)
irc.errorInvalid(_('encoding'), encoding)
except binascii.Error:
irc.errorInvalid('base64 string',
s='Base64 strings must be a multiple of 4 in '
'length, padded with \'=\' if necessary.')
irc.errorInvalid(_('base64 string'),
s=_('Base64 strings must be a multiple of 4 in '
'length, padded with \'=\' if necessary.'))
decode = wrap(decode, ['something', 'text'])
@internationalizeDocstring
def levenshtein(self, irc, msg, args, s1, s2):
"""<string1> <string2>
@ -96,12 +103,13 @@ class String(callbacks.Plugin):
"""
max = self.registryValue('levenshtein.max')
if len(s1) > max or len(s2) > max:
irc.error('Levenshtein distance is a complicated algorithm, try '
'it with some smaller inputs.')
irc.error(_('Levenshtein distance is a complicated algorithm, try '
'it with some smaller inputs.'))
else:
irc.reply(str(utils.str.distance(s1, s2)))
levenshtein = wrap(levenshtein, ['something', 'text'])
@internationalizeDocstring
def soundex(self, irc, msg, args, text, length):
"""<string> [<length>]
@ -112,6 +120,7 @@ class String(callbacks.Plugin):
irc.reply(utils.str.soundex(text, length))
soundex = wrap(soundex, ['somethingWithoutSpaces', additional('int', 4)])
@internationalizeDocstring
def len(self, irc, msg, args, text):
"""<text>
@ -120,6 +129,7 @@ class String(callbacks.Plugin):
irc.reply(str(len(text)))
len = wrap(len, ['text'])
@internationalizeDocstring
def re(self, irc, msg, args, ff, text):
"""<regexp> <text>
@ -133,7 +143,7 @@ class String(callbacks.Plugin):
else:
f = lambda s: ff.search(s) and ff.search(s).group(0) or ''
if f('') and len(f(' ')) > len(f(''))+1: # Matches the empty string.
s = 'You probably don\'t want to match the empty string.'
s = _('You probably don\'t want to match the empty string.')
irc.error(s)
else:
irc.reply(f(text))
@ -141,6 +151,7 @@ class String(callbacks.Plugin):
first('regexpMatcher', 'regexpReplacer'),
'text'])
@internationalizeDocstring
def xor(self, irc, msg, args, password, text):
"""<password> <text>
@ -153,6 +164,7 @@ class String(callbacks.Plugin):
irc.reply(''.join(ret))
xor = wrap(xor, ['something', 'text'])
@internationalizeDocstring
def md5(self, irc, msg, args, text):
"""<text>
@ -163,6 +175,7 @@ class String(callbacks.Plugin):
irc.reply(utils.crypt.md5(text).hexdigest())
md5 = wrap(md5, ['text'])
@internationalizeDocstring
def sha(self, irc, msg, args, text):
"""<text>

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Success')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -42,10 +44,10 @@ def configure(advanced):
Success = conf.registerPlugin('Success')
# This is where your configuration variables (if any) should go. For example:
# conf.registerGlobalValue(Success, 'someConfigVariableName',
# registry.Boolean(False, """Help for someConfigVariableName."""))
# registry.Boolean(False, _("""Help for someConfigVariableName.""")))
conf.registerChannelValue(conf.supybot.plugins.Success, 'prefixNick',
registry.Boolean(True, """Determines whether the bot will prefix the nick
of the user giving an invalid command to the success response."""))
registry.Boolean(True, _("""Determines whether the bot will prefix the nick
of the user giving an invalid command to the success response.""")))
# vim:set shiftwidth=4 softtabstop=8 expandtab textwidth=78

View File

@ -0,0 +1,33 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 09:09+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:49
msgid ""
"Determines whether the bot will prefix the nick\n"
" of the user giving an invalid command to the success response."
msgstr ""
#: plugin.py:39
#, docstring
msgid ""
"This plugin was written initially to work with MoobotFactoids, the two\n"
" of them to provide a similar-to-moobot-and-blootbot interface for factoids.\n"
" Basically, it replaces the standard 'The operation succeeded.' messages\n"
" with messages kept in a database, able to give more personable\n"
" responses."
msgstr ""

View File

@ -31,7 +31,10 @@ import supybot.conf as conf
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Success')
@internationalizeDocstring
class Success(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.

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Time')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -40,10 +42,10 @@ def configure(advanced):
Time = conf.registerPlugin('Time')
conf.registerChannelValue(Time, 'format',
registry.String(str(conf.supybot.reply.format.time()), """Determines the
registry.String(str(conf.supybot.reply.format.time()), _("""Determines the
format string for timestamps. Refer to the Python documentation for the
time module to see what formats are accepted. If you set this variable to
the empty string, the timestamp will not be shown."""))
the empty string, the timestamp will not be shown.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

97
plugins/Time/messages.pot Normal file
View File

@ -0,0 +1,97 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 09:38+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:45
msgid ""
"Determines the\n"
" format string for timestamps. Refer to the Python documentation for the\n"
" time module to see what formats are accepted. If you set this variable to\n"
" the empty string, the timestamp will not be shown."
msgstr ""
#: plugin.py:60
#, docstring
msgid ""
"[<years>y] [<weeks>w] [<days>d] [<hours>h] [<minutes>m] [<seconds>s]\n"
"\n"
" Returns the number of seconds in the number of <years>, <weeks>,\n"
" <days>, <hours>, <minutes>, and <seconds> given. An example usage is\n"
" \"seconds 2h 30m\", which would return 9000, which is '3600*2 + 30*60'.\n"
" Useful for scheduling events at a given number of seconds in the\n"
" future.\n"
" "
msgstr ""
#: plugin.py:95
#, docstring
msgid ""
"<time string>\n"
"\n"
" Returns the number of seconds since epoch <time string> is.\n"
" <time string> can be any number of natural formats; just try something\n"
" and see if it will work.\n"
" "
msgstr ""
#: plugin.py:106 plugin.py:122
msgid "That's right now!"
msgstr ""
#: plugin.py:111
#, docstring
msgid ""
"<time string>\n"
"\n"
" Returns the number of seconds until <time string>.\n"
" "
msgstr ""
#: plugin.py:127
#, docstring
msgid ""
"[<seconds since epoch>]\n"
"\n"
" Returns the ctime for <seconds since epoch>, or the current ctime if\n"
" no <seconds since epoch> is given.\n"
" "
msgstr ""
#: plugin.py:133
msgid "number of seconds since epoch"
msgstr ""
#: plugin.py:138
#, docstring
msgid ""
"[<format>] [<seconds since epoch>]\n"
"\n"
" Returns the current time in <format> format, or, if <format> is not\n"
" given, uses the configurable format for the current channel. If no\n"
" <seconds since epoch> time is given, the current time is used.\n"
" "
msgstr ""
#: plugin.py:155
#, docstring
msgid ""
"<seconds>\n"
"\n"
" Returns a pretty string that is the amount of time represented by\n"
" <seconds>.\n"
" "
msgstr ""

View File

@ -34,6 +34,8 @@ import supybot.conf as conf
import supybot.utils as utils
from supybot.commands import *
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Time')
parser = utils.python.universalImport('dateutil.parser', 'local.dateutil.parser')
@ -53,6 +55,7 @@ def parse(s):
return i
class Time(callbacks.Plugin):
@internationalizeDocstring
def seconds(self, irc, msg, args):
"""[<years>y] [<weeks>w] [<days>d] [<hours>h] [<minutes>m] [<seconds>s]
@ -87,6 +90,7 @@ class Time(callbacks.Plugin):
seconds += i
irc.reply(str(seconds))
@internationalizeDocstring
def at(self, irc, msg, args, s):
"""<time string>
@ -99,9 +103,10 @@ class Time(callbacks.Plugin):
if new != now:
irc.reply(str(new))
else:
irc.error('That\'s right now!')
irc.error(_('That\'s right now!'))
at = wrap(at, ['text'])
@internationalizeDocstring
def until(self, irc, msg, args, s):
"""<time string>
@ -114,9 +119,10 @@ class Time(callbacks.Plugin):
new += 86400
irc.reply(str(new-now))
else:
irc.error('That\'s right now!')
irc.error(_('That\'s right now!'))
until = wrap(until, ['text'])
@internationalizeDocstring
def ctime(self, irc, msg, args, seconds):
"""[<seconds since epoch>]
@ -124,9 +130,10 @@ class Time(callbacks.Plugin):
no <seconds since epoch> is given.
"""
irc.reply(time.ctime(seconds))
ctime = wrap(ctime, [additional(('int', 'number of seconds since epoch'),
ctime = wrap(ctime,[additional(('int', _('number of seconds since epoch')),
TIME.time)])
@internationalizeDocstring
def time(self, irc, msg, args, channel, format, seconds):
"""[<format>] [<seconds since epoch>]
@ -143,6 +150,7 @@ class Time(callbacks.Plugin):
time = wrap(time, [optional('channel'), optional('nonInt'),
additional('float', TIME.time)])
@internationalizeDocstring
def elapsed(self, irc, msg, args, seconds):
"""<seconds>

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Todo')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -42,7 +44,7 @@ def configure(advanced):
Todo = conf.registerPlugin('Todo')
# This is where your configuration variables (if any) should go. For example:
# conf.registerGlobalValue(Todo, 'someConfigVariableName',
# registry.Boolean(False, """Help for someConfigVariableName."""))
# registry.Boolean(False, _("""Help for someConfigVariableName.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

129
plugins/Todo/messages.pot Normal file
View File

@ -0,0 +1,129 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 09:38+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: plugin.py:135
#, docstring
msgid ""
"[<username> [<task id>]|<task id>]\n"
"\n"
" Retrieves a task for the given task id. If no task id is given, it\n"
" will return a list of task ids that that user has added to their todo\n"
" list.\n"
" "
msgstr ""
#: plugin.py:150
msgid "#%i: %s"
msgstr ""
#: plugin.py:155
msgid "%s for %s: %L"
msgstr ""
#: plugin.py:159
msgid "That user has no tasks in their todo list."
msgstr ""
#: plugin.py:161
msgid "You have no tasks in your todo list."
msgstr ""
#: plugin.py:168
msgid "Active"
msgstr ""
#: plugin.py:170
msgid "Inactive"
msgstr ""
#: plugin.py:172
msgid ", priority: %i"
msgstr ""
#: plugin.py:175
msgid "%s todo for %s: %s (Added at %s)"
msgstr ""
#: plugin.py:179 plugin.py:260 plugin.py:274
msgid "task id"
msgstr ""
#: plugin.py:184
#, docstring
msgid ""
"[--priority=<num>] <text>\n"
"\n"
" Adds <text> as a task in your own personal todo list. The optional\n"
" priority argument allows you to set a task as a high or low priority.\n"
" Any integer is valid.\n"
" "
msgstr ""
#: plugin.py:195
msgid "(Todo #%i added)"
msgstr ""
#: plugin.py:201
#, docstring
msgid ""
"<task id> [<task id> ...]\n"
"\n"
" Removes <task id> from your personal todo list.\n"
" "
msgstr ""
#: plugin.py:212
msgid "Task %i could not be removed either because that id doesn't exist or it has been removed already."
msgstr ""
#: plugin.py:216
msgid "No tasks were removed because the following tasks could not be removed: %L."
msgstr ""
#: plugin.py:226
#, docstring
msgid ""
"[--{regexp} <value>] [<glob> <glob> ...]\n"
"\n"
" Searches your todos for tasks matching <glob>. If --regexp is given,\n"
" its associated value is taken as a regexp and matched against the\n"
" tasks.\n"
" "
msgstr ""
#: plugin.py:246
msgid "No tasks matched that query."
msgstr ""
#: plugin.py:252
#, docstring
msgid ""
"<id> <priority>\n"
"\n"
" Sets the priority of the todo with the given id to the specified value.\n"
" "
msgstr ""
#: plugin.py:266
#, docstring
msgid ""
"<task id> <regexp>\n"
"\n"
" Modify the task with the given id using the supplied regexp.\n"
" "
msgstr ""

View File

@ -41,6 +41,8 @@ from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Todo')
class TodoRecord(dbi.Record):
__fields__ = [
@ -128,6 +130,7 @@ class Todo(callbacks.Plugin):
def _shrink(self, s):
return utils.str.ellipsisify(s, 50)
@internationalizeDocstring
def todo(self, irc, msg, args, user, taskid):
"""[<username> [<task id>]|<task id>]
@ -144,38 +147,39 @@ class Todo(callbacks.Plugin):
try:
tasks = self.db.getTodos(user.id)
utils.sortBy(operator.attrgetter('priority'), tasks)
tasks = [format('#%i: %s', t.id, self._shrink(t.task))
tasks = [format(_('#%i: %s'), t.id, self._shrink(t.task))
for t in tasks]
Todo = 'Todo'
if len(tasks) != 1:
Todo = 'Todos'
irc.reply(format('%s for %s: %L',
irc.reply(format(_('%s for %s: %L'),
Todo, user.name, tasks))
except dbi.NoRecordError:
if u != user:
irc.reply('That user has no tasks in their todo list.')
irc.reply(_('That user has no tasks in their todo list.'))
else:
irc.reply('You have no tasks in your todo list.')
irc.reply(_('You have no tasks in your todo list.'))
return
# Reply with the user's task
else:
try:
t = self.db.get(user.id, taskid)
if t.active:
active = 'Active'
active = _('Active')
else:
active = 'Inactive'
active = _('Inactive')
if t.priority:
t.task += format(', priority: %i', t.priority)
t.task += format(_(', priority: %i'), t.priority)
at = time.strftime(conf.supybot.reply.format.time(),
time.localtime(t.at))
s = format('%s todo for %s: %s (Added at %s)',
s = format(_('%s todo for %s: %s (Added at %s)'),
active, user.name, t.task, at)
irc.reply(s)
except dbi.NoRecordError:
irc.errorInvalid('task id', taskid)
irc.errorInvalid(_('task id'), taskid)
todo = wrap(todo, [first('otherUser', 'user'), additional(('id', 'task'))])
@internationalizeDocstring
def add(self, irc, msg, args, user, optlist, text, now):
"""[--priority=<num>] <text>
@ -188,10 +192,11 @@ class Todo(callbacks.Plugin):
if option == 'priority':
priority = arg
todoId = self.db.add(priority, now, user.id, text)
irc.replySuccess(format('(Todo #%i added)', todoId))
irc.replySuccess(format(_('(Todo #%i added)'), todoId))
add = wrap(add, ['user', getopts({'priority': ('int', 'priority')}),
'text', 'now'])
@internationalizeDocstring
def remove(self, irc, msg, args, user, tasks):
"""<task id> [<task id> ...]
@ -204,18 +209,19 @@ class Todo(callbacks.Plugin):
except dbi.NoRecordError:
invalid.append(taskid)
if invalid and len(invalid) == 1:
irc.error(format('Task %i could not be removed either because '
irc.error(format(_('Task %i could not be removed either because '
'that id doesn\'t exist or it has been removed '
'already.', invalid[0]))
'already.'), invalid[0]))
elif invalid:
irc.error(format('No tasks were removed because the following '
'tasks could not be removed: %L.', invalid))
irc.error(format(_('No tasks were removed because the following '
'tasks could not be removed: %L.'), invalid))
else:
for taskid in tasks:
self.db.remove(user.id, taskid)
irc.replySuccess()
remove = wrap(remove, ['user', many(('id', 'task'))])
@internationalizeDocstring
def search(self, irc, msg, args, user, optlist, globs):
"""[--{regexp} <value>] [<glob> <glob> ...]
@ -237,10 +243,11 @@ class Todo(callbacks.Plugin):
L = [format('#%i: %s', t.id, self._shrink(t.task)) for t in tasks]
irc.reply(format('%L', L))
except dbi.NoRecordError:
irc.reply('No tasks matched that query.')
irc.reply(_('No tasks matched that query.'))
search = wrap(search,
['user', getopts({'regexp': 'regexpMatcher'}), any('glob')])
@internationalizeDocstring
def setpriority(self, irc, msg, args, user, id, priority):
"""<id> <priority>
@ -250,10 +257,11 @@ class Todo(callbacks.Plugin):
self.db.setpriority(user.id, id, priority)
irc.replySuccess()
except dbi.NoRecordError:
irc.errorInvalid('task id', id)
irc.errorInvalid(_('task id'), id)
setpriority = wrap(setpriority,
['user', ('id', 'task'), ('int', 'priority')])
@internationalizeDocstring
def change(self, irc, msg, args, user, id, replacer):
"""<task id> <regexp>
@ -263,7 +271,7 @@ class Todo(callbacks.Plugin):
self.db.change(user.id, id, replacer)
irc.replySuccess()
except dbi.NoRecordError:
irc.errorInvalid('task id', id)
irc.errorInvalid(_('task id'), id)
change = wrap(change, ['user', ('id', 'task'), 'regexpReplacer'])

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Topic')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -45,32 +47,32 @@ class TopicFormat(registry.TemplatedString):
Topic = conf.registerPlugin('Topic')
conf.registerChannelValue(Topic, 'separator',
registry.StringSurroundedBySpaces(' || ', """Determines what separator is
used between individually added topics in the channel topic."""))
registry.StringSurroundedBySpaces(' || ', _("""Determines what separator is
used between individually added topics in the channel topic.""")))
conf.registerChannelValue(Topic, 'format',
TopicFormat('$topic ($nick)', """Determines what format is used to add
TopicFormat('$topic ($nick)', _("""Determines what format is used to add
topics in the topic. All the standard substitutes apply, in addition to
"$topic" for the topic itself."""))
"$topic" for the topic itself.""")))
conf.registerChannelValue(Topic, 'recognizeTopiclen',
registry.Boolean(True, """Determines whether the bot will recognize the
registry.Boolean(True, _("""Determines whether the bot will recognize the
TOPICLEN value sent to it by the server and thus refuse to send TOPICs
longer than the TOPICLEN. These topics are likely to be truncated by the
server anyway, so this defaults to True."""))
server anyway, so this defaults to True.""")))
conf.registerChannelValue(Topic, 'default',
registry.String('', """Determines what the default topic for the channel
is. This is used by the default command to set this topic."""))
registry.String('', _("""Determines what the default topic for the channel
is. This is used by the default command to set this topic.""")))
conf.registerGroup(Topic, 'undo')
conf.registerChannelValue(Topic.undo, 'max',
registry.NonNegativeInteger(10, """Determines the number of previous
topics to keep around in case the undo command is called."""))
registry.NonNegativeInteger(10, _("""Determines the number of previous
topics to keep around in case the undo command is called.""")))
conf.registerChannelValue(Topic, 'requireManageCapability',
registry.String('channel,op; channel,halfop',
"""Determines the
_("""Determines the
capabilities required (if any) to make any topic changes,
(everything except for read-only operations). Use 'channel,capab' for
channel-level capabilities.
Note that absence of an explicit anticapability means user has
capability."""))
capability.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

356
plugins/Topic/messages.pot Normal file
View File

@ -0,0 +1,356 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 09:38+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:45
#, docstring
msgid "Value must include $topic, otherwise the actual topic would be left out."
msgstr ""
#: config.py:50
msgid ""
"Determines what separator is\n"
" used between individually added topics in the channel topic."
msgstr ""
#: config.py:53
msgid ""
"Determines what format is used to add\n"
" topics in the topic. All the standard substitutes apply, in addition to\n"
" \"$topic\" for the topic itself."
msgstr ""
#: config.py:57
msgid ""
"Determines whether the bot will recognize the\n"
" TOPICLEN value sent to it by the server and thus refuse to send TOPICs\n"
" longer than the TOPICLEN. These topics are likely to be truncated by the\n"
" server anyway, so this defaults to True."
msgstr ""
#: config.py:62
msgid ""
"Determines what the default topic for the channel\n"
" is. This is used by the default command to set this topic."
msgstr ""
#: config.py:66
msgid ""
"Determines the number of previous\n"
" topics to keep around in case the undo command is called."
msgstr ""
#: config.py:70
msgid ""
"Determines the \n"
" capabilities required (if any) to make any topic changes,\n"
" (everything except for read-only operations). Use 'channel,capab' for \n"
" channel-level capabilities.\n"
" Note that absence of an explicit anticapability means user has \n"
" capability."
msgstr ""
#: plugin.py:55
msgid "I'm not currently in %s."
msgstr ""
#: plugin.py:59
msgid "I can't change the topic, I'm not opped and %s is +t."
msgstr ""
#: plugin.py:66
msgid "The topic must not include %q."
msgstr ""
#: plugin.py:77
msgid "topic number"
msgstr ""
#: plugin.py:90
msgid "There are no topics in %s."
msgstr ""
#: plugin.py:198
msgid "That topic is too long for this server (maximum length: %i; this topic: %i)."
msgstr ""
#: plugin.py:212
#, docstring
msgid ""
"Check if the user has any of the required capabilities to manage\n"
" the channel topic.\n"
"\n"
" The list of required capabilities is in requireManageCapability\n"
" channel config.\n"
"\n"
" Also allow if the user is a chanop. Since he can change the topic\n"
" manually anyway.\n"
" "
msgstr ""
#: plugin.py:264
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Returns the topic for <channel>. <channel> is only necessary if the\n"
" message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:275
#, docstring
msgid ""
"[<channel>] <topic>\n"
"\n"
" Adds <topic> to the topics for <channel>. <channel> is only necessary\n"
" if the message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:290
#, docstring
msgid ""
"[<channel>] <topic>\n"
"\n"
" Adds <topic> to the topics for <channel>. If the topic is too long\n"
" for the server, topics will be popped until there is enough room.\n"
" <channel> is only necessary if the message isn't sent in the channel\n"
" itself.\n"
" "
msgstr ""
#: plugin.py:307
#, docstring
msgid ""
"[<channel>] <number> <topic>\n"
"\n"
" Replaces topic <number> with <topic>.\n"
" "
msgstr ""
#: plugin.py:321
#, docstring
msgid ""
"[<channel>] <topic>\n"
"\n"
" Adds <topic> to the topics for <channel> at the beginning of the topics\n"
" currently on <channel>. <channel> is only necessary if the message\n"
" isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:337
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Shuffles the topics in <channel>. <channel> is only necessary if the\n"
" message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:347
msgid "I can't shuffle 1 or fewer topics."
msgstr ""
#: plugin.py:359
#, docstring
msgid ""
"[<channel>] <number> [<number> ...]\n"
"\n"
" Reorders the topics from <channel> in the order of the specified\n"
" <number> arguments. <number> is a one-based index into the topics.\n"
" <channel> is only necessary if the message isn't sent in the channel\n"
" itself.\n"
" "
msgstr ""
#: plugin.py:372
msgid "I cannot reorder 1 or fewer topics."
msgstr ""
#: plugin.py:374
msgid "All topic numbers must be specified."
msgstr ""
#: plugin.py:376
msgid "Duplicate topic numbers cannot be specified."
msgstr ""
#: plugin.py:384
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Returns a list of the topics in <channel>, prefixed by their indexes.\n"
" Mostly useful for topic reordering. <channel> is only necessary if the\n"
" message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:393
msgid "%i: %s"
msgstr ""
#: plugin.py:400
#, docstring
msgid ""
"[<channel>] <number>\n"
"\n"
" Returns topic number <number> from <channel>. <number> is a one-based\n"
" index into the topics. <channel> is only necessary if the message\n"
" isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:415
#, docstring
msgid ""
"[<channel>] <number> <regexp>\n"
"\n"
" Changes the topic number <number> on <channel> according to the regular\n"
" expression <regexp>. <number> is the one-based index into the topics;\n"
" <regexp> is a regular expression of the form\n"
" s/regexp/replacement/flags. <channel> is only necessary if the message\n"
" isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:433
#, docstring
msgid ""
"[<channel>] [<number>] <topic>\n"
"\n"
" Sets the topic <number> to be <text>. If no <number> is given, this\n"
" sets the entire topic. <channel> is only necessary if the message\n"
" isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:454
#, docstring
msgid ""
"[<channel>] <number>\n"
"\n"
" Removes topic <number> from the topic for <channel> Topics are\n"
" numbered starting from 1; you can also use negative indexes to refer\n"
" to topics starting the from the end of the topic. <channel> is only\n"
" necessary if the message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:471 plugin.py:485
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Locks the topic (sets the mode +t) in <channel>. <channel> is only\n"
" necessary if the message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:481
msgid "lock the topic"
msgstr ""
#: plugin.py:495
msgid "unlock the topic"
msgstr ""
#: plugin.py:499
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Restores the topic to the last topic set by the bot. <channel> is only\n"
" necessary if the message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:510
msgid "I haven't yet set the topic in %s."
msgstr ""
#: plugin.py:518
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Restores the topic to the one previous to the last topic command that\n"
" set it. <channel> is only necessary if the message isn't sent in the\n"
" channel itself.\n"
" "
msgstr ""
#: plugin.py:532
msgid "There are no more undos for %s."
msgstr ""
#: plugin.py:537
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Undoes the last undo. <channel> is only necessary if the message isn't\n"
" sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:549
msgid "There are no redos for %s."
msgstr ""
#: plugin.py:554
#, docstring
msgid ""
"[<channel>] <first topic number> <second topic number>\n"
"\n"
" Swaps the order of the first topic number and the second topic number.\n"
" <channel> is only necessary if the message isn't sent in the channel\n"
" itself.\n"
" "
msgstr ""
#: plugin.py:565
msgid "I refuse to swap the same topic with itself."
msgstr ""
#: plugin.py:575
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Sets the topic in <channel> to the default topic for <channel>. The\n"
" default topic for a channel may be configured via the configuration\n"
" variable supybot.plugins.Topic.default.\n"
" "
msgstr ""
#: plugin.py:588
msgid "There is no default topic configured for %s."
msgstr ""
#: plugin.py:594
#, docstring
msgid ""
"[<channel>] <separator>\n"
"\n"
" Sets the topic separator for <channel> to <separator> Converts the\n"
" current topic appropriately.\n"
" "
msgstr ""

View File

@ -43,6 +43,8 @@ import supybot.ircmsgs as ircmsgs
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Topic')
def canChangeTopic(irc, msg, args, state):
@ -50,18 +52,19 @@ def canChangeTopic(irc, msg, args, state):
callConverter('channel', irc, msg, args, state)
callConverter('inChannel', irc, msg, args, state)
if state.channel not in irc.state.channels:
state.error(format('I\'m not currently in %s.', state.channel),
state.error(format(_('I\'m not currently in %s.'), state.channel),
Raise=True)
c = irc.state.channels[state.channel]
if irc.nick not in c.ops and 't' in c.modes:
state.error(format('I can\'t change the topic, I\'m not opped '
'and %s is +t.', state.channel), Raise=True)
state.error(format(_('I can\'t change the topic, I\'m not opped '
'and %s is +t.'), state.channel), Raise=True)
def getTopic(irc, msg, args, state, format=True):
separator = state.cb.registryValue('separator', state.channel)
if separator in args[0]:
state.errorInvalid('topic', args[0],
format('The topic must not include %q.', separator))
format(_('The topic must not include %q.'),
separator))
topic = args.pop(0)
if format:
env = {'topic': topic}
@ -71,7 +74,7 @@ def getTopic(irc, msg, args, state, format=True):
def getTopicNumber(irc, msg, args, state):
def error(s):
state.errorInvalid('topic number', s)
state.errorInvalid(_('topic number'), s)
try:
n = int(args[0])
if not n:
@ -84,7 +87,7 @@ def getTopicNumber(irc, msg, args, state):
separator = state.cb.registryValue('separator', state.channel)
topics = splitTopic(topic, separator)
if not topics:
state.error(format('There are no topics in %s.', state.channel),
state.error(format(_('There are no topics in %s.'), state.channel),
Raise=True)
try:
topics[n]
@ -192,9 +195,9 @@ class Topic(callbacks.Plugin):
newTopic = self._joinTopic(channel, topics)
elif len(newTopic) > maxLen:
if self.registryValue('recognizeTopiclen', channel):
irc.error(format('That topic is too long for this server '
'(maximum length: %i; this topic: %i).',
maxLen, len(newTopic)),
irc.error(format(_('That topic is too long for this '
'server (maximum length: %i; this topic: '
'%i).'), maxLen, len(newTopic)),
Raise=True)
except KeyError:
pass
@ -204,6 +207,7 @@ class Topic(callbacks.Plugin):
irc.queueMsg(ircmsgs.topic(channel, newTopic))
irc.noReply()
@internationalizeDocstring
def _checkManageCapabilities(self, irc, msg, channel):
"""Check if the user has any of the required capabilities to manage
the channel topic.
@ -255,6 +259,7 @@ class Topic(callbacks.Plugin):
# us to undo the first topic change that takes place in a channel.
self._addUndo(msg.args[1], [msg.args[2]])
@internationalizeDocstring
def topic(self, irc, msg, args, channel):
"""[<channel>]
@ -265,6 +270,7 @@ class Topic(callbacks.Plugin):
irc.reply(topic)
topic = wrap(topic, ['inChannel'])
@internationalizeDocstring
def add(self, irc, msg, args, channel, topic):
"""[<channel>] <topic>
@ -279,6 +285,7 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics)
add = wrap(add, ['canChangeTopic', rest('topic')])
@internationalizeDocstring
def fit(self, irc, msg, args, channel, topic):
"""[<channel>] <topic>
@ -295,6 +302,7 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics, fit=True)
fit = wrap(fit, ['canChangeTopic', rest('topic')])
@internationalizeDocstring
def replace(self, irc, msg, args, channel, i, topic):
"""[<channel>] <number> <topic>
@ -308,6 +316,7 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics)
replace = wrap(replace, ['canChangeTopic', 'topicNumber', rest('topic')])
@internationalizeDocstring
def insert(self, irc, msg, args, channel, topic):
"""[<channel>] <topic>
@ -323,6 +332,7 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics)
insert = wrap(insert, ['canChangeTopic', rest('topic')])
@internationalizeDocstring
def shuffle(self, irc, msg, args, channel):
"""[<channel>]
@ -334,7 +344,7 @@ class Topic(callbacks.Plugin):
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel)
if len(topics) == 0 or len(topics) == 1:
irc.error('I can\'t shuffle 1 or fewer topics.', Raise=True)
irc.error(_('I can\'t shuffle 1 or fewer topics.'), Raise=True)
elif len(topics) == 2:
topics.reverse()
else:
@ -344,6 +354,7 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics)
shuffle = wrap(shuffle, ['canChangeTopic'])
@internationalizeDocstring
def reorder(self, irc, msg, args, channel, numbers):
"""[<channel>] <number> [<number> ...]
@ -358,16 +369,17 @@ class Topic(callbacks.Plugin):
topics = self._splitTopic(irc.state.getTopic(channel), channel)
num = len(topics)
if num == 0 or num == 1:
irc.error('I cannot reorder 1 or fewer topics.', Raise=True)
irc.error(_('I cannot reorder 1 or fewer topics.'), Raise=True)
if len(numbers) != num:
irc.error('All topic numbers must be specified.', Raise=True)
irc.error(_('All topic numbers must be specified.'), Raise=True)
if sorted(numbers) != range(num):
irc.error('Duplicate topic numbers cannot be specified.')
irc.error(_('Duplicate topic numbers cannot be specified.'))
return
newtopics = [topics[i] for i in numbers]
self._sendTopics(irc, channel, newtopics)
reorder = wrap(reorder, ['canChangeTopic', many('topicNumber')])
@internationalizeDocstring
def list(self, irc, msg, args, channel):
"""[<channel>]
@ -378,11 +390,12 @@ class Topic(callbacks.Plugin):
topics = self._splitTopic(irc.state.getTopic(channel), channel)
L = []
for (i, t) in enumerate(topics):
L.append(format('%i: %s', i+1, utils.str.ellipsisify(t, 30)))
L.append(format(_('%i: %s'), i+1, utils.str.ellipsisify(t, 30)))
s = utils.str.commaAndify(L)
irc.reply(s)
list = wrap(list, ['inChannel'])
@internationalizeDocstring
def get(self, irc, msg, args, channel, number):
"""[<channel>] <number>
@ -397,6 +410,7 @@ class Topic(callbacks.Plugin):
irc.reply(topics[number])
get = wrap(get, ['inChannel', 'topicNumber'])
@internationalizeDocstring
def change(self, irc, msg, args, channel, number, replacer):
"""[<channel>] <number> <regexp>
@ -414,6 +428,7 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics)
change = wrap(change, ['canChangeTopic', 'topicNumber', 'regexpReplacer'])
@internationalizeDocstring
def set(self, irc, msg, args, channel, number, topic):
"""[<channel>] [<number>] <topic>
@ -434,6 +449,7 @@ class Topic(callbacks.Plugin):
optional('topicNumber'),
rest(('topic', False))])
@internationalizeDocstring
def remove(self, irc, msg, args, channel, number):
"""[<channel>] <number>
@ -450,6 +466,7 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics)
remove = wrap(remove, ['canChangeTopic', 'topicNumber'])
@internationalizeDocstring
def lock(self, irc, msg, args, channel):
"""[<channel>]
@ -461,8 +478,9 @@ class Topic(callbacks.Plugin):
irc.errorNoCapability(capabilities, Raise=True)
irc.queueMsg(ircmsgs.mode(channel, '+t'))
irc.noReply()
lock = wrap(lock, ['channel', ('haveOp', 'lock the topic')])
lock = wrap(lock, ['channel', ('haveOp', _('lock the topic'))])
@internationalizeDocstring
def unlock(self, irc, msg, args, channel):
"""[<channel>]
@ -474,8 +492,9 @@ class Topic(callbacks.Plugin):
irc.errorNoCapability(capabilities, Raise=True)
irc.queueMsg(ircmsgs.mode(channel, '-t'))
irc.noReply()
unlock = wrap(unlock, ['channel', ('haveOp', 'unlock the topic')])
unlock = wrap(unlock, ['channel', ('haveOp', _('unlock the topic'))])
@internationalizeDocstring
def restore(self, irc, msg, args, channel):
"""[<channel>]
@ -488,11 +507,13 @@ class Topic(callbacks.Plugin):
try:
topics = self.lastTopics[channel]
except KeyError:
irc.error(format('I haven\'t yet set the topic in %s.', channel))
irc.error(format(_('I haven\'t yet set the topic in %s.'),
channel))
return
self._sendTopics(irc, channel, topics)
restore = wrap(restore, ['canChangeTopic'])
@internationalizeDocstring
def undo(self, irc, msg, args, channel):
"""[<channel>]
@ -508,9 +529,10 @@ class Topic(callbacks.Plugin):
if topics is not None:
self._sendTopics(irc, channel, topics, isDo=True)
else:
irc.error(format('There are no more undos for %s.', channel))
irc.error(format(_('There are no more undos for %s.'), channel))
undo = wrap(undo, ['canChangetopic'])
@internationalizeDocstring
def redo(self, irc, msg, args, channel):
"""[<channel>]
@ -524,9 +546,10 @@ class Topic(callbacks.Plugin):
if topics is not None:
self._sendTopics(irc, channel, topics, isDo=True)
else:
irc.error(format('There are no redos for %s.', channel))
irc.error(format(_('There are no redos for %s.'), channel))
redo = wrap(redo, ['canChangeTopic'])
@internationalizeDocstring
def swap(self, irc, msg, args, channel, first, second):
"""[<channel>] <first topic number> <second topic number>
@ -539,7 +562,7 @@ class Topic(callbacks.Plugin):
irc.errorNoCapability(capabilities, Raise=True)
topics = self._splitTopic(irc.state.getTopic(channel), channel)
if first == second:
irc.error('I refuse to swap the same topic with itself.')
irc.error(_('I refuse to swap the same topic with itself.'))
return
t = topics[first]
topics[first] = topics[second]
@ -547,6 +570,7 @@ class Topic(callbacks.Plugin):
self._sendTopics(irc, channel, topics)
swap = wrap(swap, ['canChangeTopic', 'topicNumber', 'topicNumber'])
@internationalizeDocstring
def default(self, irc, msg, args, channel):
"""[<channel>]
@ -561,10 +585,11 @@ class Topic(callbacks.Plugin):
if topic:
self._sendTopics(irc, channel, [topic])
else:
irc.error(format('There is no default topic configured for %s.',
irc.error(format(_('There is no default topic configured for %s.'),
channel))
default = wrap(default, ['canChangeTopic'])
@internationalizeDocstring
def separator(self, irc, msg, args, channel, separator):
"""[<channel>] <separator>

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('URL')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -40,10 +42,10 @@ def configure(advanced):
URL = conf.registerPlugin('URL')
conf.registerChannelValue(URL, 'nonSnarfingRegexp',
registry.Regexp(None, """Determines what URLs are not to be snarfed and
registry.Regexp(None, _("""Determines what URLs are not to be snarfed and
stored in the database for the channel; URLs matching the given regexp will
not be snarfed. Give the empty string if you have no URLs that you'd like
to exclude from being snarfed."""))
to exclude from being snarfed.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

58
plugins/URL/messages.pot Normal file
View File

@ -0,0 +1,58 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 09:38+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:45
msgid ""
"Determines what URLs are not to be snarfed and\n"
" stored in the database for the channel; URLs matching the given regexp will\n"
" not be snarfed. Give the empty string if you have no URLs that you'd like\n"
" to exclude from being snarfed."
msgstr ""
#: plugin.py:89
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Returns the number of URLs in the URL database. <channel> is only\n"
" required if the message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:96
msgid "I have %n in my database."
msgstr ""
#: plugin.py:101
#, docstring
msgid ""
"[<channel>] [--{from,with,without,near,proto} <value>] [--nolimit]\n"
"\n"
" Gives the last URL matching the given criteria. --from is from whom\n"
" the URL came; --proto is the protocol the URL used; --with is something\n"
" inside the URL; --without is something that should not be in the URL;\n"
" --near is something in the same message as the URL; If --nolimit is\n"
" given, returns all the URLs that are found. to just the URL.\n"
" <channel> is only necessary if the message isn't sent in the channel\n"
" itself.\n"
" "
msgstr ""
#: plugin.py:143
msgid "No URLs matched that criteria."
msgstr ""

View File

@ -36,6 +36,8 @@ import supybot.plugins as plugins
import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('URL')
class UrlRecord(dbi.Record):
__fields__ = [
@ -82,6 +84,7 @@ class URL(callbacks.Plugin):
self.log.debug('Adding %u to db.', url)
self.db.add(channel, url, msg)
@internationalizeDocstring
def stats(self, irc, msg, args, channel):
"""[<channel>]
@ -90,9 +93,10 @@ class URL(callbacks.Plugin):
"""
self.db.vacuum(channel)
count = self.db.size(channel)
irc.reply(format('I have %n in my database.', (count, 'URL')))
irc.reply(format(_('I have %n in my database.'), (count, 'URL')))
stats = wrap(stats, ['channeldb'])
@internationalizeDocstring
def last(self, irc, msg, args, channel, optlist):
"""[<channel>] [--{from,with,without,near,proto} <value>] [--nolimit]
@ -136,7 +140,7 @@ class URL(callbacks.Plugin):
return True
urls = [record.url for record in self.db.urls(channel, predicate)]
if not urls:
irc.reply('No URLs matched that criteria.')
irc.reply(_('No URLs matched that criteria.'))
else:
if nolimit:
urls = [format('%u', url) for url in urls]

View File

@ -30,6 +30,8 @@
import supybot.conf as conf
import supybot.utils as utils
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Unix')
import plugin
@ -42,11 +44,11 @@ def configure(advanced):
# registry as appropriate.
from supybot.questions import output, expect, anything, something, yn
conf.registerPlugin('Unix', True)
output("""The "progstats" command can reveal potentially sensitive
output(_("""The "progstats" command can reveal potentially sensitive
information about your machine. Here's an example of its output:
%s\n""" % progstats())
if yn('Would you like to disable this command for non-owner users?',
%s\n""") % progstats())
if yn(_('Would you like to disable this command for non-owner users?'),
default=True):
conf.supybot.commands.disabled().add('Unix.progstats')
@ -54,36 +56,36 @@ def configure(advanced):
Unix = conf.registerPlugin('Unix')
conf.registerGroup(Unix, 'fortune')
conf.registerGlobalValue(Unix.fortune, 'command',
registry.String(utils.findBinaryInPath('fortune') or '', """Determines what
command will be called for the fortune command."""))
registry.String(utils.findBinaryInPath('fortune') or '', _("""Determines
what command will be called for the fortune command.""")))
conf.registerGlobalValue(Unix.fortune, 'short',
registry.Boolean(True, """Determines whether only short fortunes will be
used if possible. This sends the -s option to the fortune program."""))
registry.Boolean(True, _("""Determines whether only short fortunes will be
used if possible. This sends the -s option to the fortune program.""")))
conf.registerGlobalValue(Unix.fortune, 'equal',
registry.Boolean(True, """Determines whether fortune will give equal
registry.Boolean(True, _("""Determines whether fortune will give equal
weight to the different fortune databases. If false, then larger
databases will be given more weight. This sends the -e option to the
fortune program."""))
fortune program.""")))
conf.registerGlobalValue(Unix.fortune, 'offensive',
registry.Boolean(False, """Determines whether fortune will retrieve
registry.Boolean(False, _("""Determines whether fortune will retrieve
offensive fortunes along with the normal fortunes. This sends the -a
option to the fortune program."""))
option to the fortune program.""")))
conf.registerGlobalValue(Unix.fortune, 'files',
registry.SpaceSeparatedListOfStrings([], """Determines what specific file
registry.SpaceSeparatedListOfStrings([], _("""Determines what specific file
(if any) will be used with the fortune command; if none is given, the
system-wide default will be used. Do note that this fortune file must be
placed with the rest of your system's fortune files."""))
placed with the rest of your system's fortune files.""")))
conf.registerGroup(Unix, 'spell')
conf.registerGlobalValue(Unix.spell, 'command',
registry.String(utils.findBinaryInPath('aspell') or
utils.findBinaryInPath('ispell') or '', """Determines what
command will be called for the spell command."""))
utils.findBinaryInPath('ispell') or '', _("""Determines
what command will be called for the spell command.""")))
conf.registerGroup(Unix, 'wtf')
conf.registerGlobalValue(Unix.wtf, 'command',
registry.String(utils.findBinaryInPath('wtf') or '', """Determines what
command will be called for the wtf command."""))
registry.String(utils.findBinaryInPath('wtf') or '', _("""Determines what
command will be called for the wtf command.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

198
plugins/Unix/messages.pot Normal file
View File

@ -0,0 +1,198 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 09:38+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:47
msgid ""
"The \"progstats\" command can reveal potentially sensitive\n"
" information about your machine. Here's an example of its output:\n"
"\n"
" %s\n"
msgstr ""
#: config.py:51
msgid "Would you like to disable this command for non-owner users?"
msgstr ""
#: config.py:59
msgid ""
"Determines\n"
" what command will be called for the fortune command."
msgstr ""
#: config.py:62
msgid ""
"Determines whether only short fortunes will be\n"
" used if possible. This sends the -s option to the fortune program."
msgstr ""
#: config.py:65
msgid ""
"Determines whether fortune will give equal\n"
" weight to the different fortune databases. If false, then larger\n"
" databases will be given more weight. This sends the -e option to the\n"
" fortune program."
msgstr ""
#: config.py:70
msgid ""
"Determines whether fortune will retrieve\n"
" offensive fortunes along with the normal fortunes. This sends the -a\n"
" option to the fortune program."
msgstr ""
#: config.py:74
msgid ""
"Determines what specific file\n"
" (if any) will be used with the fortune command; if none is given, the\n"
" system-wide default will be used. Do note that this fortune file must be\n"
" placed with the rest of your system's fortune files."
msgstr ""
#: config.py:82
msgid ""
"Determines\n"
" what command will be called for the spell command."
msgstr ""
#: config.py:87
msgid ""
"Determines what\n"
" command will be called for the wtf command."
msgstr ""
#: plugin.py:73
#, docstring
msgid ""
"<error number or code>\n"
"\n"
" Returns the number of an errno code, or the errno code of a number.\n"
" "
msgstr ""
#: plugin.py:85
msgid "I can't find the errno number for that code."
msgstr ""
#: plugin.py:88
msgid "(unknown)"
msgstr ""
#: plugin.py:89
msgid "%s (#%i): %s"
msgstr ""
#: plugin.py:94
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns various unix-y information on the running supybot process.\n"
" "
msgstr ""
#: plugin.py:102
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns the current pid of the process for this Supybot.\n"
" "
msgstr ""
#: plugin.py:112
#, docstring
msgid ""
"<password> [<salt>]\n"
"\n"
" Returns the resulting of doing a crypt() on <password> If <salt> is\n"
" not given, uses a random salt. If running on a glibc2 system,\n"
" prepending '$1$' to your salt will cause crypt to return an MD5sum\n"
" based crypt rather than the standard DES based crypt.\n"
" "
msgstr ""
#: plugin.py:131
#, docstring
msgid ""
"<word>\n"
"\n"
" Returns the result of passing <word> to aspell/ispell. The results\n"
" shown are sorted from best to worst in terms of being a likely match\n"
" for the spelling of <word>.\n"
" "
msgstr ""
#: plugin.py:140
msgid "The spell checking command is not configured. If one is installed, reconfigure supybot.plugins.Unix.spell.command appropriately."
msgstr ""
#: plugin.py:145
msgid "<word> must begin with an alphabet character."
msgstr ""
#: plugin.py:167
msgid "No results found."
msgstr ""
#: plugin.py:178
msgid "%q may be spelled correctly."
msgstr ""
#: plugin.py:180
msgid "I could not find an alternate spelling for %q"
msgstr ""
#: plugin.py:184
msgid "Possible spellings for %q: %L."
msgstr ""
#: plugin.py:193
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns a fortune from the *nix fortune program.\n"
" "
msgstr ""
#: plugin.py:213
msgid "It seems the configured fortune command was not available."
msgstr ""
#: plugin.py:222
msgid "The fortune command is not configured. If fortune is installed on this system, reconfigure the supybot.plugins.Unix.fortune.command configuration variable appropriately."
msgstr ""
#: plugin.py:229
#, docstring
msgid ""
"[is] <something>\n"
"\n"
" Returns wtf <something> is. 'wtf' is a *nix command that first\n"
" appeared in NetBSD 1.5. In most *nices, it's available in some sort\n"
" of 'bsdgames' package.\n"
" "
msgstr ""
#: plugin.py:244
msgid "It seems the configured wtf command was not available."
msgstr ""
#: plugin.py:253
msgid "The wtf command is not configured. If it is installed on this system, reconfigure the supybot.plugins.Unix.wtf.command configuration variable appropriately."
msgstr ""

View File

@ -44,6 +44,8 @@ from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Unix')
def progstats():
pw = pwd.getpwuid(os.getuid())
@ -66,6 +68,7 @@ def pipeReadline(fd, timeout=2):
raise TimeoutError
class Unix(callbacks.Plugin):
@internationalizeDocstring
def errno(self, irc, msg, args, s):
"""<error number or code>
@ -79,13 +82,14 @@ class Unix(callbacks.Plugin):
try:
i = getattr(errno, name)
except AttributeError:
irc.reply('I can\'t find the errno number for that code.')
irc.reply(_('I can\'t find the errno number for that code.'))
return
except KeyError:
name = '(unknown)'
irc.reply(format('%s (#%i): %s', name, i, os.strerror(i)))
name = _('(unknown)')
irc.reply(format(_('%s (#%i): %s'), name, i, os.strerror(i)))
errno = wrap(errno, ['something'])
@internationalizeDocstring
def progstats(self, irc, msg, args):
"""takes no arguments
@ -93,6 +97,7 @@ class Unix(callbacks.Plugin):
"""
irc.reply(progstats())
@internationalizeDocstring
def pid(self, irc, msg, args):
"""takes no arguments
@ -102,6 +107,7 @@ class Unix(callbacks.Plugin):
pid = wrap(pid, [('checkCapability', 'owner')])
_cryptre = re.compile(r'[./0-9A-Za-z]')
@internationalizeDocstring
def crypt(self, irc, msg, args, password, salt):
"""<password> [<salt>]
@ -120,6 +126,7 @@ class Unix(callbacks.Plugin):
irc.reply(crypt.crypt(password, salt))
crypt = wrap(crypt, ['something', additional('something')])
@internationalizeDocstring
def spell(self, irc, msg, args, word):
"""<word>
@ -130,12 +137,12 @@ class Unix(callbacks.Plugin):
# We are only checking the first word
spellCmd = self.registryValue('spell.command')
if not spellCmd:
irc.error('The spell checking command is not configured. If one '
irc.error(_('The spell checking command is not configured. If one '
'is installed, reconfigure '
'supybot.plugins.Unix.spell.command appropriately.',
'supybot.plugins.Unix.spell.command appropriately.'),
Raise=True)
if word and not word[0].isalpha():
irc.error('<word> must begin with an alphabet character.')
irc.error(_('<word> must begin with an alphabet character.'))
return
try:
inst = subprocess.Popen([spellCmd, '-a'], close_fds=True,
@ -157,7 +164,7 @@ class Unix(callbacks.Plugin):
lines = filter(None, out.splitlines())
lines.pop(0) # Banner
if not lines:
irc.error('No results found.', Raise=True)
irc.error(_('No results found.'), Raise=True)
line = lines.pop(0)
line2 = ''
if lines:
@ -168,18 +175,20 @@ class Unix(callbacks.Plugin):
if line[0] in '*+' and line2:
line = line2
if line[0] in '*+':
resp = format('%q may be spelled correctly.', word)
resp = format(_('%q may be spelled correctly.'), word)
elif line[0] == '#':
resp = format('I could not find an alternate spelling for %q',word)
resp = format(_('I could not find an alternate spelling for %q'),
word)
elif line[0] == '&':
matches = line.split(':')[1].strip()
resp = format('Possible spellings for %q: %L.',
resp = format(_('Possible spellings for %q: %L.'),
word, matches.split(', '))
else:
resp = 'Something unexpected was seen in the [ai]spell output.'
irc.reply(resp)
spell = wrap(spell, ['somethingWithoutSpaces'])
@internationalizeDocstring
def fortune(self, irc, msg, args):
"""takes no arguments
@ -201,8 +210,8 @@ class Unix(callbacks.Plugin):
stderr=subprocess.PIPE,
stdin=file(os.devnull))
except OSError, e:
irc.error('It seems the configured fortune command was '
'not available.', Raise=True)
irc.error(_('It seems the configured fortune command was '
'not available.'), Raise=True)
(out, err) = inst.communicate()
inst.wait()
lines = out.splitlines()
@ -210,11 +219,12 @@ class Unix(callbacks.Plugin):
lines = filter(None, lines)
irc.replies(lines, joiner=' ')
else:
irc.error('The fortune command is not configured. If fortune is '
irc.error(_('The fortune command is not configured. If fortune is '
'installed on this system, reconfigure the '
'supybot.plugins.Unix.fortune.command configuration '
'variable appropriately.')
'variable appropriately.'))
@internationalizeDocstring
def wtf(self, irc, msg, args, _, something):
"""[is] <something>
@ -231,8 +241,8 @@ class Unix(callbacks.Plugin):
stderr=file(os.devnull),
stdin=file(os.devnull))
except OSError:
irc.error('It seems the configured wtf command was not '
'available.', Raise=True)
irc.error(_('It seems the configured wtf command was not '
'available.'), Raise=True)
(out, _) = inst.communicate()
inst.wait()
if out:
@ -240,10 +250,10 @@ class Unix(callbacks.Plugin):
response = utils.str.normalizeWhitespace(response)
irc.reply(response)
else:
irc.error('The wtf command is not configured. If it is installed '
irc.error(_('The wtf command is not configured. If it is installed '
'on this system, reconfigure the '
'supybot.plugins.Unix.wtf.command configuration '
'variable appropriately.')
'variable appropriately.'))
wtf = wrap(wtf, [optional(('literal', ['is'])), 'something'])
Class = Unix

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Utilities')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -42,7 +44,7 @@ def configure(advanced):
Utilities = conf.registerPlugin('Utilities')
# This is where your configuration variables (if any) should go. For example:
# conf.registerGlobalValue(Utilities, 'someConfigVariableName',
# registry.Boolean(False, """Help for someConfigVariableName."""))
# registry.Boolean(False, _("""Help for someConfigVariableName.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

View File

@ -0,0 +1,81 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 09:39+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: plugin.py:45
#, docstring
msgid ""
"requires no arguments\n"
"\n"
" Does nothing. Useful sometimes for sequencing commands when you don't\n"
" care about their non-error return values.\n"
" "
msgstr ""
#: plugin.py:59
#, docstring
msgid ""
"[<text>]\n"
"\n"
" Does nothing except to reply with a success message. This is useful\n"
" when you want to run multiple commands as nested commands, and don't\n"
" care about their output as long as they're successful. An error, of\n"
" course, will break out of this command. <text>, if given, will be\n"
" appended to the end of the success message.\n"
" "
msgstr ""
#: plugin.py:72
#, docstring
msgid ""
"<text> [<text> ...]\n"
"\n"
" Returns the last argument given. Useful when you'd like multiple\n"
" nested commands to run, but only the output of the last one to be\n"
" returned.\n"
" "
msgstr ""
#: plugin.py:86
#, docstring
msgid ""
"<text>\n"
"\n"
" Returns the arguments given it. Uses our standard substitute on the\n"
" string(s) given to it; $nick (or $who), $randomNick, $randomInt,\n"
" $botnick, $channel, $user, $host, $today, $now, and $randomDate are all\n"
" handled appropriately.\n"
" "
msgstr ""
#: plugin.py:99
#, docstring
msgid ""
"<arg> [<arg> ...]\n"
"\n"
" Shuffles the arguments given it.\n"
" "
msgstr ""
#: plugin.py:109
#, docstring
msgid ""
"<command> <text>\n"
"\n"
" Tokenizes <text> and calls <command> with the resulting arguments.\n"
" "
msgstr ""

View File

@ -34,10 +34,13 @@ import random
from supybot.commands import *
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Utilities')
class Utilities(callbacks.Plugin):
# Yes, I really do mean "requires no arguments" below. "takes no
# arguments" would probably lead people to think it was a useless command.
@internationalizeDocstring
def ignore(self, irc, msg, args):
"""requires no arguments
@ -51,6 +54,7 @@ class Utilities(callbacks.Plugin):
irc.reply('')
# Do be careful not to wrap this unless you do any('something').
@internationalizeDocstring
def success(self, irc, msg, args, text):
"""[<text>]
@ -63,6 +67,7 @@ class Utilities(callbacks.Plugin):
irc.replySuccess(text)
success = wrap(success, [additional('text')])
@internationalizeDocstring
def last(self, irc, msg, args):
"""<text> [<text> ...]
@ -76,6 +81,7 @@ class Utilities(callbacks.Plugin):
else:
raise callbacks.ArgumentError
@internationalizeDocstring
def echo(self, irc, msg, args, text):
"""<text>
@ -88,6 +94,7 @@ class Utilities(callbacks.Plugin):
irc.reply(text, prefixNick=False)
echo = wrap(echo, ['text'])
@internationalizeDocstring
def shuffle(self, irc, msg, args, things):
"""<arg> [<arg> ...]
@ -97,6 +104,7 @@ class Utilities(callbacks.Plugin):
irc.reply(' '.join(things))
shuffle = wrap(shuffle, [many('anything')])
@internationalizeDocstring
def apply(self, irc, msg, args, command, rest):
"""<command> <text>

View File

@ -29,6 +29,8 @@
import supybot.conf as conf
import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Web')
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
@ -45,17 +47,17 @@ def configure(advanced):
Web = conf.registerPlugin('Web')
conf.registerChannelValue(Web, 'titleSnarfer',
registry.Boolean(False, """Determines whether the bot will output the HTML
title of URLs it sees in the channel."""))
registry.Boolean(False, _("""Determines whether the bot will output the
HTML title of URLs it sees in the channel.""")))
conf.registerChannelValue(Web, 'nonSnarfingRegexp',
registry.Regexp(None, """Determines what URLs are to be snarfed and stored
in the database in the channel; URLs matching the regexp given will not be
snarfed. Give the empty string if you have no URLs that you'd like to
exclude from being snarfed."""))
registry.Regexp(None, _("""Determines what URLs are to be snarfed and
stored in the database in the channel; URLs matching the regexp given will
not be snarfed. Give the empty string if you have no URLs that you'd like
to exclude from being snarfed.""")))
conf.registerGroup(Web, 'fetch')
conf.registerGlobalValue(Web.fetch, 'maximum',
registry.NonNegativeInteger(0, """Determines the maximum number of
bytes the bot will download via the 'fetch' command in this plugin."""))
registry.NonNegativeInteger(0, _("""Determines the maximum number of
bytes the bot will download via the 'fetch' command in this plugin.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

156
plugins/Web/messages.pot Normal file
View File

@ -0,0 +1,156 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2010-10-20 09:39+CEST\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:50
msgid ""
"Determines whether the bot will output the\n"
" HTML title of URLs it sees in the channel."
msgstr ""
#: config.py:53
msgid ""
"Determines what URLs are to be snarfed and\n"
" stored in the database in the channel; URLs matching the regexp given will\n"
" not be snarfed. Give the empty string if you have no URLs that you'd like\n"
" to exclude from being snarfed."
msgstr ""
#: config.py:60
msgid ""
"Determines the maximum number of\n"
" bytes the bot will download via the 'fetch' command in this plugin."
msgstr ""
#: plugin.py:71
#, docstring
msgid "Add the help for \"@help Web\" here."
msgstr ""
#: plugin.py:114
#, docstring
msgid ""
"<url>\n"
"\n"
" Returns the HTTP headers of <url>. Only HTTP urls are valid, of\n"
" course.\n"
" "
msgstr ""
#: plugin.py:121
msgid "%s: %s"
msgstr ""
#: plugin.py:131
#, docstring
msgid ""
"<url>\n"
"\n"
" Returns the DOCTYPE string of <url>. Only HTTP urls are valid, of\n"
" course.\n"
" "
msgstr ""
#: plugin.py:143
msgid "That URL has no specified doctype."
msgstr ""
#: plugin.py:148
#, docstring
msgid ""
"<url>\n"
"\n"
" Returns the Content-Length header of <url>. Only HTTP urls are valid,\n"
" of course.\n"
" "
msgstr ""
#: plugin.py:157 plugin.py:162
msgid "%u is %i bytes long."
msgstr ""
#: plugin.py:164
msgid "The server didn't tell me how long %u is but it's longer than %i bytes."
msgstr ""
#: plugin.py:173
#, docstring
msgid ""
"<url>\n"
"\n"
" Returns the HTML <title>...</title> of a URL.\n"
" "
msgstr ""
#: plugin.py:188
msgid "That URL appears to have no HTML title."
msgstr ""
#: plugin.py:190
msgid "That URL appears to have no HTML title within the first %i bytes."
msgstr ""
#: plugin.py:198
#, docstring
msgid ""
"<hostname|ip>\n"
"\n"
" Returns Netcraft.com's determination of what operating system and\n"
" webserver is running on the host given.\n"
" "
msgstr ""
#: plugin.py:212
msgid "No results found for %s."
msgstr ""
#: plugin.py:214
msgid "The format of page the was odd."
msgstr ""
#: plugin.py:219
#, docstring
msgid ""
"<text>\n"
"\n"
" Returns the URL quoted form of the text.\n"
" "
msgstr ""
#: plugin.py:228
#, docstring
msgid ""
"<text>\n"
"\n"
" Returns the text un-URL quoted.\n"
" "
msgstr ""
#: plugin.py:238
#, docstring
msgid ""
"<url>\n"
"\n"
" Returns the contents of <url>, or as much as is configured in\n"
" supybot.plugins.Web.fetch.maximum. If that configuration variable is\n"
" set to 0, this command will be effectively disabled.\n"
" "
msgstr ""
#: plugin.py:246
msgid "This command is disabled (supybot.plugins.Web.fetch.maximum is set to 0)."
msgstr ""

View File

@ -38,6 +38,8 @@ from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Web')
class Title(HTMLParser.HTMLParser):
entitydefs = htmlentitydefs.entitydefs.copy()
@ -107,6 +109,7 @@ class Web(callbacks.PluginRegexp):
titleSnarfer = urlSnarfer(titleSnarfer)
titleSnarfer.__doc__ = utils.web._httpUrlRe
@internationalizeDocstring
def headers(self, irc, msg, args, url):
"""<url>
@ -115,7 +118,7 @@ class Web(callbacks.PluginRegexp):
"""
fd = utils.web.getUrlFd(url)
try:
s = ', '.join([format('%s: %s', k, v)
s = ', '.join([format(_('%s: %s'), k, v)
for (k, v) in fd.headers.items()])
irc.reply(s)
finally:
@ -123,6 +126,7 @@ class Web(callbacks.PluginRegexp):
headers = wrap(headers, ['httpUrl'])
_doctypeRe = re.compile(r'(<!DOCTYPE[^>]+>)', re.M)
@internationalizeDocstring
def doctype(self, irc, msg, args, url):
"""<url>
@ -136,9 +140,10 @@ class Web(callbacks.PluginRegexp):
s = utils.str.normalizeWhitespace(m.group(0))
irc.reply(s)
else:
irc.reply('That URL has no specified doctype.')
irc.reply(_('That URL has no specified doctype.'))
doctype = wrap(doctype, ['httpUrl'])
@internationalizeDocstring
def size(self, irc, msg, args, url):
"""<url>
@ -149,20 +154,21 @@ class Web(callbacks.PluginRegexp):
try:
try:
size = fd.headers['Content-Length']
irc.reply(format('%u is %i bytes long.', url, size))
irc.reply(format(_('%u is %i bytes long.'), url, size))
except KeyError:
size = conf.supybot.protocols.http.peekSize()
s = fd.read(size)
if len(s) != size:
irc.reply(format('%u is %i bytes long.', url, len(s)))
irc.reply(format(_('%u is %i bytes long.'), url, len(s)))
else:
irc.reply(format('The server didn\'t tell me how long %u '
'is but it\'s longer than %i bytes.',
irc.reply(format(_('The server didn\'t tell me how long %u '
'is but it\'s longer than %i bytes.'),
url, size))
finally:
fd.close()
size = wrap(size, ['httpUrl'])
@internationalizeDocstring
def title(self, irc, msg, args, url):
"""<url>
@ -179,14 +185,15 @@ class Web(callbacks.PluginRegexp):
if parser.title:
irc.reply(utils.web.htmlToText(parser.title.strip()))
elif len(text) < size:
irc.reply('That URL appears to have no HTML title.')
irc.reply(_('That URL appears to have no HTML title.'))
else:
irc.reply(format('That URL appears to have no HTML title '
'within the first %i bytes.', size))
irc.reply(format(_('That URL appears to have no HTML title '
'within the first %i bytes.'), size))
title = wrap(title, ['httpUrl'])
_netcraftre = re.compile(r'td align="left">\s+<a[^>]+>(.*?)<a href',
re.S | re.I)
@internationalizeDocstring
def netcraft(self, irc, msg, args, hostname):
"""<hostname|ip>
@ -202,11 +209,12 @@ class Web(callbacks.PluginRegexp):
s = s.rstrip('-').strip()
irc.reply(s) # Snip off "the site"
elif 'We could not get any results' in html:
irc.reply('No results found for %s.' % hostname)
irc.reply(_('No results found for %s.') % hostname)
else:
irc.error('The format of page the was odd.')
irc.error(_('The format of page the was odd.'))
netcraft = wrap(netcraft, ['text'])
@internationalizeDocstring
def urlquote(self, irc, msg, args, text):
"""<text>
@ -215,6 +223,7 @@ class Web(callbacks.PluginRegexp):
irc.reply(utils.web.urlquote(text))
urlquote = wrap(urlquote, ['text'])
@internationalizeDocstring
def urlunquote(self, irc, msg, args, text):
"""<text>
@ -224,6 +233,7 @@ class Web(callbacks.PluginRegexp):
irc.reply(s)
urlunquote = wrap(urlunquote, ['text'])
@internationalizeDocstring
def fetch(self, irc, msg, args, url):
"""<url>
@ -233,8 +243,8 @@ class Web(callbacks.PluginRegexp):
"""
max = self.registryValue('fetch.maximum')
if not max:
irc.error('This command is disabled '
'(supybot.plugins.Web.fetch.maximum is set to 0).',
irc.error(_('This command is disabled '
'(supybot.plugins.Web.fetch.maximum is set to 0).'),
Raise=True)
fd = utils.web.getUrlFd(url)
irc.reply(fd.read(max))