mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-29 22:29:24 +01:00
Creating the internationalization module and internationalize/localize ChannelStats into French
This commit is contained in:
parent
26a458b9ec
commit
50acd3d8d9
155
plugins/ChannelStats/ChannelStats.pot
Normal file
155
plugins/ChannelStats/ChannelStats.pot
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2010-10-06 16:16+0200\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"
|
||||||
|
"Language: \n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=CHARSET\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: plugin.py:252
|
||||||
|
msgid "I couldn't find you in my user database."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:265
|
||||||
|
msgid ""
|
||||||
|
"%s has sent %n; a total of %n, %n, %n, and %n; %s of those messages %s. %s "
|
||||||
|
"has joined %n, parted %n, quit %n, kicked someone %n, been kicked %n, "
|
||||||
|
"changed the topic %n, and changed the mode %n."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:272
|
||||||
|
msgid "character"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:273 plugin.py:355
|
||||||
|
msgid "word"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:274 plugin.py:356
|
||||||
|
msgid "smiley"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:275 plugin.py:357
|
||||||
|
msgid "frown"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:277 plugin.py:358
|
||||||
|
msgid "was an ACTION"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:278 plugin.py:359
|
||||||
|
msgid "were ACTIONs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:280 plugin.py:281 plugin.py:282 plugin.py:283 plugin.py:284
|
||||||
|
#: plugin.py:285 plugin.py:286
|
||||||
|
msgid "time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:289
|
||||||
|
#, python-format
|
||||||
|
msgid "I have no stats for that %s in %s."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:291
|
||||||
|
msgid ""
|
||||||
|
"[<channel>] [<name>]\n"
|
||||||
|
"\n"
|
||||||
|
" Returns the statistics for <name> on <channel>. <channel> is only\n"
|
||||||
|
" necessary if the message isn't sent on the channel itself. If "
|
||||||
|
"<name>\n"
|
||||||
|
" isn't given, it defaults to the user sending the command.\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:305
|
||||||
|
msgid ""
|
||||||
|
"There's really no reason why you should have underscores or brackets in your "
|
||||||
|
"mathematical expression. Please remove them."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:309
|
||||||
|
msgid "You can't use lambda in this command."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:323
|
||||||
|
msgid "stat variable"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:335
|
||||||
|
msgid ""
|
||||||
|
"[<channel>] <stat expression>\n"
|
||||||
|
"\n"
|
||||||
|
" Returns the ranking of users according to the given stat "
|
||||||
|
"expression.\n"
|
||||||
|
" Valid variables in the stat expression include 'msgs', 'chars',\n"
|
||||||
|
" 'words', 'smileys', 'frowns', 'actions', 'joins', 'parts', 'quits',\n"
|
||||||
|
" 'kicks', 'kicked', 'topics', and 'modes'. Any simple mathematical\n"
|
||||||
|
" expression involving those variables is permitted.\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:349
|
||||||
|
msgid ""
|
||||||
|
"On %s there %h been %i messages, containing %i characters, %n, %n, and %n; "
|
||||||
|
"%i of those messages %s. There have been %n, %n, %n, %n, %n, and %n. There "
|
||||||
|
"%b currently %n and the channel has peaked at %n."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:360
|
||||||
|
msgid "join"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:361
|
||||||
|
msgid "part"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:362
|
||||||
|
msgid "quit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:363
|
||||||
|
msgid "kick"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:364
|
||||||
|
msgid "mode"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:364 plugin.py:365
|
||||||
|
msgid "change"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:365
|
||||||
|
msgid "topic"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:367 plugin.py:368
|
||||||
|
msgid "user"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:371
|
||||||
|
#, python-format
|
||||||
|
msgid "I've never been on %s."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: plugin.py:372
|
||||||
|
msgid ""
|
||||||
|
"[<channel>]\n"
|
||||||
|
"\n"
|
||||||
|
" Returns the statistics for <channel>. <channel> is only necessary "
|
||||||
|
"if\n"
|
||||||
|
" the message isn't sent on the channel itself.\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
167
plugins/ChannelStats/locale/fr.po
Normal file
167
plugins/ChannelStats/locale/fr.po
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
# French translations for supybot-i package
|
||||||
|
# Traductions françaises du paquet supybot-i.
|
||||||
|
# Copyright (C) 2010 THE supybot-i'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the supybot-i package.
|
||||||
|
# ProgVal <progval@gmail.com>, 2010.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: supybot-i 18n\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2010-10-06 16:16+0200\n"
|
||||||
|
"PO-Revision-Date: 2010-10-06 16:46+0100\n"
|
||||||
|
"Last-Translator: Valentin 'ProgVal' Lorentz <progval@gmail.com>\n"
|
||||||
|
"Language-Team: French\n"
|
||||||
|
"Language: fr\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
|
|
||||||
|
#: plugin.py:252
|
||||||
|
msgid "I couldn't find you in my user database."
|
||||||
|
msgstr "Je ne peux vous trouver dans ma base de données."
|
||||||
|
|
||||||
|
#: plugin.py:265
|
||||||
|
msgid "%s has sent %n; a total of %n, %n, %n, and %n; %s of those messages %s. %s has joined %n, parted %n, quit %n, kicked someone %n, been kicked %n, changed the topic %n, and changed the mode %n."
|
||||||
|
msgstr "%s a envoyé %n ; un total de %n, %n, %n, et %n ; %s de ces messages %s. %s est arrivé %nfois, est parti %nfois, a quitté %nfois, a kické %nfois, a été kické %nfois, a changé le topic %nfois, et a changé les modes %nfois."
|
||||||
|
|
||||||
|
#: plugin.py:272
|
||||||
|
msgid "character"
|
||||||
|
msgstr "caractère"
|
||||||
|
|
||||||
|
#: plugin.py:273
|
||||||
|
#: plugin.py:355
|
||||||
|
msgid "word"
|
||||||
|
msgstr "mot"
|
||||||
|
|
||||||
|
#: plugin.py:274
|
||||||
|
#: plugin.py:356
|
||||||
|
msgid "smiley"
|
||||||
|
msgstr "smiley"
|
||||||
|
|
||||||
|
#: plugin.py:275
|
||||||
|
#: plugin.py:357
|
||||||
|
msgid "frown"
|
||||||
|
msgstr "sadley"
|
||||||
|
|
||||||
|
#: plugin.py:277
|
||||||
|
#: plugin.py:358
|
||||||
|
msgid "was an ACTION"
|
||||||
|
msgstr "était une action"
|
||||||
|
|
||||||
|
#: plugin.py:278
|
||||||
|
#: plugin.py:359
|
||||||
|
msgid "were ACTIONs"
|
||||||
|
msgstr "étaient des ACTIONs"
|
||||||
|
|
||||||
|
#: plugin.py:280
|
||||||
|
#: plugin.py:281
|
||||||
|
#: plugin.py:282
|
||||||
|
#: plugin.py:283
|
||||||
|
#: plugin.py:284
|
||||||
|
#: plugin.py:285
|
||||||
|
#: plugin.py:286
|
||||||
|
msgid "time"
|
||||||
|
msgstr " fois"
|
||||||
|
|
||||||
|
#: plugin.py:289
|
||||||
|
#, python-format
|
||||||
|
msgid "I have no stats for that %s in %s."
|
||||||
|
msgstr "Je n'ai pas de statistiques pour %s sur %s."
|
||||||
|
|
||||||
|
#: plugin.py:291
|
||||||
|
msgid ""
|
||||||
|
"[<channel>] [<name>]\n"
|
||||||
|
"\n"
|
||||||
|
" Returns the statistics for <name> on <channel>. <channel> is only\n"
|
||||||
|
" necessary if the message isn't sent on the channel itself. If <name>\n"
|
||||||
|
" isn't given, it defaults to the user sending the command.\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"[canal>] [nom]\n"
|
||||||
|
"\n"
|
||||||
|
" Retourne les statistiques pour <nom> sur le <canal>. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même. Si <nom> n'est pas donné, il correspond par défaut à l'utilisateur envoyant la commande"
|
||||||
|
|
||||||
|
#: plugin.py:305
|
||||||
|
msgid "There's really no reason why you should have underscores or brackets in your mathematical expression. Please remove them."
|
||||||
|
msgstr "Il n'y a aucune raison pour que vous ayez des underscores ou des crochets dans vos expressions mathématiques. Veuillez les supprimer."
|
||||||
|
|
||||||
|
#: plugin.py:309
|
||||||
|
msgid "You can't use lambda in this command."
|
||||||
|
msgstr "Vous ne pouvez utiliser lambda dans cette commande."
|
||||||
|
|
||||||
|
#: plugin.py:323
|
||||||
|
msgid "stat variable"
|
||||||
|
msgstr "Variable statistique"
|
||||||
|
|
||||||
|
#: plugin.py:335
|
||||||
|
msgid ""
|
||||||
|
"[<channel>] <stat expression>\n"
|
||||||
|
"\n"
|
||||||
|
" Returns the ranking of users according to the given stat expression.\n"
|
||||||
|
" Valid variables in the stat expression include 'msgs', 'chars',\n"
|
||||||
|
" 'words', 'smileys', 'frowns', 'actions', 'joins', 'parts', 'quits',\n"
|
||||||
|
" 'kicks', 'kicked', 'topics', and 'modes'. Any simple mathematical\n"
|
||||||
|
" expression involving those variables is permitted.\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"[<canal>] <expression de statistiques>\n"
|
||||||
|
"\n"
|
||||||
|
"Retourne le rang des utilisateurs en fonction de l'expression de statistiques données. Les variables valides dans l'expression de statistiques sont : 'msgs', 'chars', 'words', 'smileys', 'frowns', 'actions', 'joins', 'parts', 'quits', 'kicks', 'kicked', 'topics', et 'modes'. Toute expression mathématiques simple utilisant ces variables est autorisée."
|
||||||
|
|
||||||
|
#: plugin.py:349
|
||||||
|
msgid "On %s there %h been %i messages, containing %i characters, %n, %n, and %n; %i of those messages %s. There have been %n, %n, %n, %n, %n, and %n. There %b currently %n and the channel has peaked at %n."
|
||||||
|
msgstr "Sur %s il y a eu%v %i messages, contenant %i caractères, %n, %n, et %n ; %i de ces messages %s. Il y a eu %n, %n, %n, %n, %n, et %n. Il y a%v actuellement %n et le record du canal est de %n."
|
||||||
|
|
||||||
|
#: plugin.py:360
|
||||||
|
msgid "join"
|
||||||
|
msgstr "arrivée"
|
||||||
|
|
||||||
|
#: plugin.py:361
|
||||||
|
msgid "part"
|
||||||
|
msgstr "départ"
|
||||||
|
|
||||||
|
#: plugin.py:362
|
||||||
|
msgid "quit"
|
||||||
|
msgstr "quit"
|
||||||
|
|
||||||
|
#: plugin.py:363
|
||||||
|
msgid "kick"
|
||||||
|
msgstr "kick"
|
||||||
|
|
||||||
|
#: plugin.py:364
|
||||||
|
msgid "mode"
|
||||||
|
msgstr "mode"
|
||||||
|
|
||||||
|
#: plugin.py:364
|
||||||
|
#: plugin.py:365
|
||||||
|
msgid "change"
|
||||||
|
msgstr "changement"
|
||||||
|
|
||||||
|
#: plugin.py:365
|
||||||
|
msgid "topic"
|
||||||
|
msgstr "topic"
|
||||||
|
|
||||||
|
#: plugin.py:367
|
||||||
|
#: plugin.py:368
|
||||||
|
msgid "user"
|
||||||
|
msgstr "utilisateur"
|
||||||
|
|
||||||
|
#: plugin.py:371
|
||||||
|
#, python-format
|
||||||
|
msgid "I've never been on %s."
|
||||||
|
msgstr "Je n'ai jamais été sur %s."
|
||||||
|
|
||||||
|
#: plugin.py:372
|
||||||
|
msgid ""
|
||||||
|
"[<channel>]\n"
|
||||||
|
"\n"
|
||||||
|
" Returns the statistics for <channel>. <channel> is only necessary if\n"
|
||||||
|
" the message isn't sent on the channel itself.\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"[canal]\n"
|
||||||
|
"\n"
|
||||||
|
"Retourne les statistiques pour le <canal>. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||||
|
|
@ -34,6 +34,7 @@ import types
|
|||||||
|
|
||||||
import supybot.log as log
|
import supybot.log as log
|
||||||
import supybot.conf as conf
|
import supybot.conf as conf
|
||||||
|
import supybot.i18n as i18n
|
||||||
import supybot.utils as utils
|
import supybot.utils as utils
|
||||||
import supybot.world as world
|
import supybot.world as world
|
||||||
import supybot.ircdb as ircdb
|
import supybot.ircdb as ircdb
|
||||||
@ -44,6 +45,8 @@ 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
|
||||||
|
|
||||||
|
_ = i18n.PluginInternationalization('ChannelStats')
|
||||||
|
|
||||||
class ChannelStat(irclib.IrcCommandDispatcher):
|
class ChannelStat(irclib.IrcCommandDispatcher):
|
||||||
_values = ['actions', 'chars', 'frowns', 'joins', 'kicks','modes',
|
_values = ['actions', 'chars', 'frowns', 'joins', 'kicks','modes',
|
||||||
'msgs', 'parts', 'quits', 'smileys', 'topics', 'words', 'users']
|
'msgs', 'parts', 'quits', 'smileys', 'topics', 'words', 'users']
|
||||||
@ -239,12 +242,6 @@ class ChannelStats(callbacks.Plugin):
|
|||||||
self.db.channels[channel][id].kicked += 1
|
self.db.channels[channel][id].kicked += 1
|
||||||
|
|
||||||
def stats(self, irc, msg, args, channel, name):
|
def stats(self, irc, msg, args, channel, name):
|
||||||
"""[<channel>] [<name>]
|
|
||||||
|
|
||||||
Returns the statistics for <name> on <channel>. <channel> is only
|
|
||||||
necessary if the message isn't sent on the channel itself. If <name>
|
|
||||||
isn't given, it defaults to the user sending the command.
|
|
||||||
"""
|
|
||||||
if name and ircutils.strEqual(name, irc.nick):
|
if name and ircutils.strEqual(name, irc.nick):
|
||||||
id = 0
|
id = 0
|
||||||
elif not name:
|
elif not name:
|
||||||
@ -252,7 +249,7 @@ class ChannelStats(callbacks.Plugin):
|
|||||||
id = ircdb.users.getUserId(msg.prefix)
|
id = ircdb.users.getUserId(msg.prefix)
|
||||||
name = ircdb.users.getUser(id).name
|
name = ircdb.users.getUser(id).name
|
||||||
except KeyError:
|
except KeyError:
|
||||||
irc.error('I couldn\'t find you in my user database.')
|
irc.error(_('I couldn\'t find you in my user database.'))
|
||||||
return
|
return
|
||||||
elif not ircdb.users.hasUser(name):
|
elif not ircdb.users.hasUser(name):
|
||||||
try:
|
try:
|
||||||
@ -265,53 +262,51 @@ class ChannelStats(callbacks.Plugin):
|
|||||||
id = ircdb.users.getUserId(name)
|
id = ircdb.users.getUserId(name)
|
||||||
try:
|
try:
|
||||||
stats = self.db.getUserStats(channel, id)
|
stats = self.db.getUserStats(channel, id)
|
||||||
s = format('%s has sent %n; a total of %n, %n, '
|
s = format(_('%s has sent %n; a total of %n, %n, '
|
||||||
'%n, and %n; %s of those messages %s'
|
'%n, and %n; %s of those messages %s. '
|
||||||
'%s has joined %n, parted %n, quit %n, '
|
'%s has joined %n, parted %n, quit %n, '
|
||||||
'kicked someone %n, been kicked %n, '
|
'kicked someone %n, been kicked %n, '
|
||||||
'changed the topic %n, and changed the '
|
'changed the topic %n, and changed the '
|
||||||
'mode %n.',
|
'mode %n.'),
|
||||||
name, (stats.msgs, 'message'),
|
name, (stats.msgs, 'message'),
|
||||||
(stats.chars, 'character'),
|
(stats.chars, _('character')),
|
||||||
(stats.words, 'word'),
|
(stats.words, _('word')),
|
||||||
(stats.smileys, 'smiley'),
|
(stats.smileys, _('smiley')),
|
||||||
(stats.frowns, 'frown'),
|
(stats.frowns, _('frown')),
|
||||||
stats.actions,
|
stats.actions,
|
||||||
stats.actions == 1 and 'was an ACTION. '
|
stats.actions == 1 and _('was an ACTION')
|
||||||
or 'were ACTIONs. ',
|
or _('were ACTIONs'),
|
||||||
name,
|
name,
|
||||||
(stats.joins, 'time'),
|
(stats.joins, _('time')),
|
||||||
(stats.parts, 'time'),
|
(stats.parts, _('time')),
|
||||||
(stats.quits, 'time'),
|
(stats.quits, _('time')),
|
||||||
(stats.kicks, 'time'),
|
(stats.kicks, _('time')),
|
||||||
(stats.kicked, 'time'),
|
(stats.kicked, _('time')),
|
||||||
(stats.topics, 'time'),
|
(stats.topics, _('time')),
|
||||||
(stats.modes, 'time'))
|
(stats.modes, _('time')))
|
||||||
irc.reply(s)
|
irc.reply(s)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
irc.error(format('I have no stats for that %s in %s.',
|
irc.error(format(_('I have no stats for that %s in %s.'),
|
||||||
name, channel))
|
name, channel))
|
||||||
|
stats.__doc__ = _("""[<channel>] [<name>]
|
||||||
|
|
||||||
|
Returns the statistics for <name> on <channel>. <channel> is only
|
||||||
|
necessary if the message isn't sent on the channel itself. If <name>
|
||||||
|
isn't given, it defaults to the user sending the command.
|
||||||
|
""")
|
||||||
stats = wrap(stats, ['channeldb', additional('something')])
|
stats = wrap(stats, ['channeldb', additional('something')])
|
||||||
|
|
||||||
_env = {'__builtins__': types.ModuleType('__builtins__')}
|
_env = {'__builtins__': types.ModuleType('__builtins__')}
|
||||||
_env.update(math.__dict__)
|
_env.update(math.__dict__)
|
||||||
def rank(self, irc, msg, args, channel, expr):
|
def rank(self, irc, msg, args, channel, expr):
|
||||||
"""[<channel>] <stat expression>
|
|
||||||
|
|
||||||
Returns the ranking of users according to the given stat expression.
|
|
||||||
Valid variables in the stat expression include 'msgs', 'chars',
|
|
||||||
'words', 'smileys', 'frowns', 'actions', 'joins', 'parts', 'quits',
|
|
||||||
'kicks', 'kicked', 'topics', and 'modes'. Any simple mathematical
|
|
||||||
expression involving those variables is permitted.
|
|
||||||
"""
|
|
||||||
# XXX I could do this the right way, and abstract out a safe eval,
|
# XXX I could do this the right way, and abstract out a safe eval,
|
||||||
# or I could just copy/paste from the Math plugin.
|
# or I could just copy/paste from the Math plugin.
|
||||||
if expr != expr.translate(utils.str.chars, '_[]'):
|
if expr != expr.translate(utils.str.chars, '_[]'):
|
||||||
irc.error('There\'s really no reason why you should have '
|
irc.error(_('There\'s really no reason why you should have '
|
||||||
'underscores or brackets in your mathematical '
|
'underscores or brackets in your mathematical '
|
||||||
'expression. Please remove them.', Raise=True)
|
'expression. Please remove them.'), Raise=True)
|
||||||
if 'lambda' in expr:
|
if 'lambda' in expr:
|
||||||
irc.error('You can\'t use lambda in this command.', Raise=True)
|
irc.error(_('You can\'t use lambda in this command.'), Raise=True)
|
||||||
expr = expr.lower()
|
expr = expr.lower()
|
||||||
users = []
|
users = []
|
||||||
for ((c, id), stats) in self.db.items():
|
for ((c, id), stats) in self.db.items():
|
||||||
@ -325,7 +320,7 @@ class ChannelStats(callbacks.Plugin):
|
|||||||
except ZeroDivisionError:
|
except ZeroDivisionError:
|
||||||
v = float('inf')
|
v = float('inf')
|
||||||
except NameError, e:
|
except NameError, e:
|
||||||
irc.errorInvalid('stat variable', str(e).split()[1])
|
irc.errorInvalid(_('stat variable'), str(e).split()[1])
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
irc.error(utils.exnToString(e), Raise=True)
|
irc.error(utils.exnToString(e), Raise=True)
|
||||||
if id == 0:
|
if id == 0:
|
||||||
@ -337,40 +332,48 @@ class ChannelStats(callbacks.Plugin):
|
|||||||
s = utils.str.commaAndify(['#%s %s (%.3g)' % (i+1, u, v)
|
s = utils.str.commaAndify(['#%s %s (%.3g)' % (i+1, u, v)
|
||||||
for (i, (v, u)) in enumerate(users)])
|
for (i, (v, u)) in enumerate(users)])
|
||||||
irc.reply(s)
|
irc.reply(s)
|
||||||
|
rank.__doc__ = _("""[<channel>] <stat expression>
|
||||||
|
|
||||||
|
Returns the ranking of users according to the given stat expression.
|
||||||
|
Valid variables in the stat expression include 'msgs', 'chars',
|
||||||
|
'words', 'smileys', 'frowns', 'actions', 'joins', 'parts', 'quits',
|
||||||
|
'kicks', 'kicked', 'topics', and 'modes'. Any simple mathematical
|
||||||
|
expression involving those variables is permitted.
|
||||||
|
""")
|
||||||
rank = wrap(rank, ['channeldb', 'text'])
|
rank = wrap(rank, ['channeldb', 'text'])
|
||||||
|
|
||||||
def channelstats(self, irc, msg, args, channel):
|
def channelstats(self, irc, msg, args, channel):
|
||||||
"""[<channel>]
|
|
||||||
|
|
||||||
Returns the statistics for <channel>. <channel> is only necessary if
|
|
||||||
the message isn't sent on the channel itself.
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
stats = self.db.getChannelStats(channel)
|
stats = self.db.getChannelStats(channel)
|
||||||
curUsers = len(irc.state.channels[channel].users)
|
curUsers = len(irc.state.channels[channel].users)
|
||||||
s = format('On %s there %h been %i messages, containing %i '
|
s = format(_('On %s there %h been %i messages, containing %i '
|
||||||
'characters, %n, %n, and %n; '
|
'characters, %n, %n, and %n; '
|
||||||
'%i of those messages %s. There have been '
|
'%i of those messages %s. There have been '
|
||||||
'%n, %n, %n, %n, %n, and %n. There %b currently %n '
|
'%n, %n, %n, %n, %n, and %n. There %b currently %n '
|
||||||
'and the channel has peaked at %n.',
|
'and the channel has peaked at %n.'),
|
||||||
channel, stats.msgs, stats.msgs, stats.chars,
|
channel, stats.msgs, stats.msgs, stats.chars,
|
||||||
(stats.words, 'word'),
|
(stats.words, _('word')),
|
||||||
(stats.smileys, 'smiley'),
|
(stats.smileys, _('smiley')),
|
||||||
(stats.frowns, 'frown'),
|
(stats.frowns, _('frown')),
|
||||||
stats.actions, stats.actions == 1 and 'was an ACTION'
|
stats.actions, stats.actions == 1 and _('was an ACTION')
|
||||||
or 'were ACTIONs',
|
or _('were ACTIONs'),
|
||||||
(stats.joins, 'join'),
|
(stats.joins, _('join')),
|
||||||
(stats.parts, 'part'),
|
(stats.parts, _('part')),
|
||||||
(stats.quits, 'quit'),
|
(stats.quits, _('quit')),
|
||||||
(stats.kicks, 'kick'),
|
(stats.kicks, _('kick')),
|
||||||
(stats.modes, 'mode', 'change'),
|
(stats.modes, _('mode'), _('change')),
|
||||||
(stats.topics, 'topic', 'change'),
|
(stats.topics, _('topic'), _('change')),
|
||||||
curUsers,
|
curUsers,
|
||||||
(curUsers, 'user'),
|
(curUsers, _('user')),
|
||||||
(stats.users, 'user'))
|
(stats.users, _('user')))
|
||||||
irc.reply(s)
|
irc.reply(s)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
irc.error(format('I\'ve never been on %s.', channel))
|
irc.error(format(_('I\'ve never been on %s.'), channel))
|
||||||
|
channelstats.__doc__ = _("""[<channel>]
|
||||||
|
|
||||||
|
Returns the statistics for <channel>. <channel> is only necessary if
|
||||||
|
the message isn't sent on the channel itself.
|
||||||
|
""")
|
||||||
channelstats = wrap(channelstats, ['channeldb'])
|
channelstats = wrap(channelstats, ['channeldb'])
|
||||||
|
|
||||||
|
|
||||||
|
8
setup.py
8
setup.py
@ -113,8 +113,14 @@ package_dir = {'supybot': 'src',
|
|||||||
'plugins/Time/local/dateutil',
|
'plugins/Time/local/dateutil',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
package_data = {}
|
||||||
|
|
||||||
for plugin in plugins:
|
for plugin in plugins:
|
||||||
package_dir['supybot.plugins.' + plugin] = 'plugins/' + plugin
|
package_dir['supybot.plugins.' + plugin] = 'plugins/' + plugin
|
||||||
|
locale_path = 'plugins/' + plugin + '/locale/'
|
||||||
|
locale_name = 'supybot.plugins.'+plugin
|
||||||
|
if os.path.exists(locale_path):
|
||||||
|
package_data.update({locale_name: ['locale/'+s for s in os.listdir(locale_path)]})
|
||||||
|
|
||||||
version = '0.83.4.1+git'
|
version = '0.83.4.1+git'
|
||||||
setup(
|
setup(
|
||||||
@ -151,6 +157,8 @@ setup(
|
|||||||
|
|
||||||
package_dir=package_dir,
|
package_dir=package_dir,
|
||||||
|
|
||||||
|
package_data=package_data,
|
||||||
|
|
||||||
scripts=['scripts/supybot',
|
scripts=['scripts/supybot',
|
||||||
'scripts/supybot-test',
|
'scripts/supybot-test',
|
||||||
'scripts/supybot-botchk',
|
'scripts/supybot-botchk',
|
||||||
|
129
src/i18n.py
Normal file
129
src/i18n.py
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
###
|
||||||
|
# Copyright (c) 2010, Valentin Lorentz
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of the author of this software nor the name of
|
||||||
|
# contributors to this software may be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written consent.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
###
|
||||||
|
|
||||||
|
"""
|
||||||
|
Supybot internationalisation and localisation managment.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__all__ = ['PluginInternationalization']
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import supybot.conf as conf
|
||||||
|
|
||||||
|
WAITING_FOR_MSGID = 1
|
||||||
|
IN_MSGID = 2
|
||||||
|
WAITING_FOR_MSGSTR = 3
|
||||||
|
IN_MSGSTR = 4
|
||||||
|
|
||||||
|
MSGID = 'msgid "'
|
||||||
|
MSGSTR = 'msgstr "'
|
||||||
|
|
||||||
|
#registerGlobalValue(supybot, 'language',
|
||||||
|
# ValidNick('supybot', """Determines the bot's default language.
|
||||||
|
# Valid values are things like en, fr, de, etc."""))
|
||||||
|
|
||||||
|
def get_plugin_dir(plugin_name):
|
||||||
|
filename = sys.modules[plugin_name].__file__
|
||||||
|
if filename.endswith("plugin.pyc"):
|
||||||
|
return filename[0:-len("plugin.pyc")]
|
||||||
|
elif filename.endswith("plugin.py"):
|
||||||
|
return filename[0:-len("plugin.py")]
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
i18nClasses = {}
|
||||||
|
|
||||||
|
class PluginInternationalization:
|
||||||
|
"""Internationalization managment for a plugin."""
|
||||||
|
def __init__(self, name='supybot'):
|
||||||
|
self.name = name
|
||||||
|
self.load_locale('toto')
|
||||||
|
i18nClasses.update({name: self})
|
||||||
|
|
||||||
|
def load_locale(self, locale_name):
|
||||||
|
directory = get_plugin_dir(self.name) + 'locale/'
|
||||||
|
try:
|
||||||
|
translation_file = open('%s%s.po' % (directory, locale_name), 'ru')
|
||||||
|
except IOError: # The translation is unavailable
|
||||||
|
self.translations = {}
|
||||||
|
return
|
||||||
|
step = WAITING_FOR_MSGID
|
||||||
|
self.translations = {}
|
||||||
|
for line in translation_file:
|
||||||
|
line = line[0:-1] # Remove the ending \n
|
||||||
|
|
||||||
|
if line.startswith(MSGID):
|
||||||
|
# Don't check if step is WAITING_FOR_MSGID
|
||||||
|
untranslated = ''
|
||||||
|
translated = ''
|
||||||
|
data = line[len(MSGID):-1]
|
||||||
|
if len(data) == 0: # Multiline mode
|
||||||
|
step = IN_MSGID
|
||||||
|
else:
|
||||||
|
untranslated += data
|
||||||
|
step = WAITING_FOR_MSGSTR
|
||||||
|
|
||||||
|
|
||||||
|
elif step is IN_MSGID and line.startswith('"') and \
|
||||||
|
line.endswith('"'):
|
||||||
|
untranslated += line[1:-1]
|
||||||
|
elif step is IN_MSGID and untranslated == '': # Empty MSGID
|
||||||
|
step = WAITING_FOR_MSGID
|
||||||
|
elif step is IN_MSGID: # the MSGID is finished
|
||||||
|
step = WAITING_FOR_MSGSTR
|
||||||
|
|
||||||
|
|
||||||
|
if step is WAITING_FOR_MSGSTR and line.startswith(MSGSTR):
|
||||||
|
data = line[len(MSGSTR):-1]
|
||||||
|
if len(data) == 0: # Multiline mode
|
||||||
|
step = IN_MSGID
|
||||||
|
else:
|
||||||
|
self.translations.update({untranslated: data})
|
||||||
|
step = WAITING_FOR_MSGID
|
||||||
|
|
||||||
|
|
||||||
|
elif step is IN_MSGSTR and line.startswith('"') and \
|
||||||
|
line.endswith('"'):
|
||||||
|
untranslated += line[1:-1]
|
||||||
|
elif step is IN_MSGSTR: # the MSGSTR is finished
|
||||||
|
step = WAITING_FOR_MSGID
|
||||||
|
if translated == '':
|
||||||
|
translated = untranslated
|
||||||
|
self.translations.update({untranslated: translated})
|
||||||
|
|
||||||
|
def __call__(self, untranslated, *args):
|
||||||
|
if len(args) == 0:
|
||||||
|
try:
|
||||||
|
return self.translations[untranslated]
|
||||||
|
except KeyError:
|
||||||
|
return untranslated
|
||||||
|
else:
|
||||||
|
translation = self(untranslated)
|
||||||
|
return translation % args
|
||||||
|
|
@ -1,6 +1,7 @@
|
|||||||
###
|
###
|
||||||
# Copyright (c) 2002-2005, Jeremiah Fincher
|
# Copyright (c) 2002-2005, Jeremiah Fincher
|
||||||
# Copyright (c) 2008-2009, James Vega
|
# Copyright (c) 2008-2009, James Vega
|
||||||
|
# Copyright (c) 2010, Valentin Lorentz
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@ -362,7 +363,7 @@ def timestamp(t):
|
|||||||
t = time.time()
|
t = time.time()
|
||||||
return time.ctime(t)
|
return time.ctime(t)
|
||||||
|
|
||||||
_formatRe = re.compile('%((?:\d+)?\.\d+f|[bfhiLnpqrstu%])')
|
_formatRe = re.compile('%((?:\d+)?\.\d+f|[bfhiLnpqrstuv%])')
|
||||||
def format(s, *args, **kwargs):
|
def format(s, *args, **kwargs):
|
||||||
"""w00t.
|
"""w00t.
|
||||||
|
|
||||||
@ -379,6 +380,8 @@ def format(s, *args, **kwargs):
|
|||||||
n: nItems (takes a 2-tuple of (n, item) or a 3-tuple of (n, between, item))
|
n: nItems (takes a 2-tuple of (n, item) or a 3-tuple of (n, between, item))
|
||||||
t: time, formatted (takes an int)
|
t: time, formatted (takes an int)
|
||||||
u: url, wrapped in braces (this should be configurable at some point)
|
u: url, wrapped in braces (this should be configurable at some point)
|
||||||
|
v: void : takes one or many arguments, but doesn't display it
|
||||||
|
(useful for translation)
|
||||||
"""
|
"""
|
||||||
args = list(args)
|
args = list(args)
|
||||||
args.reverse() # For more efficient popping.
|
args.reverse() # For more efficient popping.
|
||||||
@ -429,6 +432,9 @@ def format(s, *args, **kwargs):
|
|||||||
return timestamp(args.pop())
|
return timestamp(args.pop())
|
||||||
elif char == 'u':
|
elif char == 'u':
|
||||||
return '<%s>' % args.pop()
|
return '<%s>' % args.pop()
|
||||||
|
elif char == 'v':
|
||||||
|
args.pop()
|
||||||
|
return ''
|
||||||
elif char == '%':
|
elif char == '%':
|
||||||
return '%'
|
return '%'
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user