Internationalize ChannelLogger, Ctcp, Dict, Dunno, Factoids

This commit is contained in:
Valentin Lorentz 2010-10-17 11:22:07 +02:00
parent ca23f946e5
commit d14bb0cc16
15 changed files with 571 additions and 63 deletions

View File

@ -30,6 +30,8 @@
import supybot.conf as conf import supybot.conf as conf
import supybot.registry as registry import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('ChannelLogger')
def configure(advanced): def configure(advanced):
# This will be called by supybot to configure this module. advanced is # This will be called by supybot to configure this module. advanced is
@ -41,50 +43,50 @@ def configure(advanced):
ChannelLogger = conf.registerPlugin('ChannelLogger') ChannelLogger = conf.registerPlugin('ChannelLogger')
conf.registerChannelValue(ChannelLogger, 'enable', conf.registerChannelValue(ChannelLogger, 'enable',
registry.Boolean(True, """Determines whether logging is enabled.""")) registry.Boolean(True, _("""Determines whether logging is enabled.""")))
conf.registerGlobalValue(ChannelLogger, 'flushImmediately', conf.registerGlobalValue(ChannelLogger, 'flushImmediately',
registry.Boolean(False, """Determines whether channel logfiles will be registry.Boolean(False, _("""Determines whether channel logfiles will be
flushed anytime they're written to, rather than being buffered by the flushed anytime they're written to, rather than being buffered by the
operating system.""")) operating system.""")))
conf.registerChannelValue(ChannelLogger, 'stripFormatting', conf.registerChannelValue(ChannelLogger, 'stripFormatting',
registry.Boolean(True, """Determines whether formatting characters (such registry.Boolean(True, _("""Determines whether formatting characters (such
as bolding, color, etc.) are removed when writing the logs to disk.""")) as bolding, color, etc.) are removed when writing the logs to disk.""")))
conf.registerChannelValue(ChannelLogger, 'timestamp', conf.registerChannelValue(ChannelLogger, 'timestamp',
registry.Boolean(True, """Determines whether the logs for this channel are registry.Boolean(True, _("""Determines whether the logs for this channel are
timestamped with the timestamp in supybot.log.timestampFormat.""")) timestamped with the timestamp in supybot.log.timestampFormat.""")))
conf.registerChannelValue(ChannelLogger, 'noLogPrefix', conf.registerChannelValue(ChannelLogger, 'noLogPrefix',
registry.String('[nolog]', """Determines what string a message should be registry.String('[nolog]', _("""Determines what string a message should be
prefixed with in order not to be logged. If you don't want any such prefixed with in order not to be logged. If you don't want any such
prefix, just set it to the empty string.""")) prefix, just set it to the empty string.""")))
conf.registerChannelValue(ChannelLogger, 'rotateLogs', conf.registerChannelValue(ChannelLogger, 'rotateLogs',
registry.Boolean(False, """Determines whether the bot will automatically registry.Boolean(False, _("""Determines whether the bot will automatically
rotate the logs for this channel. The bot will rotate logs when the rotate the logs for this channel. The bot will rotate logs when the
timestamp for the log changes. The timestamp is set according to timestamp for the log changes. The timestamp is set according to
the 'filenameTimestamp' configuration variable.""")) the 'filenameTimestamp' configuration variable.""")))
conf.registerChannelValue(ChannelLogger, 'filenameTimestamp', conf.registerChannelValue(ChannelLogger, 'filenameTimestamp',
registry.String('%Y-%m-%d', """Determines how to represent the timestamp registry.String('%Y-%m-%d', _("""Determines how to represent the timestamp
used for the filename in rotated logs. When this timestamp changes, the used for the filename in rotated logs. When this timestamp changes, the
old logfiles will be closed and a new one started. The format characters old logfiles will be closed and a new one started. The format characters
for the timestamp are in the time.strftime docs at python.org. In order for the timestamp are in the time.strftime docs at python.org. In order
for your logs to be rotated, you'll also have to enable for your logs to be rotated, you'll also have to enable
supybot.plugins.ChannelLogger.rotateLogs.""")) supybot.plugins.ChannelLogger.rotateLogs.""")))
conf.registerGlobalValue(ChannelLogger, 'directories', conf.registerGlobalValue(ChannelLogger, 'directories',
registry.Boolean(True, """Determines whether the bot will partition its registry.Boolean(True, _("""Determines whether the bot will partition its
channel logs into separate directories based on different criteria.""")) channel logs into separate directories based on different criteria.""")))
conf.registerGlobalValue(ChannelLogger.directories, 'network', conf.registerGlobalValue(ChannelLogger.directories, 'network',
registry.Boolean(True, """Determines whether the bot will use a network registry.Boolean(True, _("""Determines whether the bot will use a network
directory if using directories.""")) directory if using directories.""")))
conf.registerGlobalValue(ChannelLogger.directories, 'channel', conf.registerGlobalValue(ChannelLogger.directories, 'channel',
registry.Boolean(True, """Determines whether the bot will use a channel registry.Boolean(True, _("""Determines whether the bot will use a channel
directory if using directories.""")) directory if using directories.""")))
conf.registerGlobalValue(ChannelLogger.directories, 'timestamp', conf.registerGlobalValue(ChannelLogger.directories, 'timestamp',
registry.Boolean(False, """Determines whether the bot will use a timestamp registry.Boolean(False, _("""Determines whether the bot will use a timestamp
(determined by supybot.plugins.ChannelLogger.directories.timestamp.format) (determined by supybot.plugins.ChannelLogger.directories.timestamp.format)
if using directories.""")) if using directories.""")))
conf.registerGlobalValue(ChannelLogger.directories.timestamp, 'format', conf.registerGlobalValue(ChannelLogger.directories.timestamp, 'format',
registry.String('%B', """Determines what timestamp format will be used in registry.String('%B', _("""Determines what timestamp format will be used in
the directory stucture for channel logs if the directory stucture for channel logs if
supybot.plugins.ChannelLogger.directories.timestamp is True.""")) supybot.plugins.ChannelLogger.directories.timestamp is True.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

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-17 10:02+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 logging is enabled."
msgstr ""
#: config.py:48
msgid ""
"Determines whether channel logfiles will be\n"
" flushed anytime they're written to, rather than being buffered by the\n"
" operating system."
msgstr ""
#: config.py:52
msgid ""
"Determines whether formatting characters (such\n"
" as bolding, color, etc.) are removed when writing the logs to disk."
msgstr ""
#: config.py:55
msgid ""
"Determines whether the logs for this channel are\n"
" timestamped with the timestamp in supybot.log.timestampFormat."
msgstr ""
#: config.py:58
msgid ""
"Determines what string a message should be\n"
" prefixed with in order not to be logged. If you don't want any such\n"
" prefix, just set it to the empty string."
msgstr ""
#: config.py:62
msgid ""
"Determines whether the bot will automatically\n"
" rotate the logs for this channel. The bot will rotate logs when the\n"
" timestamp for the log changes. The timestamp is set according to\n"
" the 'filenameTimestamp' configuration variable."
msgstr ""
#: config.py:67
msgid ""
"Determines how to represent the timestamp\n"
" used for the filename in rotated logs. When this timestamp changes, the\n"
" old logfiles will be closed and a new one started. The format characters\n"
" for the timestamp are in the time.strftime docs at python.org. In order\n"
" for your logs to be rotated, you'll also have to enable\n"
" supybot.plugins.ChannelLogger.rotateLogs."
msgstr ""
#: config.py:75
msgid ""
"Determines whether the bot will partition its\n"
" channel logs into separate directories based on different criteria."
msgstr ""
#: config.py:78
msgid ""
"Determines whether the bot will use a network\n"
" directory if using directories."
msgstr ""
#: config.py:81
msgid ""
"Determines whether the bot will use a channel\n"
" directory if using directories."
msgstr ""
#: config.py:84
msgid ""
"Determines whether the bot will use a timestamp\n"
" (determined by supybot.plugins.ChannelLogger.directories.timestamp.format)\n"
" if using directories."
msgstr ""
#: config.py:88
msgid ""
"Determines what timestamp format will be used in\n"
" the directory stucture for channel logs if\n"
" supybot.plugins.ChannelLogger.directories.timestamp is True."
msgstr ""

View File

@ -39,6 +39,8 @@ import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.registry as registry import supybot.registry as registry
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('ChannelLogger')
class FakeLog(object): class FakeLog(object):
def flush(self): def flush(self):

View File

@ -29,6 +29,8 @@
import supybot.conf as conf import supybot.conf as conf
import supybot.registry as registry import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Ctcp')
def configure(advanced): def configure(advanced):
# This will be called by supybot to configure this module. advanced is # This will be called by supybot to configure this module. advanced is

64
plugins/Ctcp/messages.pot Normal file
View File

@ -0,0 +1,64 @@
# 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-17 10:16+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:77
#, docstring
msgid "\001PING ?(.*)\001"
msgstr ""
#: plugin.py:86
#, docstring
msgid "\001VERSION\001"
msgstr ""
#: plugin.py:91
#, docstring
msgid "\001USERINFO\001"
msgstr ""
#: plugin.py:96
#, docstring
msgid "\001TIME\001"
msgstr ""
#: plugin.py:101
#, docstring
msgid "\001FINGER\001"
msgstr ""
#: plugin.py:104
msgid "FINGER Supybot, the best Python IRC bot in existence!"
msgstr ""
#: plugin.py:107
#, docstring
msgid "\001SOURCE\001"
msgstr ""
#: plugin.py:123
#, docstring
msgid ""
"[<channel>] [--nicks]\n"
"\n"
" Sends a CTCP VERSION to <channel>, returning the various\n"
" version strings returned. It waits for 10 seconds before returning\n"
" the versions received at that point. If --nicks is given, nicks are\n"
" associated with the version strings; otherwise, only the version\n"
" strings are given.\n"
" "
msgstr ""

View File

@ -36,6 +36,8 @@ import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.schedule as schedule import supybot.schedule as schedule
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Ctcp')
class Ctcp(callbacks.PluginRegexp): class Ctcp(callbacks.PluginRegexp):
public = False public = False
@ -99,7 +101,7 @@ class Ctcp(callbacks.PluginRegexp):
"\x01FINGER\x01" "\x01FINGER\x01"
self.log.info('Received CTCP FINGER from %s', msg.prefix) self.log.info('Received CTCP FINGER from %s', msg.prefix)
self._reply(irc, msg, self._reply(irc, msg,
'FINGER Supybot, the best Python IRC bot in existence!') _('FINGER Supybot, the best Python IRC bot in existence!'))
def ctcpSource(self, irc, msg, match): def ctcpSource(self, irc, msg, match):
"\x01SOURCE\x01" "\x01SOURCE\x01"
@ -116,6 +118,7 @@ class Ctcp(callbacks.PluginRegexp):
if version == 'VERSION': if version == 'VERSION':
self.versions.setdefault(payload, []).append(msg.nick) self.versions.setdefault(payload, []).append(msg.nick)
@internationalizeDocstring
def version(self, irc, msg, args, channel, optlist): def version(self, irc, msg, args, channel, optlist):
"""[<channel>] [--nicks] """[<channel>] [--nicks]

View File

@ -29,22 +29,24 @@
import supybot.conf as conf import supybot.conf as conf
import supybot.registry as registry import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Dict')
def configure(advanced): def configure(advanced):
from supybot.questions import output, expect, anything, something, yn from supybot.questions import output, expect, anything, something, yn
conf.registerPlugin('Dict', True) conf.registerPlugin('Dict', True)
output('The default dictd server is dict.org.') output(_('The default dictd server is dict.org.'))
if yn('Would you like to specify a different dictd server?'): if yn(_('Would you like to specify a different dictd server?')):
server = something('What server?') server = something('What server?')
conf.supybot.plugins.Dict.server.set(server) conf.supybot.plugins.Dict.server.set(server)
Dict = conf.registerPlugin('Dict') Dict = conf.registerPlugin('Dict')
conf.registerGlobalValue(Dict, 'server', conf.registerGlobalValue(Dict, 'server',
registry.String('dict.org', """Determines what server the bot will registry.String('dict.org', _("""Determines what server the bot will
retrieve definitions from.""")) retrieve definitions from.""")))
conf.registerChannelValue(Dict, 'default', conf.registerChannelValue(Dict, 'default',
registry.String('', """Determines the default dictionary the bot will registry.String('', _("""Determines the default dictionary the bot will
ask for definitions in. If this value is '*' (without the quotes) the bot ask for definitions in. If this value is '*' (without the quotes) the bot
will use all dictionaries to define words.""")) will use all dictionaries to define words.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

82
plugins/Dict/messages.pot Normal file
View File

@ -0,0 +1,82 @@
# 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-17 10: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:38
msgid "The default dictd server is dict.org."
msgstr ""
#: config.py:39
msgid "Would you like to specify a different dictd server?"
msgstr ""
#: config.py:45
msgid ""
"Determines what server the bot will\n"
" retrieve definitions from."
msgstr ""
#: config.py:48
msgid ""
"Determines the default dictionary the bot will\n"
" ask for definitions in. If this value is '*' (without the quotes) the bot\n"
" will use all dictionaries to define words."
msgstr ""
#: plugin.py:52
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns the dictionaries valid for the dict command.\n"
" "
msgstr ""
#: plugin.py:68
#, docstring
msgid ""
"takes no arguments\n"
"\n"
" Returns a random valid dictionary.\n"
" "
msgstr ""
#: plugin.py:83
#, docstring
msgid ""
"[<dictionary>] <word>\n"
"\n"
" Looks up the definition of <word> on the dictd server specified by\n"
" the supybot.plugins.Dict.server config variable.\n"
" "
msgstr ""
#: plugin.py:106
msgid "You must give a word to define."
msgstr ""
#: plugin.py:112
msgid "No definition for %q could be found."
msgstr ""
#: plugin.py:115
msgid "No definition for %q could be found in %s"
msgstr ""
#: plugin.py:127
msgid "%L responded: %s"
msgstr ""

View File

@ -35,6 +35,8 @@ import supybot.utils as utils
from supybot.commands import * from supybot.commands import *
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Dict')
try: try:
dictclient = utils.python.universalImport('dictclient', 'local.dictclient') dictclient = utils.python.universalImport('dictclient', 'local.dictclient')
@ -45,6 +47,7 @@ except ImportError:
class Dict(callbacks.Plugin): class Dict(callbacks.Plugin):
threaded = True threaded = True
@internationalizeDocstring
def dictionaries(self, irc, msg, args): def dictionaries(self, irc, msg, args):
"""takes no arguments """takes no arguments
@ -60,6 +63,7 @@ class Dict(callbacks.Plugin):
irc.error(utils.web.strError(e)) irc.error(utils.web.strError(e))
dictionaries = wrap(dictionaries) dictionaries = wrap(dictionaries)
@internationalizeDocstring
def random(self, irc, msg, args): def random(self, irc, msg, args):
"""takes no arguments """takes no arguments
@ -74,6 +78,7 @@ class Dict(callbacks.Plugin):
irc.error(utils.web.strError(e)) irc.error(utils.web.strError(e))
random = wrap(random) random = wrap(random)
@internationalizeDocstring
def dict(self, irc, msg, args, words): def dict(self, irc, msg, args, words):
"""[<dictionary>] <word> """[<dictionary>] <word>
@ -98,16 +103,17 @@ class Dict(callbacks.Plugin):
'dictionary: %s.', msg.args[0], default) 'dictionary: %s.', msg.args[0], default)
dictionary = '*' dictionary = '*'
if not words: if not words:
irc.error('You must give a word to define.', Raise=True) irc.error(_('You must give a word to define.'), Raise=True)
word = ' '.join(words) word = ' '.join(words)
definitions = conn.define(dictionary, word) definitions = conn.define(dictionary, word)
dbs = set() dbs = set()
if not definitions: if not definitions:
if dictionary == '*': if dictionary == '*':
irc.reply(format('No definition for %q could be found.', word)) irc.reply(format(_('No definition for %q could be found.'),
word))
else: else:
irc.reply(format('No definition for %q could be found in %s', irc.reply(format(_('No definition for %q could be found in '
word, ircutils.bold(dictionary))) '%s'), word, ircutils.bold(dictionary)))
return return
L = [] L = []
for d in definitions: for d in definitions:
@ -118,7 +124,7 @@ class Dict(callbacks.Plugin):
L.append('%s: %s' % (db, s)) L.append('%s: %s' % (db, s))
utils.sortBy(len, L) utils.sortBy(len, L)
if dictionary == '*' and len(dbs) > 1: if dictionary == '*' and len(dbs) > 1:
s = format('%L responded: %s', list(dbs), '; '.join(L)) s = format(_('%L responded: %s'), list(dbs), '; '.join(L))
else: else:
s = '; '.join(L) s = '; '.join(L)
irc.reply(s) irc.reply(s)

View File

@ -29,6 +29,8 @@
import supybot.conf as conf import supybot.conf as conf
import supybot.registry as registry import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Dunno')
def configure(advanced): def configure(advanced):
# This will be called by supybot to configure this module. advanced is # This will be called by supybot to configure this module. advanced is
@ -41,8 +43,8 @@ def configure(advanced):
Dunno = conf.registerPlugin('Dunno') Dunno = conf.registerPlugin('Dunno')
conf.registerChannelValue(Dunno, 'prefixNick', conf.registerChannelValue(Dunno, 'prefixNick',
registry.Boolean(True, """Determines whether the bot will prefix the nick registry.Boolean(True, _("""Determines whether the bot will prefix the nick
of the user giving an invalid command to the "dunno" response.""")) of the user giving an invalid command to the "dunno" response.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

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-17 10:48+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 bot will prefix the nick\n"
" of the user giving an invalid command to the \"dunno\" response."
msgstr ""
#: plugin.py:38
#, 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 'Error: <x> is not a valid command.'\n"
" messages with messages kept in a database, able to give more personable\n"
" responses."
msgstr ""

View File

@ -30,7 +30,10 @@
from supybot.commands import * from supybot.commands import *
import supybot.plugins as plugins import supybot.plugins as plugins
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Dunno')
@internationalizeDocstring
class Dunno(plugins.ChannelIdDatabasePlugin): class Dunno(plugins.ChannelIdDatabasePlugin):
"""This plugin was written initially to work with MoobotFactoids, the two """This plugin was written initially to work with MoobotFactoids, the two
of them to provide a similar-to-moobot-and-blootbot interface for factoids. of them to provide a similar-to-moobot-and-blootbot interface for factoids.

View File

@ -30,6 +30,8 @@
import supybot.conf as conf import supybot.conf as conf
import supybot.registry as registry import supybot.registry as registry
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Factoids')
def configure(advanced): def configure(advanced):
# This will be called by supybot to configure this module. advanced is # This will be called by supybot to configure this module. advanced is
@ -46,22 +48,22 @@ class FactoidFormat(registry.TemplatedString):
Factoids = conf.registerPlugin('Factoids') Factoids = conf.registerPlugin('Factoids')
conf.registerChannelValue(Factoids, 'learnSeparator', conf.registerChannelValue(Factoids, 'learnSeparator',
registry.String('as', """Determines what separator must be used in the registry.String('as', _("""Determines what separator must be used in the
learn command. Defaults to 'as' -- learn <key> as <value>. Users might learn command. Defaults to 'as' -- learn <key> as <value>. Users might
feel more comfortable with 'is' or something else, so it's feel more comfortable with 'is' or something else, so it's
configurable.""")) configurable.""")))
conf.registerChannelValue(Factoids, 'showFactoidIfOnlyOneMatch', conf.registerChannelValue(Factoids, 'showFactoidIfOnlyOneMatch',
registry.Boolean(True, """Determines whether the bot will reply with the registry.Boolean(True, _("""Determines whether the bot will reply with the
single matching factoid if only one factoid matches when using the search single matching factoid if only one factoid matches when using the search
command.""")) command.""")))
conf.registerChannelValue(Factoids, 'replyWhenInvalidCommand', conf.registerChannelValue(Factoids, 'replyWhenInvalidCommand',
registry.Boolean(True, """Determines whether the bot will reply to invalid registry.Boolean(True, _("""Determines whether the bot will reply to invalid
commands by searching for a factoid; basically making the whatis commands by searching for a factoid; basically making the whatis
unnecessary when you want all factoids for a given key.""")) unnecessary when you want all factoids for a given key.""")))
conf.registerChannelValue(Factoids, 'format', conf.registerChannelValue(Factoids, 'format',
FactoidFormat('$key could be $value.', """Determines the format of FactoidFormat('$key could be $value.', _("""Determines the format of
the response given when a factoid's value is requested. All the standard the response given when a factoid's value is requested. All the standard
substitutes apply, in addition to "$key" for the factoid's key and "$value" substitutes apply, in addition to "$key" for the factoid's key and "$value"
for the factoid's value.""")) for the factoid's value.""")))
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

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-17 10:59+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 $value, otherwise the factoid's value would be left\n"
" out."
msgstr ""
#: config.py:51
msgid ""
"Determines what separator must be used in the\n"
" learn command. Defaults to 'as' -- learn <key> as <value>. Users might\n"
" feel more comfortable with 'is' or something else, so it's\n"
" configurable."
msgstr ""
#: config.py:56
msgid ""
"Determines whether the bot will reply with the\n"
" single matching factoid if only one factoid matches when using the search\n"
" command."
msgstr ""
#: config.py:60
msgid ""
"Determines whether the bot will reply to invalid\n"
" commands by searching for a factoid; basically making the whatis\n"
" unnecessary when you want all factoids for a given key."
msgstr ""
#: config.py:64
msgid ""
"Determines the format of\n"
" the response given when a factoid's value is requested. All the standard\n"
" substitutes apply, in addition to \"$key\" for the factoid's key and \"$value\"\n"
" for the factoid's value."
msgstr ""
#: plugin.py:153
msgid ""
"[<channel>] <key> %s <value>\n"
"\n"
" Associates <key> with <value>. <channel> is only\n"
" necessary if the message isn't sent on the channel\n"
" itself. The word '%s' is necessary to separate the\n"
" key from the value. It can be changed to another word\n"
" via the learnSeparator registry value.\n"
" "
msgstr ""
#: plugin.py:179
msgid "That's not a valid number for that key."
msgstr ""
#: plugin.py:199 plugin.py:345
msgid "No factoid matches that key."
msgstr ""
#: plugin.py:211
#, docstring
msgid ""
"[<channel>] <key> [<number>]\n"
"\n"
" Looks up the value of <key> in the factoid database. If given a\n"
" number, will return only that exact factoid. <channel> is only\n"
" necessary if the message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:222 plugin.py:273 plugin.py:384
msgid "key id"
msgstr ""
#: plugin.py:230
#, docstring
msgid ""
"[<channel>] <key>\n"
"\n"
" Locks the factoid(s) associated with <key> so that they cannot be\n"
" removed or added to. <channel> is only necessary if the message isn't\n"
" sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:245
#, docstring
msgid ""
"[<channel>] <key>\n"
"\n"
" Unlocks the factoid(s) associated with <key> so that they can be\n"
" removed or added to. <channel> is only necessary if the message isn't\n"
" sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:260
#, docstring
msgid ""
"[<channel>] <key> [<number>|*]\n"
"\n"
" Removes the factoid <key> from the factoids database. If there are\n"
" more than one factoid with such a key, a number is necessary to\n"
" determine which one should be removed. A * can be used to remove all\n"
" factoids associated with a key. <channel> is only necessary if\n"
" the message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:285
msgid "There is no such factoid."
msgstr ""
#: plugin.py:298
msgid "Invalid factoid number."
msgstr ""
#: plugin.py:304
msgid "%s factoids have that key. Please specify which one to remove, or use * to designate all of them."
msgstr ""
#: plugin.py:312
#, docstring
msgid ""
"[<channel>]\n"
"\n"
" Returns a random factoid from the database for <channel>. <channel>\n"
" is only necessary if the message isn't sent in the channel itself.\n"
" "
msgstr ""
#: plugin.py:330
msgid "I couldn't find a factoid."
msgstr ""
#: plugin.py:335
#, docstring
msgid ""
"[<channel>] <key>\n"
"\n"
" Gives information about the factoid(s) associated with <key>.\n"
" <channel> is only necessary if the message isn't sent in the channel\n"
" itself.\n"
" "
msgstr ""
#: plugin.py:358
msgid "#%i was added by %s at %s"
msgstr ""
#: plugin.py:369
#, docstring
msgid ""
"[<channel>] <key> <number> <regexp>\n"
"\n"
" Changes the factoid #<number> associated with <key> according to\n"
" <regexp>.\n"
" "
msgstr ""
#: plugin.py:381
msgid "I couldn't find any key %q"
msgstr ""
#: plugin.py:396
#, docstring
msgid ""
"[<channel>] [--values] [--{regexp} <value>] [<glob> ...]\n"
"\n"
" Searches the keyspace for keys matching <glob>. If --regexp is given,\n"
" it associated value is taken as a regexp and matched against the keys.\n"
" If --values is given, search the value space instead of the keyspace.\n"
" "
msgstr ""
#: plugin.py:431
msgid "No keys matched that query."
msgstr ""
#: plugin.py:436
msgid "More than 100 keys matched that query; please narrow your query."
msgstr ""

View File

@ -39,6 +39,8 @@ from supybot.commands import *
import supybot.plugins as plugins import supybot.plugins as plugins
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
from supybot.i18n import PluginInternationalization, internationalizeDocstring
_ = PluginInternationalization('Factoids')
try: try:
import sqlite import sqlite
@ -148,14 +150,14 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
else: else:
irc.error('That factoid is locked.') irc.error('That factoid is locked.')
learn = wrap(learn, ['factoid']) learn = wrap(learn, ['factoid'])
learn._fake__doc__ = """[<channel>] <key> %s <value> learn._fake__doc__ = _("""[<channel>] <key> %s <value>
Associates <key> with <value>. <channel> is only Associates <key> with <value>. <channel> is only
necessary if the message isn't sent on the channel necessary if the message isn't sent on the channel
itself. The word '%s' is necessary to separate the itself. The word '%s' is necessary to separate the
key from the value. It can be changed to another word key from the value. It can be changed to another word
via the learnSeparator registry value. via the learnSeparator registry value.
""" """)
def _lookupFactoid(self, channel, key): def _lookupFactoid(self, channel, key):
@ -174,7 +176,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
try: try:
irc.reply(factoids[number-1]) irc.reply(factoids[number-1])
except IndexError: except IndexError:
irc.error('That\'s not a valid number for that key.') irc.error(_('That\'s not a valid number for that key.'))
return return
else: else:
env = {'key': key} env = {'key': key}
@ -194,7 +196,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
irc.replies(factoidsS, prefixer=prefixer, irc.replies(factoidsS, prefixer=prefixer,
joiner=', or ', onlyPrefixFirst=True) joiner=', or ', onlyPrefixFirst=True)
elif error: elif error:
irc.error('No factoid matches that key.') irc.error(_('No factoid matches that key.'))
def invalidCommand(self, irc, msg, tokens): def invalidCommand(self, irc, msg, tokens):
if irc.isChannel(msg.args[0]): if irc.isChannel(msg.args[0]):
@ -204,6 +206,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
factoids = self._lookupFactoid(channel, key) factoids = self._lookupFactoid(channel, key)
self._replyFactoids(irc, msg, key, factoids, error=False) self._replyFactoids(irc, msg, key, factoids, error=False)
@internationalizeDocstring
def whatis(self, irc, msg, args, channel, words): def whatis(self, irc, msg, args, channel, words):
"""[<channel>] <key> [<number>] """[<channel>] <key> [<number>]
@ -216,12 +219,13 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
if words[-1].isdigit(): if words[-1].isdigit():
number = int(words.pop()) number = int(words.pop())
if number <= 0: if number <= 0:
irc.errorInvalid('key id') irc.errorInvalid(_('key id'))
key = ' '.join(words) key = ' '.join(words)
factoids = self._lookupFactoid(channel, key) factoids = self._lookupFactoid(channel, key)
self._replyFactoids(irc, msg, key, factoids, number) self._replyFactoids(irc, msg, key, factoids, number)
whatis = wrap(whatis, ['channel', many('something')]) whatis = wrap(whatis, ['channel', many('something')])
@internationalizeDocstring
def lock(self, irc, msg, args, channel, key): def lock(self, irc, msg, args, channel, key):
"""[<channel>] <key> """[<channel>] <key>
@ -236,6 +240,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
irc.replySuccess() irc.replySuccess()
lock = wrap(lock, ['channel', 'text']) lock = wrap(lock, ['channel', 'text'])
@internationalizeDocstring
def unlock(self, irc, msg, args, channel, key): def unlock(self, irc, msg, args, channel, key):
"""[<channel>] <key> """[<channel>] <key>
@ -250,6 +255,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
irc.replySuccess() irc.replySuccess()
unlock = wrap(unlock, ['channel', 'text']) unlock = wrap(unlock, ['channel', 'text'])
@internationalizeDocstring
def forget(self, irc, msg, args, channel, words): def forget(self, irc, msg, args, channel, words):
"""[<channel>] <key> [<number>|*] """[<channel>] <key> [<number>|*]
@ -264,7 +270,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
if words[-1].isdigit(): if words[-1].isdigit():
number = int(words.pop()) number = int(words.pop())
if number <= 0: if number <= 0:
irc.errorInvalid('key id') irc.errorInvalid(_('key id'))
elif words[-1] == '*': elif words[-1] == '*':
words.pop() words.pop()
number = True number = True
@ -276,7 +282,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
WHERE key LIKE %s AND WHERE key LIKE %s AND
factoids.key_id=keys.id""", key) factoids.key_id=keys.id""", key)
if cursor.rowcount == 0: if cursor.rowcount == 0:
irc.error('There is no such factoid.') irc.error(_('There is no such factoid.'))
elif cursor.rowcount == 1 or number is True: elif cursor.rowcount == 1 or number is True:
(id, _) = cursor.fetchone() (id, _) = cursor.fetchone()
cursor.execute("""DELETE FROM factoids WHERE key_id=%s""", id) cursor.execute("""DELETE FROM factoids WHERE key_id=%s""", id)
@ -289,18 +295,19 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
try: try:
(_, id) = results[number-1] (_, id) = results[number-1]
except IndexError: except IndexError:
irc.error('Invalid factoid number.') irc.error(_('Invalid factoid number.'))
return return
cursor.execute("DELETE FROM factoids WHERE id=%s", id) cursor.execute("DELETE FROM factoids WHERE id=%s", id)
db.commit() db.commit()
irc.replySuccess() irc.replySuccess()
else: else:
irc.error('%s factoids have that key. ' irc.error(_('%s factoids have that key. '
'Please specify which one to remove, ' 'Please specify which one to remove, '
'or use * to designate all of them.' % 'or use * to designate all of them.') %
cursor.rowcount) cursor.rowcount)
forget = wrap(forget, ['channel', many('something')]) forget = wrap(forget, ['channel', many('something')])
@internationalizeDocstring
def random(self, irc, msg, args, channel): def random(self, irc, msg, args, channel):
"""[<channel>] """[<channel>]
@ -320,9 +327,10 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
L.append('"%s": %s' % (ircutils.bold(key), factoid)) L.append('"%s": %s' % (ircutils.bold(key), factoid))
irc.reply('; '.join(L)) irc.reply('; '.join(L))
else: else:
irc.error('I couldn\'t find a factoid.') irc.error(_('I couldn\'t find a factoid.'))
random = wrap(random, ['channel']) random = wrap(random, ['channel'])
@internationalizeDocstring
def info(self, irc, msg, args, channel, key): def info(self, irc, msg, args, channel, key):
"""[<channel>] <key> """[<channel>] <key>
@ -334,7 +342,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT id, locked FROM keys WHERE key LIKE %s", key) cursor.execute("SELECT id, locked FROM keys WHERE key LIKE %s", key)
if cursor.rowcount == 0: if cursor.rowcount == 0:
irc.error('No factoid matches that key.') irc.error(_('No factoid matches that key.'))
return return
(id, locked) = map(int, cursor.fetchone()) (id, locked) = map(int, cursor.fetchone())
cursor.execute("""SELECT added_by, added_at FROM factoids cursor.execute("""SELECT added_by, added_at FROM factoids
@ -347,7 +355,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
counter += 1 counter += 1
added_at = time.strftime(conf.supybot.reply.format.time(), added_at = time.strftime(conf.supybot.reply.format.time(),
time.localtime(int(added_at))) time.localtime(int(added_at)))
L.append(format('#%i was added by %s at %s', L.append(format(_('#%i was added by %s at %s'),
counter, added_by, added_at)) counter, added_by, added_at))
factoids = '; '.join(L) factoids = '; '.join(L)
s = format('Key %q is %s and has %n associated with it: %s', s = format('Key %q is %s and has %n associated with it: %s',
@ -356,6 +364,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
irc.reply(s) irc.reply(s)
info = wrap(info, ['channel', 'text']) info = wrap(info, ['channel', 'text'])
@internationalizeDocstring
def change(self, irc, msg, args, channel, key, number, replacer): def change(self, irc, msg, args, channel, key, number, replacer):
"""[<channel>] <key> <number> <regexp> """[<channel>] <key> <number> <regexp>
@ -369,10 +378,10 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
WHERE keys.key LIKE %s AND WHERE keys.key LIKE %s AND
keys.id=factoids.key_id""", key) keys.id=factoids.key_id""", key)
if cursor.rowcount == 0: if cursor.rowcount == 0:
irc.error(format('I couldn\'t find any key %q', key)) irc.error(format(_('I couldn\'t find any key %q'), key))
return return
elif cursor.rowcount < number: elif cursor.rowcount < number:
irc.errorInvalid('key id') irc.errorInvalid(_('key id'))
(id, fact) = cursor.fetchall()[number-1] (id, fact) = cursor.fetchall()[number-1]
newfact = replacer(fact) newfact = replacer(fact)
cursor.execute("UPDATE factoids SET fact=%s WHERE id=%s", newfact, id) cursor.execute("UPDATE factoids SET fact=%s WHERE id=%s", newfact, id)
@ -382,6 +391,7 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
'factoidId', 'regexpReplacer']) 'factoidId', 'regexpReplacer'])
_sqlTrans = string.maketrans('*?', '%_') _sqlTrans = string.maketrans('*?', '%_')
@internationalizeDocstring
def search(self, irc, msg, args, channel, optlist, globs): def search(self, irc, msg, args, channel, optlist, globs):
"""[<channel>] [--values] [--{regexp} <value>] [<glob> ...] """[<channel>] [--values] [--{regexp} <value>] [<glob> ...]
@ -418,13 +428,13 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
sql = sql.replace('TARGET', target) sql = sql.replace('TARGET', target)
cursor.execute(sql, formats) cursor.execute(sql, formats)
if cursor.rowcount == 0: if cursor.rowcount == 0:
irc.reply('No keys matched that query.') irc.reply(_('No keys matched that query.'))
elif cursor.rowcount == 1 and \ elif cursor.rowcount == 1 and \
self.registryValue('showFactoidIfOnlyOneMatch', channel): self.registryValue('showFactoidIfOnlyOneMatch', channel):
self.whatis(irc, msg, [channel, cursor.fetchone()[0]]) self.whatis(irc, msg, [channel, cursor.fetchone()[0]])
elif cursor.rowcount > 100: elif cursor.rowcount > 100:
irc.reply('More than 100 keys matched that query; ' irc.reply(_('More than 100 keys matched that query; '
'please narrow your query.') 'please narrow your query.'))
else: else:
keys = [repr(t[0]) for t in cursor.fetchall()] keys = [repr(t[0]) for t in cursor.fetchall()]
s = format('%L', keys) s = format('%L', keys)