mirror of https://github.com/Mikaela/Limnoria.git
Merge branch 'testing'
This commit is contained in:
commit
872e92eaff
|
@ -0,0 +1,226 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Finnish translation of Admin plugin in Supybot\n"
|
||||
"POT-Creation-Date: 2010-10-16 10:43+CEST\n"
|
||||
"PO-Revision-Date: 2011-02-28 14:51+0200\n"
|
||||
"Last-Translator: Mika Suomalainen <mika.henrik.mainio@hotmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
"X-Poedit-Language: Finnish\n"
|
||||
"X-Poedit-Country: FINLAND\n"
|
||||
|
||||
#: plugin.py:54
|
||||
msgid "Nick/channel temporarily unavailable."
|
||||
msgstr "Nimimerkki/kanava on väliaikaisesti saavutettavissa."
|
||||
|
||||
#: plugin.py:72
|
||||
msgid "Cannot join %s, it's full."
|
||||
msgstr "Ei voida liittyä %s, se on täynnä."
|
||||
|
||||
#: plugin.py:80
|
||||
msgid "Cannot join %s, I was not invited."
|
||||
msgstr "Ei voi liittyä %s, minua ei ole kutsuttu."
|
||||
|
||||
#: plugin.py:88
|
||||
msgid "Cannot join %s, it's banned me."
|
||||
msgstr "Ei voi liittyä %s, se on bannannut minut."
|
||||
|
||||
#: plugin.py:96
|
||||
msgid "Cannot join %s, my keyword was wrong."
|
||||
msgstr "Ei voi littyä %s, minun avainsanani oli väärä."
|
||||
|
||||
#: plugin.py:104
|
||||
msgid "Cannot join %s, I'm not identified with the NickServ."
|
||||
msgstr "Ei voi liittyä %s, minä en ole tunnistautunut NickServillä."
|
||||
|
||||
#: plugin.py:134
|
||||
msgid ""
|
||||
"<channel> [<key>]\n"
|
||||
"\n"
|
||||
" Tell the bot to join the given channel. If <key> is given, it is used\n"
|
||||
" when attempting to join the channel.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<kanava> [<avain>]\n"
|
||||
"\n"
|
||||
"Käskee botin liittyä annetulle kanavalle. Jos <avain> on annettu, sitä käytetään\n"
|
||||
"yrittäessä liittyä kanavalle.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:147
|
||||
msgid "I'm already too close to maximum number of channels for this network."
|
||||
msgstr "Minä olen liian lähellä kanavien maksimi määrää tällä verkolla."
|
||||
|
||||
#: plugin.py:156
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Returns the channels the bot is on. Must be given in private, in order\n"
|
||||
" to protect the secrecy of secret channels.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Ei ota parametrejä\n"
|
||||
"\n"
|
||||
"Palauttaa listan kanavista, joilla botti on. Täytyy antaa yksityisviestillä salaisten kanavien\n"
|
||||
"salaisuuden suojelemiseksi.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:166
|
||||
msgid "I'm not currently in any channels."
|
||||
msgstr "En juuri nyt ole millään kanavalla."
|
||||
|
||||
#: plugin.py:172
|
||||
msgid "My connection is restricted, I can't change nicks."
|
||||
msgstr "Minun yhteyteni on rajoitettu. En voi vaihtaa nimimerkkiä."
|
||||
|
||||
#: plugin.py:179
|
||||
msgid "Someone else is already using that nick."
|
||||
msgstr "Joku muu käyttää jo tuota nimimerkkiä."
|
||||
|
||||
#: plugin.py:186
|
||||
msgid "That nick is currently banned."
|
||||
msgstr "Se nimimerkki on juuri nyt bannattu."
|
||||
|
||||
#: plugin.py:193
|
||||
msgid "I can't change nicks, the server said %q."
|
||||
msgstr "Minä en voi vaihtaa nimimerkkiä, palvelin sanoi %q"
|
||||
|
||||
#: plugin.py:207
|
||||
msgid ""
|
||||
"[<nick>]\n"
|
||||
"\n"
|
||||
" Changes the bot's nick to <nick>. If no nick is given, returns the\n"
|
||||
" bot's current nick.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<nimimerkki>]\n"
|
||||
"\n"
|
||||
"Vaihtaa botin nimimerkin <nimimerkiksi>. Jos nimimerkkiä ei ole annettu, palauttaa\n"
|
||||
"botin nykyisen nimimerkin.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:222
|
||||
msgid ""
|
||||
"[<channel>] [<reason>]\n"
|
||||
"\n"
|
||||
" Tells the bot to part the list of channels you give it. <channel> is\n"
|
||||
" only necessary if you want the bot to part a channel other than the\n"
|
||||
" current channel. If <reason> is specified, use it as the part\n"
|
||||
" message.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [<syy>]\n"
|
||||
"\n"
|
||||
"Käskee botin poistua kanavilta, jotka annat sille. <kanava> on\n"
|
||||
"vaadittu jost tahdot botin poistuvat muulta, kuin \n"
|
||||
"nykyiseltä kanavalta. Jos <syy> on määritetty, sitä käytetään poistumis\n"
|
||||
"viestissä.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:240
|
||||
msgid "I'm not in %s."
|
||||
msgstr "Minä en ole %s:ssa."
|
||||
|
||||
#: plugin.py:252
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Gives the user specified by <name> (or the user to whom <hostmask>\n"
|
||||
" currently maps) the specified capability <capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nimi|hostmask> <valtuus>\n"
|
||||
"\n"
|
||||
"Antaa <nimen> määrittämälle käyttäjälle (tai käyttäjälle jonka <hostmask>\n"
|
||||
"ilmoittaa) määritetyn valtuuden <valtuus>\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:272
|
||||
msgid "The \"owner\" capability can't be added in the bot. Use the supybot-adduser program (or edit the users.conf file yourself) to add an owner capability."
|
||||
msgstr "\"Owner\" valtuutta ei voida lisätä bottiin. Käytä supybot-adduser ohjelmaa (tai muokkaa users.conf tiedostoa itse) lisätäksesi owner valtuuden."
|
||||
|
||||
#: plugin.py:283
|
||||
msgid "You can't add capabilities you don't have."
|
||||
msgstr "Et voi lisätä valtuuksia, joita sinulla ei ole."
|
||||
|
||||
#: plugin.py:288
|
||||
msgid ""
|
||||
"<name|hostmask> <capability>\n"
|
||||
"\n"
|
||||
" Takes from the user specified by <name> (or the user to whom\n"
|
||||
" <hostmask> currently maps) the specified capability <capability>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nimi|hostmask> <valtuus>\n"
|
||||
"\n"
|
||||
"Ottaa <nimen> määrittämältä käyttäjältä (tai käyttäjältä jonka\n"
|
||||
" <hostmask> sopii) määritetyn valtuuden <valtuus>\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:300
|
||||
msgid "That user doesn't have that capability."
|
||||
msgstr "Tuolla käyttäjällä ei ole sitä valtuutta."
|
||||
|
||||
#: plugin.py:302
|
||||
msgid "You can't remove capabilities you don't have."
|
||||
msgstr "Sinä et voi poistaa valtuuksia, joita sinulla ei ole."
|
||||
|
||||
#: plugin.py:310
|
||||
msgid ""
|
||||
"<hostmask|nick> [<expires>]\n"
|
||||
"\n"
|
||||
" This will set a persistent ignore on <hostmask> or the hostmask\n"
|
||||
" currently associated with <nick>. <expires> is an optional argument\n"
|
||||
" specifying when (in \"seconds from now\") the ignore will expire; if\n"
|
||||
" it isn't given, the ignore will never automatically expire.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<hostmask|nimimerkki> [<vanhentuu>]\n"
|
||||
"\n"
|
||||
"Tämä asettaa pysyvän ignoren <hostmaskiin> tai hostmaskiin,\n"
|
||||
" joka on tällä hetkellä yhdistetty <nimimerkkiin>. <vanhentuu> on vaihtoehtoinen paremetri,\n"
|
||||
"joka määrittää (in \"sekuntit\") jolloin ignore vanhentuu; jos\n"
|
||||
"sitä ei ole annettu, ignore ei vanhene automaattisesti ikinä.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:323
|
||||
msgid ""
|
||||
"<hostmask|nick>\n"
|
||||
"\n"
|
||||
" This will remove the persistent ignore on <hostmask> or the\n"
|
||||
" hostmask currently associated with <nick>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<hostmask|nimimerkki>\n"
|
||||
"\n"
|
||||
"Tämä poistaa pysyvän ignoren <hostmaskista> tai\n"
|
||||
"hostmaskista joka on tällä hetkellä yhdistetty <nimimerkkiin>.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:332
|
||||
msgid "%s wasn't in the ignores database."
|
||||
msgstr "%s ei ollut ignore tietokannassa."
|
||||
|
||||
#: plugin.py:337
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Lists the hostmasks that the bot is ignoring.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Ei ota parametrejä\n"
|
||||
"\n"
|
||||
"Luetteloi hostmaskit jotka ovat botin ignoressa.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:345
|
||||
msgid "I'm not currently globally ignoring anyone."
|
||||
msgstr "Kukaan ei juuri nyt ole globaalisti estolistalla."
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-16 10:43+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot Alias plugin\n"
|
||||
"POT-Creation-Date: 2010-10-16 14:10+CEST\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Mika Suomalainen <mika.henrik.mainio@hotmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Finnish\n"
|
||||
"X-Poedit-Country: FINLAND\n"
|
||||
|
||||
#: plugin.py:45
|
||||
msgid ""
|
||||
"Returns the channel the msg came over or the channel given in args.\n"
|
||||
"\n"
|
||||
" If the channel was given in args, args is modified (the channel is\n"
|
||||
" removed).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Palauttaa kanavan, jolta viesti tuli tai kanavan, joka on annettu parametreissä.\n"
|
||||
"\n"
|
||||
"Jos kanava annetaan parametreissä, parametriä muokataan (kanava\n"
|
||||
"poistetaan).\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:164
|
||||
msgid " at least"
|
||||
msgstr "vähintään"
|
||||
|
||||
#: plugin.py:165
|
||||
msgid ""
|
||||
"<an alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias for %q."
|
||||
msgstr ""
|
||||
"<alias,%s %n>\n"
|
||||
"\n"
|
||||
"Alias %q:lle."
|
||||
|
||||
#: plugin.py:220
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Locks an alias so that no one else can change it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
"Lukitsee aliaksen, niin ettei kukaan muu voi muuttaa sitä.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:229
|
||||
#: plugin.py:243
|
||||
msgid "There is no such alias."
|
||||
msgstr "Tuollaista aliasta ei ole."
|
||||
|
||||
#: plugin.py:234
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
" Unlocks an alias so that people can define new aliases over it.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<alias>\n"
|
||||
"\n"
|
||||
"Poistaa lukituksen aliaksesta, jotta ihmiset vouvat määrittää uusia aliaksia sen päälle.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:254
|
||||
msgid "That name isn't valid. Try %q instead."
|
||||
msgstr "Nimi ei ole kelvollinen. Yritä sen sijaa %q:ta."
|
||||
|
||||
#: plugin.py:292
|
||||
msgid ""
|
||||
"<name> <alias>\n"
|
||||
"\n"
|
||||
" Defines an alias <name> that executes <alias>. The <alias>\n"
|
||||
" should be in the standard \"command argument [nestedcommand argument]\"\n"
|
||||
" arguments to the alias; they'll be filled with the first, second, etc.\n"
|
||||
" arguments. $1, $2, etc. can be used for required arguments. @1, @2,\n"
|
||||
" etc. can be used for optional arguments. $* simply means \"all\n"
|
||||
" remaining arguments,\" and cannot be combined with optional arguments.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nimi> <alias>\n"
|
||||
"\n"
|
||||
"Määrittää aliaksen <nimi>, joka suorittaa <aliaksen>. <Alias>\n"
|
||||
"Aliaksen pitäisi olla tavallisia \"komento parametri [sisäkkäiset parametrit]\"\n"
|
||||
"parametrejä aliakselle; ne täytetään ensinmäinen, toinen, jne.\n"
|
||||
"Parametrit. $1, $2, jne. voidaan käyttää vaadittuina parametreinä. @1, @2,\n"
|
||||
"jne. voidaan käyttää vaihtoehtoisina parametreinä. $* tarkoittaa yksinkertaisesti \"kaikki\n"
|
||||
"jäljellä olevat parametrit,\" ja johon ei voida yhdistää vaihtoehtoisia parametrejä.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:315
|
||||
msgid ""
|
||||
"<name>\n"
|
||||
"\n"
|
||||
" Removes the given alias, if unlocked.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nimi>\n"
|
||||
"\n"
|
||||
"Poistaa annetun aliaksen jos se ei ole lukittu.\n"
|
||||
" "
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot-fr\n"
|
||||
"POT-Creation-Date: 2010-10-16 14:10+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
|
@ -39,6 +39,10 @@ msgstr ""
|
|||
"\n"
|
||||
"Alias pour %q."
|
||||
|
||||
#: plugin.py:166
|
||||
msgid "argument"
|
||||
msgstr "argument"
|
||||
|
||||
#: plugin.py:220
|
||||
msgid ""
|
||||
"<alias>\n"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-16 14:10+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -36,6 +36,10 @@ msgid ""
|
|||
"Alias for %q."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:166
|
||||
msgid "argument"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:220
|
||||
#, docstring
|
||||
msgid ""
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot Anonymous\n"
|
||||
"POT-Creation-Date: 2010-10-16 15:14+CEST\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Mika Suomalainen <mika.henrik.mainio@hotmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Finnish\n"
|
||||
"X-Poedit-Country: FINLAND\n"
|
||||
|
||||
#: config.py:49
|
||||
msgid ""
|
||||
"Determines whether\n"
|
||||
" the bot should require people trying to use this plugin to be in the\n"
|
||||
" channel they wish to anonymously send to."
|
||||
msgstr ""
|
||||
"Määrittelee täytyisikö \n"
|
||||
"botin vaatia ihmisiä, jotka yrittävät käyttää tätä lisäosaa olla\n"
|
||||
"kanavalla, jonne he tahtovat lähettää viestin tuntemattomasti."
|
||||
|
||||
#: config.py:53
|
||||
msgid ""
|
||||
"Determines whether the bot should require\n"
|
||||
" people trying to use this plugin to be registered."
|
||||
msgstr ""
|
||||
"Määrittelee täytyisikö botin vaatia\n"
|
||||
"ihmisiä, jotka yrittävät käyttää tätä lisäosaa olla rekisteröityneitä."
|
||||
|
||||
#: config.py:56
|
||||
msgid ""
|
||||
"Determines what capability (if any) the bot should\n"
|
||||
" require people trying to use this plugin to have."
|
||||
msgstr ""
|
||||
"Määrittää mitä valtuutta (jos mitään) botin täytyisi\n"
|
||||
"vaatia ihmisiltä, jotka yrittävät käyttää tätä lisäosaa."
|
||||
|
||||
#: config.py:59
|
||||
msgid ""
|
||||
"Determines whether the bot will require \n"
|
||||
" targets of the \"say\" command to be public (i.e., channels). If this is\n"
|
||||
" True, the bot will allow people to use the \"say\" command to send private\n"
|
||||
" messages to other users."
|
||||
msgstr ""
|
||||
"Määrittelee täytyykö botin vaatia \n"
|
||||
"\"say\" komennon olevan julkisia (esim., kanavia). Jos tämä on\n"
|
||||
" True, botti sallii ihmisten käyttää \"say\" komentoa lähettääkseen yksityisviestejä \n"
|
||||
" toisille käyttäjille."
|
||||
|
||||
#: plugin.py:41
|
||||
msgid ""
|
||||
"This plugin allows users to act through the bot anonymously. The 'do'\n"
|
||||
" command has the bot perform an anonymous action in a given channel, and\n"
|
||||
" the 'say' command allows other people to speak through the bot. Since\n"
|
||||
" this can be fairly well abused, you might want to set\n"
|
||||
" supybot.plugins.Anonymous.requireCapability so only users with that\n"
|
||||
" capability can use this plugin. For extra security, you can require that\n"
|
||||
" the user be *in* the channel they are trying to address anonymously with\n"
|
||||
" supybot.plugins.Anonymous.requirePresenceInChannel, or you can require\n"
|
||||
" that the user be registered by setting\n"
|
||||
" supybot.plugins.Anonymous.requireRegistration.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Tämä lisäosa sallii käyttäjien toimia botin kautta tuntemattomasti.\n"
|
||||
"Komento 'do' sallii botin tehdä Anonymous toiminnon annetulla kanavalla ja\n"
|
||||
"'say' komento sallii toisten ihmisten puhua botin läpi. Koska\n"
|
||||
"tätä voidaan väärinkäyttää helposti voit tahtoa asettaa \n"
|
||||
"supybot.plugins.Anonymous.requireCapability niin, että vain käyttäjät tuolla\n"
|
||||
"valtuudella. Lisäturvallisuuden vuoksi voit vaatia, että käyttäjän täytyy *olla* kanavalla joita he yrittävät puhutella tuntemattomasti asetuksella supybot.plugins.Anonymous.requirePresenceInChannel, tai sinä voit vaatia,\n"
|
||||
"että tuo käyttäjä on rekisteröitynyt asetuksella\n"
|
||||
"supybot.plugins.Anonymous.requireRegistration"
|
||||
|
||||
#: plugin.py:81
|
||||
msgid ""
|
||||
"<channel|nick> <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to <channel|nick>. Can only send to <nick> if\n"
|
||||
" supybot.plugins.Anonymous.allowPrivateTarget is True.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<kanava|nimimerkki> <teksti>\n"
|
||||
"\n"
|
||||
"Lähettää <tekstin> <kanavalle|nimimerkille>. <Nimimerkille> voi lähettää vain jos\n"
|
||||
"supybot.plugins.Anonymous.allowPrivateTarget on True.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:95
|
||||
msgid ""
|
||||
"<channel> <action>\n"
|
||||
"\n"
|
||||
" Performs <action> in <channel>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<kanava> <toiminto>\n"
|
||||
"\n"
|
||||
"Suorittaa <toiminnon> <kanavalla>.\n"
|
||||
" "
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-16 15:14+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -42,7 +42,7 @@ msgid ""
|
|||
" messages to other users."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:41
|
||||
#: plugin.py:40
|
||||
#, docstring
|
||||
msgid ""
|
||||
"This plugin allows users to act through the bot anonymously. The 'do'\n"
|
||||
|
@ -58,7 +58,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:81
|
||||
#: plugin.py:80
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<channel|nick> <text>\n"
|
||||
|
@ -68,7 +68,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:95
|
||||
#: plugin.py:94
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<channel> <action>\n"
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot AutoMode\n"
|
||||
"POT-Creation-Date: 2010-10-16 18:48+CEST\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Mika Suomalainen <mika.henrik.mainio@hotmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Finnish\n"
|
||||
"X-Poedit-Country: FINLAND\n"
|
||||
|
||||
#: config.py:46
|
||||
msgid ""
|
||||
"Determines whether this plugin is enabled.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Määrittää onko tämä lisäosa käytössä.\n"
|
||||
" "
|
||||
|
||||
#: config.py:49
|
||||
msgid ""
|
||||
"Determines whether this plugin will automode\n"
|
||||
" owners."
|
||||
msgstr ""
|
||||
"Määrittää käytetäänkö tätä lisäosaa \n"
|
||||
"omistajiin."
|
||||
|
||||
#: config.py:52
|
||||
msgid ""
|
||||
"Determines whether the bot will \"fall through\n"
|
||||
" to halfop/voicing when auto-opping is turned off but\n"
|
||||
" auto-halfopping/voicing are turned on."
|
||||
msgstr ""
|
||||
"Määrittää \"siirtyykö botti\n"
|
||||
"halfoppaamiseen/voicen antamiseen kun automaatti-oppaaminen on on/off asennossa mutta\n"
|
||||
"automaattinen-halfoppaaminen/voicen antaminen ovat käytössä."
|
||||
|
||||
#: config.py:56
|
||||
msgid ""
|
||||
"Determines whether the bot will automatically\n"
|
||||
" op people with the <channel>,op capability when they join the channel.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Määrittää oppaako botti\n"
|
||||
"ihmiset <kanava>,op valtuudella automaattisesti, kun he liittyvät kanavalle.\n"
|
||||
" "
|
||||
|
||||
#: config.py:60
|
||||
msgid ""
|
||||
"Determines whether the bot will automatically\n"
|
||||
" halfop people with the <channel>,halfop capability when they join the\n"
|
||||
" channel."
|
||||
msgstr ""
|
||||
"Miirittää halfoppaako botti automaattisesti, kun\n"
|
||||
"ihmiset <kanava>,halfop valtuudella, kun he liittyvät \n"
|
||||
"kanavalle."
|
||||
|
||||
#: config.py:64
|
||||
msgid ""
|
||||
"Determines whether the bot will automatically\n"
|
||||
" voice people with the <channel>,voice capability when they join the\n"
|
||||
" channel."
|
||||
msgstr ""
|
||||
"Määrittää antaako botti automaattisesti voicen\n"
|
||||
" ihmisille, joilla on <kanava>,voice valtuus kun he liittyvät\n"
|
||||
"kanavalle."
|
||||
|
||||
#: config.py:68
|
||||
msgid ""
|
||||
"Determines whether the bot will automatically\n"
|
||||
" ban people who join the channel and are on the banlist."
|
||||
msgstr ""
|
||||
"Määrittää bannaako botti ihmiset,\n"
|
||||
"jotka liittyvät kanavalle ja ovat banni listalla."
|
||||
|
||||
#: config.py:71
|
||||
msgid ""
|
||||
"Determines how many seconds the bot\n"
|
||||
" will automatically ban a person when banning."
|
||||
msgstr ""
|
||||
"Määrittää kuinka moneksi sekuntiksi botti\n"
|
||||
"bannaa henkilön, kun ollaan bannaamassa."
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-16 18:48+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot BadWords\n"
|
||||
"POT-Creation-Date: 2011-01-29 11:48+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Mika Suomalainen <mika.henrik.mainio@hotmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Finnish\n"
|
||||
"X-Poedit-Country: FINLAND\n"
|
||||
|
||||
#: __init__.py:30
|
||||
msgid ""
|
||||
"\n"
|
||||
"Filters bad words on outgoing messages from the bot, so the bot can't be made\n"
|
||||
"to say bad words.\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Suodattaa botin ulostulevista viesteistä pahat sanat, jotta bottia ei saada\n"
|
||||
"sanomaan pahoja sanoja.\n"
|
||||
|
||||
#: config.py:40
|
||||
msgid "Would you like to add some bad words?"
|
||||
msgstr "Haluaisitko lisätä joitakin pahoja sanoja?"
|
||||
|
||||
#: config.py:41
|
||||
msgid "What words? (separate individual words by spaces)"
|
||||
msgstr "Mitkä sanoja? (Eristä erilliset sanat käyttämällä välilyöntiä."
|
||||
|
||||
#: config.py:53
|
||||
msgid ""
|
||||
"Determines what words are\n"
|
||||
" considered to be 'bad' so the bot won't say them."
|
||||
msgstr ""
|
||||
"Määrittää mitkä sanat ovat\n"
|
||||
"'pahoja', jottei botti sano niitä."
|
||||
|
||||
#: config.py:56
|
||||
msgid ""
|
||||
"Determines whether the bot will require bad\n"
|
||||
" words to be independent words, or whether it will censor them within other\n"
|
||||
" words. For instance, if 'darn' is a bad word, then if this is true, 'darn'\n"
|
||||
" will be censored, but 'darnit' will not. You probably want this to be\n"
|
||||
" false. After changing this setting, the BadWords regexp needs to be\n"
|
||||
" regenerated by adding/removing a word to the list, or reloading the\n"
|
||||
" plugin."
|
||||
msgstr ""
|
||||
"Määrittää vaatiiko botti pahojen sanojen\n"
|
||||
"olevan toisistaan riippumattomia sanoja, vai sensuroiko se ne toisten sanojen\n"
|
||||
"sisältä. Esimerkiksi,jos 'pah' on paha sana, ja jos tämä on asetettu true asentoon, 'pah'\n"
|
||||
"sensuroidaan, mutta 'pahus' ei sensuroida. Sinä luultavasti tahdot pitää tämän\n"
|
||||
"false asennossa. Tämän asetuksen muuttamisen jälkeen, BadWords regexp täytyy\n"
|
||||
"luoda uudelleen lisäämällä/poistamalla sana listalta, tai uudelleenlataamalla \n"
|
||||
"lisäosa."
|
||||
|
||||
#: config.py:73
|
||||
msgid ""
|
||||
"Determines what characters will replace bad words; a\n"
|
||||
" chunk of these characters matching the size of the replaced bad word will\n"
|
||||
" be used to replace the bad words you've configured."
|
||||
msgstr ""
|
||||
"Määrittä mitkä merkit korvaavat pahat sanat; \n"
|
||||
"osa näistä merkeistä, jotka sopivat pahasanan kokoon\n"
|
||||
"käytetään määrittämiesi pahojen sanojen korvaamisessa."
|
||||
|
||||
#: config.py:81
|
||||
msgid ""
|
||||
"Determines the manner in which\n"
|
||||
" bad words will be replaced. 'nastyCharacters' (the default) will replace a\n"
|
||||
" bad word with the same number of 'nasty characters' (like those used in\n"
|
||||
" comic books; configurable by supybot.plugins.BadWords.nastyChars).\n"
|
||||
" 'simple' will replace a bad word with a simple strings (regardless of the\n"
|
||||
" length of the bad word); this string is configurable via\n"
|
||||
" supybot.plugins.BadWords.simpleReplacement."
|
||||
msgstr ""
|
||||
"Määrittää millä tavalla\n"
|
||||
"pahat sanat korvataan. 'nastyCharacters' (oletus) korvaa\n"
|
||||
"pahan sanan samalla määrällä 'häijyjä merkkejä' (kuten ne jotka ovat\n"
|
||||
"sarjakuvissa; muokattavissa supybot.plugins.BadWords.nastyChars asetuksella).\n"
|
||||
"'simple' korvaa pahan sanan yksinkertaisella merkkijonolla (riippumatta\n"
|
||||
"pahan sanan koosta); tämä merkkijono on muokattavissa\n"
|
||||
"asetuksella supybot.plugins.BadWords.simpleReplacement."
|
||||
|
||||
#: config.py:89
|
||||
msgid ""
|
||||
"Determines what word will replace bad\n"
|
||||
" words if the replacement method is 'simple'."
|
||||
msgstr ""
|
||||
"Määrittää mikä sana korvaa pahat\n"
|
||||
"sanat jos korvausmenetelmä on 'simple'."
|
||||
|
||||
#: config.py:92
|
||||
msgid ""
|
||||
"Determines whether the bot will strip\n"
|
||||
" formatting characters from messages before it checks them for bad words.\n"
|
||||
" If this is False, it will be relatively trivial to circumvent this plugin's\n"
|
||||
" filtering. If it's True, however, it will interact poorly with other\n"
|
||||
" plugins that do coloring or bolding of text."
|
||||
msgstr ""
|
||||
"Määrittää riisuuko botti\n"
|
||||
" muotoilun merkeistä ennen kuin se tarkistaa ne pahojen sanojen varalta.\n"
|
||||
" Jos tämä on 'False', on hyvin pinnallista kiertää tämän lisäosan\n"
|
||||
" suodatusta. Jos se kuitenkin on 'True', se on huonosti vuorovaikutuksessa\n"
|
||||
"tekstin värittämistä tai korostamista tekevien lisäosien kanssa."
|
||||
|
||||
#: config.py:99
|
||||
msgid ""
|
||||
"Determines whether the bot will kick people with\n"
|
||||
" a warning when they use bad words."
|
||||
msgstr ""
|
||||
"Määrittää potkiiko botti ihmiset\n"
|
||||
"varoituksella jos he käyttävät pahoja sanoja."
|
||||
|
||||
#: config.py:102
|
||||
msgid ""
|
||||
"You have been kicked for using a word\n"
|
||||
" prohibited in the presence of this bot. Please use more appropriate\n"
|
||||
" language in the future."
|
||||
msgstr ""
|
||||
"Sinut on potkittu kielletyn sanan\n"
|
||||
"käytöstä tämän botin läsnäollessa. Ole hyvä ja käytä asianmukaisempaa\n"
|
||||
" kieltä tulevaisuudessa."
|
||||
|
||||
#: config.py:104
|
||||
msgid ""
|
||||
"Determines the kick message used by the\n"
|
||||
" bot when kicking users for saying bad words."
|
||||
msgstr ""
|
||||
"Määrittää potkimisviestin, jota\n"
|
||||
"botti käyttää, kun potkii käyttäjiä pahojen sanojen käyttämistä."
|
||||
|
||||
#: plugin.py:46
|
||||
msgid ""
|
||||
"Maintains a list of words that the bot is not allowed to say.\n"
|
||||
" Can also be used to kick people that say these words, if the bot\n"
|
||||
" has op."
|
||||
msgstr ""
|
||||
"Säilyttää listaa sanoista, joita botin ei ole sallittua sanoa.\n"
|
||||
"Voidaan myös käyttää potkimaan ihmisiä, jotka sanovat näitä sanoja, jos botilla\n"
|
||||
"on kanavaoperaattori."
|
||||
|
||||
#: plugin.py:113
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Returns the list of words being censored.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"ei ota parametrejä\n"
|
||||
"\n"
|
||||
"Palauttaa listan sanoista, joita sensuroidaan.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:123
|
||||
msgid "I'm not currently censoring any bad words."
|
||||
msgstr "Tällä hetkellä ei sensuroida yhtään pahoja sanoja."
|
||||
|
||||
#: plugin.py:128
|
||||
msgid ""
|
||||
"<word> [<word> ...]\n"
|
||||
"\n"
|
||||
" Adds all <word>s to the list of words being censored.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<sana> [<sana> ...]\n"
|
||||
"\n"
|
||||
"Lisää kaikki <sana>(t) sensuroidaan.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:140
|
||||
msgid ""
|
||||
"<word> [<word> ...]\n"
|
||||
"\n"
|
||||
" Removes <word>s from the list of words being censored.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<sana> [<sana> ...]\n"
|
||||
"\n"
|
||||
"Poistaa <sanat>(t) sensuroitujen sanojen listalta.\n"
|
||||
" "
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2011-01-29 11:48+CET\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -15,14 +15,6 @@ msgstr ""
|
|||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: __init__.py:30
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
"Filters bad words on outgoing messages from the bot, so the bot can't be made\n"
|
||||
"to say bad words.\n"
|
||||
msgstr ""
|
||||
|
||||
#: config.py:40
|
||||
msgid "Would you like to add some bad words?"
|
||||
msgstr ""
|
||||
|
|
|
@ -0,0 +1,833 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot Channel\n"
|
||||
"POT-Creation-Date: 2010-10-25 13:10+CEST\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Mika Suomalainen <mika.henrik.mainio@hotmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Finnish\n"
|
||||
"X-Poedit-Country: FINLAND\n"
|
||||
|
||||
#: config.py:48
|
||||
msgid ""
|
||||
"Determines whether the bot will always try to\n"
|
||||
" rejoin a channel whenever it's kicked from the channel."
|
||||
msgstr ""
|
||||
"Määrittää yrittääkö botti aina\n"
|
||||
"liittyä kanavalle uudelleen, kun se on potkittu kanavalta."
|
||||
|
||||
#: plugin.py:69
|
||||
msgid ""
|
||||
"[<channel>] <mode> [<arg> ...]\n"
|
||||
"\n"
|
||||
" Sets the mode in <channel> to <mode>, sending the arguments given.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel\n"
|
||||
" itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] <tila> [<parametri> ...]\n"
|
||||
"\n"
|
||||
"Asettaa <kanavan> <tilan>, tilaksi lähettäen annetut parametrin.\n"
|
||||
"<kanava> on vaadittu vain, jos viestiä ei lähetetä kanavalta\n"
|
||||
"jonka tilaa vaihdetaan.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:76
|
||||
msgid "change the mode"
|
||||
msgstr "vaihda tila"
|
||||
|
||||
#: plugin.py:80
|
||||
msgid ""
|
||||
"[<channel>] [<limit>]\n"
|
||||
"\n"
|
||||
" Sets the channel limit to <limit>. If <limit> is 0, or isn't given,\n"
|
||||
" removes the channel limit. <channel> is only necessary if the message\n"
|
||||
" isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [<rajoitus>]\n"
|
||||
"\n"
|
||||
"Asettaa kanavan <rajoituksen>. Jos <rajoitus> on 0, tai ei annettu,\n"
|
||||
"kanava rajoitus poistetaan. <Kanava>on vaadittu cain jos\n"
|
||||
"viestiä ei lähetetä kanavalta itseltään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:90
|
||||
msgid "change the limit"
|
||||
msgstr "Vaihda rajoitusta"
|
||||
|
||||
#: plugin.py:95
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" Sets +m on <channel>, making it so only ops and voiced users can\n"
|
||||
" send messages to the channel. <channel> is only necessary if the\n"
|
||||
" message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>]\n"
|
||||
"\n"
|
||||
"Asettaa tilan +m <kanavalla>, sallien vain operaattoireiden ja käyttäjien jolla on voice\n"
|
||||
"lähettää viestejä kanavalle. <Kanava> on vaadittu vain jos\n"
|
||||
"viestiä ei lähetetä itse kanavalta.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:102
|
||||
msgid "moderate the channel"
|
||||
msgstr "valvo kanavaa"
|
||||
|
||||
#: plugin.py:106
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" Sets -m on <channel>, making it so everyone can\n"
|
||||
" send messages to the channel. <channel> is only necessary if the\n"
|
||||
" message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>]\n"
|
||||
"\n"
|
||||
"Asettaa -m tilan <kanavalla>, sallien jokaisen\n"
|
||||
"lähettää viestejä kanavalla. <Kanava> on vaadittu vain jos\n"
|
||||
" viestiä ei lähetetä kanavalta itseltään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:114
|
||||
msgid "unmoderate the channel"
|
||||
msgstr "lopeta kanavan valvominen"
|
||||
|
||||
#: plugin.py:118
|
||||
msgid ""
|
||||
"[<channel>] [<key>]\n"
|
||||
"\n"
|
||||
" Sets the keyword in <channel> to <key>. If <key> is not given, removes\n"
|
||||
" the keyword requirement to join <channel>. <channel> is only necessary\n"
|
||||
" if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [<avain>]\n"
|
||||
"\n"
|
||||
"Asettaa <kanavan>avainsanan <avaimeksi>. Jos <avainta> ei ole annettu, poistaa\n"
|
||||
"poistaa avainsana vaatimuksen <kanavalle> liittymisestä. <Kanava> on vaadittu vain\n"
|
||||
"jos viestiä ei lähetetä kanavalta itsestään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:130
|
||||
msgid "change the keyword"
|
||||
msgstr "vaihtaa avainsanan"
|
||||
|
||||
#: plugin.py:135
|
||||
msgid ""
|
||||
"[<channel>] [<nick> ...]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will give all the <nick>s\n"
|
||||
" you provide ops. If you don't provide any <nick>s, this will op you.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel\n"
|
||||
" itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [<nimimerkki> ...]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä antaa kaikille <nimimerkeille>\n"
|
||||
"sinun tarjoamat opit. Jos et anna yhtään <nimimerkkiä>, tämä oppaa sinut.\n"
|
||||
"<Kanava> on vaadittu vain jos viestiä ei lähetetä kanavalta\n"
|
||||
"itsestään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:147
|
||||
msgid "op someone"
|
||||
msgstr "oppaa joku"
|
||||
|
||||
#: plugin.py:151
|
||||
msgid ""
|
||||
"[<channel>] [<nick> ...]\n"
|
||||
"\n"
|
||||
" If you have the #channel,halfop capability, this will give all the\n"
|
||||
" <nick>s you provide halfops. If you don't provide any <nick>s, this\n"
|
||||
" will give you halfops. <channel> is only necessary if the message isn't\n"
|
||||
" sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<Kanava>] [<nimimerkki> ...]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,halfop valtuus, tämä antaa kaikille\n"
|
||||
"<nimimerkeille> halfopit. Jos et anna yhtään <nimimerkkiä>, tämä\n"
|
||||
"antaa sinulle halfopit. <Kanava> on vaadittu vain jos viestiä ei\n"
|
||||
"lähetetä kanavalta itseltään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:163
|
||||
msgid "halfop someone"
|
||||
msgstr "halfoppaa joku"
|
||||
|
||||
#: plugin.py:168
|
||||
msgid ""
|
||||
"[<channel>] [<nick> ...]\n"
|
||||
"\n"
|
||||
" If you have the #channel,voice capability, this will voice all the\n"
|
||||
" <nick>s you provide. If you don't provide any <nick>s, this will\n"
|
||||
" voice you. <channel> is only necessary if the message isn't sent in the\n"
|
||||
" channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<Kanava>] [<nimimerkki> ...]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,halfop valtuus, tämä antaa kaikille\n"
|
||||
"<nimimerkeille> halfopit. Jos et anna yhtään <nimimerkkiä>, tämä\n"
|
||||
"antaa sinulle halfopit. <Kanava> on vaadittu vain jos viestiä ei\n"
|
||||
"lähetetä kanavalta itseltään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:190
|
||||
msgid "voice someone"
|
||||
msgstr "anna jollekin voice"
|
||||
|
||||
#: plugin.py:195
|
||||
msgid ""
|
||||
"[<channel>] [<nick> ...]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will remove operator\n"
|
||||
" privileges from all the nicks given. If no nicks are given, removes\n"
|
||||
" operator privileges from the person sending the message.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [<nimimerkki> ...]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä poistaa operaattori\n"
|
||||
"kaikilta annetuilta nimimerkeiltä. Jos nimimerkkejä ei ole annettu poistaa\n"
|
||||
"poistaa operaattorioikeudet henkilöltä, joka lähettää viestin.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:202
|
||||
msgid "I cowardly refuse to deop myself. If you really want me deopped, tell me to op you and then deop me yourself."
|
||||
msgstr "Minä pelkurimaisesti kieltäydyn deoppaamasta itseäni. Jos todella tahdot minut deopatuksi, käske minun opata sinut ja sitten deoppaa minut itse."
|
||||
|
||||
#: plugin.py:210
|
||||
msgid "deop someone"
|
||||
msgstr "deoppaa joku"
|
||||
|
||||
#: plugin.py:215
|
||||
msgid ""
|
||||
"[<channel>] [<nick> ...]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will remove half-operator\n"
|
||||
" privileges from all the nicks given. If no nicks are given, removes\n"
|
||||
" half-operator privileges from the person sending the message.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [<nimimerkki> ...]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä poistaa puoli-kanavaoperaattorin\n"
|
||||
"kaikilta annetuilta nimimerkeiltä. Jos nimimerkkejä ei anneta\n"
|
||||
"viestin lähettäneeltä henkilöltä poistetaan puoli-kanavaoperaattorin oikeudet.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:222
|
||||
msgid "I cowardly refuse to dehalfop myself. If you really want me dehalfopped, tell me to op you and then dehalfop me yourself."
|
||||
msgstr "Minä pelkurimaisesti kieltäydyn dehalfoppaamasta itseäni. Jos haluat minut depuoliopatuksi, käske minun opata sinut ja sitten dehalfoppaa minut itse."
|
||||
|
||||
#: plugin.py:230
|
||||
msgid "dehalfop someone"
|
||||
msgstr "dehalfoppaa joku"
|
||||
|
||||
#: plugin.py:235
|
||||
msgid ""
|
||||
"[<channel>] [<nick> ...]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will remove voice from all\n"
|
||||
" the nicks given. If no nicks are given, removes voice from the person\n"
|
||||
" sending the message.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [<nimimerkki> ...]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä poistaa voicen kaikilta\n"
|
||||
"annetuilta nimimerkeiltä. Jos nimimerkkejä ei ole annettu, poistaa voicen henkilöltä\n"
|
||||
"joka lähettää viestin.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:242
|
||||
msgid "I cowardly refuse to devoice myself. If you really want me devoiced, tell me to op you and then devoice me yourself."
|
||||
msgstr "Minä pelkurimaisesti kieltäydyn poistamasta voicea itseltäni. Jos todella tahdot poistaa minulta voicen, käske minut oppaamaan sinut ja sitten poista ääni minulta itse."
|
||||
|
||||
#: plugin.py:255
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will cause the bot to\n"
|
||||
" \"cycle\", or PART and then JOIN the channel. <channel> is only necessary\n"
|
||||
" if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>]\n"
|
||||
"\n"
|
||||
" Jos sinulla on #kanava,op valtuus, tämä aiheuttaa botin tekemään\n"
|
||||
"\"cyclen\", tai POISTUMAAN ja LIITTYMÄÄN kanavalle. <Kanava> on vaadittu vain\n"
|
||||
"jos viestiä ei lähetetä kanavalta itsestään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:268
|
||||
msgid ""
|
||||
"[<channel>] <nick>[, <nick>, ...] [<reason>]\n"
|
||||
"\n"
|
||||
" Kicks <nick>(s) from <channel> for <reason>. If <reason> isn't given,\n"
|
||||
" uses the nick of the person making the command as the reason.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel\n"
|
||||
" itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] <nimimerkki>[, <nimimerkki>, ...] [<syy>]\n"
|
||||
"\n"
|
||||
"Potkii <nimimerkit> <kanavalta> <syystä>. Jos <syytä> ei ole annettu,\n"
|
||||
"käyttää komennon antajan nimimerkkiä syynä.\n"
|
||||
"<Kanava> on vaadittu vain jos viestiä ei lähetetä kanavalta\n"
|
||||
"itsestään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:276
|
||||
msgid "I cowardly refuse to kick myself."
|
||||
msgstr "Minä pelkurimaisesti kieltäydyn potkimasta itseäni."
|
||||
|
||||
#: plugin.py:281
|
||||
msgid "The reason you gave is longer than the allowed length for a KICK reason on this server."
|
||||
msgstr "Syy, jonka annoit on pidempi kuin sallittu pituus POTKIMIS syyksi tällä palvelimella."
|
||||
|
||||
#: plugin.py:286
|
||||
msgid "kick someone"
|
||||
msgstr "potki joku"
|
||||
|
||||
#: plugin.py:292
|
||||
msgid ""
|
||||
"[<channel>] [--{exact,nick,user,host}] <nick> [<seconds>] [<reason>]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will kickban <nick> for\n"
|
||||
" as many seconds as you specify, or else (if you specify 0 seconds or\n"
|
||||
" don't specify a number of seconds) it will ban the person indefinitely.\n"
|
||||
" --exact bans only the exact hostmask; --nick bans just the nick;\n"
|
||||
" --user bans just the user, and --host bans just the host. You can\n"
|
||||
" combine these options as you choose. <reason> is a reason to give for\n"
|
||||
" the kick.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel\n"
|
||||
" itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [--{exact,nick,user,host}] <nimimerkki> [<sekuntit>] [<syy>]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä kickbannaa <nimimerkin> \n"
|
||||
"niin moneksi sekuntiksi kuin määrität, tai muuten (jos määrität 0 sekuntia tai\n"
|
||||
"tai et määritä sekuntien lukumäärää) se bannaa henkilön ikuisesti.\n"
|
||||
"--exact bannaa vain hostmaskin; --nick bannaa vain nimimerkin;\n"
|
||||
"--user bannaa vain käyttäjän, ja --host bannaa vain isännän. Voit\n"
|
||||
"yhdistää näitä vaihtoehtoja mielesi mukaan. <Syy> on syy, jonka vuoksi annat\n"
|
||||
"potkun.\n"
|
||||
"<Kanava> on vaadittu vain jos viestiä ei lähetetä kanavassa\n"
|
||||
"itsestään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:311
|
||||
msgid "I cowardly refuse to kickban myself."
|
||||
msgstr "Minä pelkurimaisesti kieltäydyn kickbannaamasta itseäni."
|
||||
|
||||
#: plugin.py:318
|
||||
msgid "I haven't seen %s."
|
||||
msgstr "Minä en ole nähnyt %s:ää."
|
||||
|
||||
#: plugin.py:326
|
||||
msgid "I cowardly refuse to ban myself."
|
||||
msgstr "Minä pelkurimaisesti kieltäydyn bannaamasta itseäni."
|
||||
|
||||
#: plugin.py:352
|
||||
msgid "%s has %s too, you can't ban him/her/it."
|
||||
msgstr "%s:llä on %s myös, et voi bannata häntä/sitä."
|
||||
|
||||
#: plugin.py:364
|
||||
msgid "kick or ban someone"
|
||||
msgstr "potki tai bannaa joku"
|
||||
|
||||
#: plugin.py:371
|
||||
msgid ""
|
||||
"[<channel>] [<hostmask>]\n"
|
||||
"\n"
|
||||
" Unbans <hostmask> on <channel>. If <hostmask> is not given, unbans\n"
|
||||
" any hostmask currently banned on <channel> that matches your current\n"
|
||||
" hostmask. Especially useful for unbanning yourself when you get\n"
|
||||
" unexpectedly (or accidentally) banned from the channel. <channel> is\n"
|
||||
" only necessary if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [<hostmask>]\n"
|
||||
"\n"
|
||||
"Poistaa bannin <hostmaskilta> <kanavalla>. Jos <hostmaskia> ei ole annettu, poistaa bannin\n"
|
||||
"kaikilta hostmaskeilta, jotka ovat bannattuja <kanavalla> ja täsmäävät sinun\n"
|
||||
"hostmaskiisi. Etenkin hyödyllinen jos joudut \n"
|
||||
"odottomattomasti (tai vahingossa) bannatuksi kanavalta. <Kanava> on\n"
|
||||
"vaadittu vain jos viestiä ei lähetetä kanavalta itseltään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:388
|
||||
msgid "All bans on %s matching %s have been removed."
|
||||
msgstr "Kaikki bannit, jotka sopivat %s :ään %s:tä on poistettu."
|
||||
|
||||
#: plugin.py:392
|
||||
msgid "No bans matching %s were found on %s."
|
||||
msgstr "Banneja, jotka täsmäävät %s:ään ei löydetty %s:tä."
|
||||
|
||||
#: plugin.py:395
|
||||
msgid "unban someone"
|
||||
msgstr "poista jonkun banni"
|
||||
|
||||
#: plugin.py:400
|
||||
msgid ""
|
||||
"[<channel>] <nick>\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will invite <nick>\n"
|
||||
" to join <channel>. <channel> is only necessary if the message isn't\n"
|
||||
" sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] <nimimerkki>\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä kutsuu <nimimerkin>\n"
|
||||
"liittymään <kanavalle>. <Kanava> on vaadittu vain jos viestiö\n"
|
||||
"ei lähetetä kanavalla itsessään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:409
|
||||
msgid "invite someone"
|
||||
msgstr "kutsu joku"
|
||||
|
||||
#: plugin.py:428
|
||||
msgid "%s is already in %s."
|
||||
msgstr "%s on jo %s:ssä."
|
||||
|
||||
#: plugin.py:435
|
||||
msgid "There is no %s on this network."
|
||||
msgstr "%s ei ole tässä verkossa."
|
||||
|
||||
#: plugin.py:447
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will \"lobotomize\" the\n"
|
||||
" bot, making it silent and unanswering to all requests made in the\n"
|
||||
" channel. <channel> is only necessary if the message isn't sent in\n"
|
||||
" the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä \"lobotomoi\" \n"
|
||||
"botin tehden sen hiljaisesksi ja vastaamattomaksi kaikkiin pyyntöihin,\n"
|
||||
" jotka on tehty kanavalla. <Kanava> on vaadittu vain jos viestiä ei lähetetä\n"
|
||||
" kanavalla itsessään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:462
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will unlobotomize the\n"
|
||||
" bot, making it respond to requests made in the channel again.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel\n"
|
||||
" itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä poistaa lobotimian\n"
|
||||
"botista, saaden sen jälleen vastaamaan kaikkiin pyyntöihin kanavalla.\n"
|
||||
"<Kanava> on vaadittu vain jos viestiä ei lähetetä kanavalla itsessään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:477
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Returns the channels in which this bot is lobotomized.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"ei ota parametrejä\n"
|
||||
"\n"
|
||||
"Palauttaa kanavat, joilla botti on lobotomoitu.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:492
|
||||
msgid "I'm currently lobotomized in %L."
|
||||
msgstr "Minut on tällähetkellä lobotomoity %L:ssa."
|
||||
|
||||
#: plugin.py:495
|
||||
msgid "I'm not currently lobotomized in any channels that you're in."
|
||||
msgstr "En tällä hetkellä ole lobotomoitu millään kanavalla, jolla sinä olet."
|
||||
|
||||
#: plugin.py:502
|
||||
msgid ""
|
||||
"[<channel>] <nick|hostmask> [<expires>]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will effect a\n"
|
||||
" persistent ban from interacting with the bot on the given\n"
|
||||
" <hostmask> (or the current hostmask associated with <nick>. Other\n"
|
||||
" plugins may enforce this ban by actually banning users with\n"
|
||||
" matching hostmasks when they join. <expires> is an optional\n"
|
||||
" argument specifying when (in \"seconds from now\") the ban should\n"
|
||||
" expire; if none is given, the ban will never automatically expire.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the\n"
|
||||
" channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] <nimimerkki|hostmask> [<expires>]\n"
|
||||
"\n"
|
||||
" Jos sinulla on #kanava,op valtuus, tämä aiheuttaa\n"
|
||||
"pysyvän bannin estääkseen bottia olemasta vuorovaikutuksessa annetun\n"
|
||||
"<hostmaskin> kanssa (tai <nimimerkin> nykyisen hostmaskin. Toiset\n"
|
||||
"toiset lisäosat saattavat pakottaa tämän bannin bannaamalla käyttäjät\n"
|
||||
" täsmäävällä hostmaskilla kun he liittyvät kanavalle. <Vanhentuu> on vaihtoehtoinen\n"
|
||||
"parametri , kun määritetään ( \"sekunteja alkaen nyt\") milloin banni\n"
|
||||
" vanhenee; jos mitään ei ole annettu, banni ei ikinä vanhene automaattisesti.\n"
|
||||
"<Kanava> on vaadittu vain jos viestiä ei lähetetä\n"
|
||||
"kanavalla itsessään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:522
|
||||
msgid ""
|
||||
"[<channel>] <hostmask>\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will remove the\n"
|
||||
" persistent ban on <hostmask>. <channel> is only necessary if the\n"
|
||||
" message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<Kanava>] <hostmask>\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä poistaa\n"
|
||||
"pysyvän bannin <hostmaskilta>. <Kanava> on vaadittu vain jos\n"
|
||||
"viestiä ei lähetetä kanavalla itsellään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:534
|
||||
msgid "There are no persistent bans for that hostmask."
|
||||
msgstr ""
|
||||
"Tuolla hostmaskilla ei ole pysyviä banneja.[<kanava>]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä näyttää\n"
|
||||
"pysyvät bannit #kanavalla.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:539
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will show you the\n"
|
||||
" current persistent bans on #channel.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä näyttää\n"
|
||||
"pysyvät bannit #kanavalla.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:549
|
||||
msgid "%q (expires %t)"
|
||||
msgstr "%q (venhentuu %t)"
|
||||
|
||||
#: plugin.py:552
|
||||
msgid "%q (never expires)"
|
||||
msgstr "%q (ei ikinä vanhennu)"
|
||||
|
||||
#: plugin.py:556
|
||||
msgid "There are no persistent bans on %s."
|
||||
msgstr "%s ei ole pysyviä banneja."
|
||||
|
||||
#: plugin.py:563
|
||||
msgid ""
|
||||
"[<channel>] <nick|hostmask> [<expires>]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will set a persistent\n"
|
||||
" ignore on <hostmask> or the hostmask currently\n"
|
||||
" associated with <nick>. <expires> is an optional argument\n"
|
||||
" specifying when (in \"seconds from now\") the ignore will expire; if\n"
|
||||
" it isn't given, the ignore will never automatically expire.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the\n"
|
||||
" channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] <nimimerkki|hostmask> [<vanhentuu>]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä asettaa pysyvän\n"
|
||||
"ignoren <hostmaskiin> tai hostmaskiin\n"
|
||||
"joka on <nimimerkin> käytössä. <Vanhentuu> on vaihtoehtoinen parametri\n"
|
||||
"kun määritetään ( \"sekunteja alkaen nyt\")milloin ignore vanhentuu; jos\n"
|
||||
"sitä ei ole annettu, banni ei ikinä vanhene automaattisesti.\n"
|
||||
"<Kanava> on vaadittu vain jos viestiä ei lähetetä\n"
|
||||
"kanavalla itsessään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:581
|
||||
msgid ""
|
||||
"[<channel>] <hostmask>\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will remove the\n"
|
||||
" persistent ignore on <hostmask> in the channel. <channel> is only\n"
|
||||
" necessary if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] <hostmask>\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä poistaa\n"
|
||||
"pysyvän ignoren <hostmaskista> kanavalla. <Kanava> on vaadittu\n"
|
||||
"viestiä ei lähetetä kanavalla itsellään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:593
|
||||
msgid "There are no ignores for that hostmask."
|
||||
msgstr "Tuolla hostmaskilla ei ole pysyviä ignoreja."
|
||||
|
||||
#: plugin.py:598
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" Lists the hostmasks that the bot is ignoring on the given channel.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the\n"
|
||||
" channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>]\n"
|
||||
"\n"
|
||||
" Luettelee hostmaskit, jotka ovat botin ignoressa annetulla kanavalla.\n"
|
||||
"<kanava> on vaadittu vain, jos viestiä ei lähetetä\n"
|
||||
"kanavalla itsellään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:607
|
||||
msgid "I'm not currently ignoring any hostmasks in %q"
|
||||
msgstr "Minun ignoressani ei ole yhtään hostmaskia %q:ssa."
|
||||
|
||||
#: plugin.py:618
|
||||
msgid ""
|
||||
"[<channel>] <nick|username> <capability> [<capability> ...]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will give the user\n"
|
||||
" <name> (or the user to whom <nick> maps)\n"
|
||||
" the capability <capability> in the channel. <channel> is only\n"
|
||||
" necessary if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] <nimimerkki|käyttäjänimi> <valtuuus> [<valtuus> ...]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä antaa käyttäjä\n"
|
||||
"<nimelle> (tai käyttäjälle, jonka <nimimerkki> määrittää)\n"
|
||||
" valtuuden <valtuus>kanavalla. <kanava> on\n"
|
||||
"vaadittu vain jos viestiä ei lähetetä kanavalla itsessään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:634
|
||||
msgid ""
|
||||
"[<channel>] <name|hostmask> <capability> [<capability> ...]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will take from the\n"
|
||||
" user currently identified as <name> (or the user to whom <hostmask>\n"
|
||||
" maps) the capability <capability> in the channel. <channel> is only\n"
|
||||
" necessary if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] <nimi|hostmask> <valtuus> [<valtuus> ...]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä ottaa\n"
|
||||
"tällä hetkellä tunnistautuneelta käyttäjältä <nimi> (tai käyttäjältä, jonka <hostmask>\n"
|
||||
"täsmää) valtuuden <valtuus> kanavalla. <Kanava> on\n"
|
||||
" on vaadittu vain jos viestiä ei lähetetä kanavalla itsessään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:653
|
||||
msgid "That user didn't have the %L %s."
|
||||
msgstr "Tuolla käyttäjällä ei ole %L:ää %s:ssä."
|
||||
|
||||
#: plugin.py:662
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"[<channel>] {True|False}\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will set the default\n"
|
||||
" response to non-power-related (that is, not {op, halfop, voice}\n"
|
||||
" capabilities to be the value you give. <channel> is only necessary\n"
|
||||
" if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] {True|False}\n"
|
||||
"\n"
|
||||
" Jos sinulla on #kanava,op valtuus, tämä asettaa oletus\n"
|
||||
"ei voimaan-liittyviin (se on, ei {op, halfop, voice}\n"
|
||||
"valtuus arvo, jonka annat. <Kanava> on vaadittu vain\n"
|
||||
"jos viestiä ei lähetetä kanavalla itsellään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:680
|
||||
msgid ""
|
||||
"[<channel>] <capability> [<capability> ...]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will add the channel\n"
|
||||
" capability <capability> for all users in the channel. <channel> is\n"
|
||||
" only necessary if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<Kanava>] <valtuus> [<valtuus> ...]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä lisää\n"
|
||||
"valtuuden <valtuus> kaikille käyttäjille kanavalla. <Kanava> on\n"
|
||||
"vaadittu vain jos viestiä ei lähetetä kanavalla itsellään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:695
|
||||
msgid ""
|
||||
"[<channel>] <capability> [<capability> ...]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will unset the channel\n"
|
||||
" capability <capability> so each user's specific capability or the\n"
|
||||
" channel default capability will take precedence. <channel> is only\n"
|
||||
" necessary if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] <valtuus> [<valtuus> ...]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä poistaa kanava valtuus\n"
|
||||
"valtuuden <valtuus> joten jokaisen käyttäjäkohtainen valtuus tai\n"
|
||||
"kanavan oletus valtuus otetaan käyttöön. <Kanava> on vaadittu\n"
|
||||
"vain jos viestiä ei lähetetä kanavalla itsessään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:711
|
||||
msgid "capability"
|
||||
msgstr "valtuusMinä en tiedä %L:stä %s:llä"
|
||||
|
||||
#: plugin.py:714
|
||||
msgid "I do not know about the %L %s."
|
||||
msgstr ""
|
||||
"[<kanava>]\n"
|
||||
"\n"
|
||||
" Palauttaa <kanavalla> olevat valtuudet. <Kanava> on\n"
|
||||
"vaadittu vain jos viestiä ei lähetetä kanavalla itsellään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:721
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" Returns the capabilities present on the <channel>. <channel> is\n"
|
||||
" only necessary if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [<lisäosa>] [<komento>]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä poistaa <komennon> käytöstä\n"
|
||||
"<kanavalla>. Jos <lisäosa> on annrttu, <komento> poistetaan käytöstä\n"
|
||||
"vain siitä lisäosasta. Jos vain <lisäosa> on annettu, kaikki komennot\n"
|
||||
"annetusta lisäosasta poistetaan käytöstä. <Kanava> on vaadittu vain jos\n"
|
||||
"viestiä ei lähetetä kanavalla itsellään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:733
|
||||
msgid ""
|
||||
"[<channel>] [<plugin>] [<command>]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will disable the <command>\n"
|
||||
" in <channel>. If <plugin> is provided, <command> will be disabled only\n"
|
||||
" for that plugin. If only <plugin> is provided, all commands in the\n"
|
||||
" given plugin will be disabled. <channel> is only necessary if the\n"
|
||||
" message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [<lisäosa>] [<komento>]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä poistaa <komennon> käytöstä\n"
|
||||
"<kanavalla>. Jos <lisäosa> on annrttu, <komento> poistetaan käytöstä\n"
|
||||
"vain siitä lisäosasta. Jos vain <lisäosa> on annettu, kaikki komennot\n"
|
||||
"annetusta lisäosasta poistetaan käytöstä. <Kanava> on vaadittu vain jos\n"
|
||||
"viestiä ei lähetetä kanavalla itsellään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:749
|
||||
#: plugin.py:788
|
||||
msgid "The %s plugin does not have a command called %s."
|
||||
msgstr "%s lisäosalla ei ole komentoa %s."
|
||||
|
||||
#: plugin.py:756
|
||||
#: plugin.py:795
|
||||
msgid "No plugin or command named %s could be found."
|
||||
msgstr "Lisäosaa tai komentoa nimeltä %s ei löytynyt."
|
||||
|
||||
#: plugin.py:772
|
||||
msgid ""
|
||||
"[<channel>] [<plugin>] [<command>]\n"
|
||||
"\n"
|
||||
" If you have the #channel,op capability, this will enable the <command>\n"
|
||||
" in <channel> if it has been disabled. If <plugin> is provided,\n"
|
||||
" <command> will be enabled only for that plugin. If only <plugin> is\n"
|
||||
" provided, all commands in the given plugin will be enabled. <channel>\n"
|
||||
" is only necessary if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] [<lisäosa>] [<komento>]\n"
|
||||
"\n"
|
||||
"Jos sinulla on #kanava,op valtuus, tämä ottaa <komennon> käyttöön\n"
|
||||
" <kanavalla> jos se on ollut pois käytöstä. Jos <lisäosa> on annettu,\n"
|
||||
" <komento> otetaan käyttöön vain siinä lisäosassa. Jos vain <lisäosa> on\n"
|
||||
"annettu, kaikki komennot annetussa lisäosassa otetaan käyttööön. <Kanava>\n"
|
||||
"on vaadittu vain jos viestiä ei lähetetä kanavalla itsellään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:809
|
||||
msgid "%s was not disabled."
|
||||
msgstr "%s ei ollut pois käytöstä."
|
||||
|
||||
#: plugin.py:818
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" Returns the nicks in <channel>. <channel> is only necessary if the\n"
|
||||
" message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>]\n"
|
||||
"\n"
|
||||
"Palauttaa nimimerkit, jotka ovat <kanavalla>. <Kanava> on vaadittu vain jos\n"
|
||||
"ei lähetetä kanavalla itsellään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:829
|
||||
msgid "You don't have access to that information."
|
||||
msgstr "Sinulla ei ole pääsyoikeutta tuohon tietoon."
|
||||
|
||||
#: plugin.py:837
|
||||
msgid ""
|
||||
"Internal message for notifying all the #channel,ops in a channel of\n"
|
||||
" a given situation."
|
||||
msgstr ""
|
||||
"Sisäinen viesti huomattamaan kaikkia #kanava,oppeja kanavalla\n"
|
||||
" annetusta tilanteesta."
|
||||
|
||||
#: plugin.py:840
|
||||
msgid "Alert to all %s ops: %s"
|
||||
msgstr "Hälytys kaikki %s operaattoreille: %s"
|
||||
|
||||
#: plugin.py:842
|
||||
msgid " (from %s)"
|
||||
msgstr "(%s:tä)"
|
||||
|
||||
#: plugin.py:850
|
||||
msgid ""
|
||||
"[<channel>] <text>\n"
|
||||
"\n"
|
||||
" Sends <text> to all the users in <channel> who have the <channel>,op\n"
|
||||
" capability.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<kanava>] <teksti>\n"
|
||||
"\n"
|
||||
"Lähettää <tekstin> kaikille käyttäjille <kanavalla> joilla on <kanava>,op\n"
|
||||
"valtuus.\n"
|
||||
" "
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot-fr\n"
|
||||
"POT-Creation-Date: 2010-10-25 13:10+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
|
@ -644,35 +644,36 @@ msgstr "%s n'était pas désactivé."
|
|||
|
||||
#: plugin.py:818
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"[<channel>] [--count]\n"
|
||||
"\n"
|
||||
" Returns the nicks in <channel>. <channel> is only necessary if the\n"
|
||||
" message isn't sent in the channel itself.\n"
|
||||
" message isn't sent in the channel itself. Returns only the number of\n"
|
||||
" nicks if --count option is provided.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>]\n"
|
||||
"[<canal>] [--count]\n"
|
||||
"\n"
|
||||
"Retourne les nick sur le <canal>. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
"Retourne les nick sur le <canal>. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même. Ne retourne que le nombre de nicks si --count est donné."
|
||||
|
||||
#: plugin.py:829
|
||||
#: plugin.py:830
|
||||
msgid "You don't have access to that information."
|
||||
msgstr "Vous n'avez pas accès à cette information"
|
||||
|
||||
#: plugin.py:837
|
||||
#: plugin.py:843
|
||||
msgid ""
|
||||
"Internal message for notifying all the #channel,ops in a channel of\n"
|
||||
" a given situation."
|
||||
msgstr "Message interne pour notifier tous les #canal,ops sur un canal d'une situation donnée."
|
||||
|
||||
#: plugin.py:840
|
||||
#: plugin.py:846
|
||||
msgid "Alert to all %s ops: %s"
|
||||
msgstr "Alerte à tous les ops de %s : %s"
|
||||
|
||||
#: plugin.py:842
|
||||
#: plugin.py:848
|
||||
msgid " (from %s)"
|
||||
msgstr "(de %s)"
|
||||
|
||||
#: plugin.py:850
|
||||
#: plugin.py:856
|
||||
msgid ""
|
||||
"[<channel>] <text>\n"
|
||||
"\n"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-25 13:10+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -579,33 +579,34 @@ msgstr ""
|
|||
#: plugin.py:818
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"[<channel>] [--count]\n"
|
||||
"\n"
|
||||
" Returns the nicks in <channel>. <channel> is only necessary if the\n"
|
||||
" message isn't sent in the channel itself.\n"
|
||||
" message isn't sent in the channel itself. Returns only the number of\n"
|
||||
" nicks if --count option is provided.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:829
|
||||
#: plugin.py:830
|
||||
msgid "You don't have access to that information."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:837
|
||||
#: plugin.py:843
|
||||
#, docstring
|
||||
msgid ""
|
||||
"Internal message for notifying all the #channel,ops in a channel of\n"
|
||||
" a given situation."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:840
|
||||
#: plugin.py:846
|
||||
msgid "Alert to all %s ops: %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:842
|
||||
#: plugin.py:848
|
||||
msgid " (from %s)"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:850
|
||||
#: plugin.py:856
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <text>\n"
|
||||
|
|
|
@ -814,11 +814,12 @@ class Channel(callbacks.Plugin):
|
|||
additional('commandName')])
|
||||
|
||||
@internationalizeDocstring
|
||||
def nicks(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
def nicks(self, irc, msg, args, channel, optlist):
|
||||
"""[<channel>] [--count]
|
||||
|
||||
Returns the nicks in <channel>. <channel> is only necessary if the
|
||||
message isn't sent in the channel itself.
|
||||
message isn't sent in the channel itself. Returns only the number of
|
||||
nicks if --count option is provided.
|
||||
"""
|
||||
# Make sure we don't elicit information about private channels to
|
||||
# people or channels that shouldn't know
|
||||
|
@ -828,9 +829,14 @@ class Channel(callbacks.Plugin):
|
|||
msg.nick not in irc.state.channels[channel].users):
|
||||
irc.error(_('You don\'t have access to that information.'))
|
||||
L = list(irc.state.channels[channel].users)
|
||||
keys = [option for (option, arg) in optlist]
|
||||
if 'count' not in keys:
|
||||
utils.sortBy(str.lower, L)
|
||||
irc.reply(utils.str.commaAndify(L))
|
||||
nicks = wrap(nicks, ['inChannel'])
|
||||
else:
|
||||
irc.reply(str(len(L)))
|
||||
nicks = wrap(nicks, ['inChannel',
|
||||
getopts({'count':''})])
|
||||
|
||||
@internationalizeDocstring
|
||||
def alertOps(self, irc, channel, s, frm=None):
|
||||
|
|
|
@ -214,5 +214,9 @@ class ChannelTestCase(ChannelPluginTestCase):
|
|||
finally:
|
||||
conf.supybot.protocols.irc.banmask.setValue(orig)
|
||||
|
||||
def testNicks(self):
|
||||
self.assertResponse('channel nicks', 'bar, foo, and test')
|
||||
self.assertResponse('channel nicks --count', '3')
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot Channellogger\n"
|
||||
"POT-Creation-Date: 2010-10-17 10:02+CEST\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Mika Suomalainen <mika.henrik.mainio@hotmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Finnish\n"
|
||||
"X-Poedit-Country: FINLAND\n"
|
||||
|
||||
#: config.py:46
|
||||
msgid "Determines whether logging is enabled."
|
||||
msgstr "Määrittää onko lokin pitäminen käytössä."
|
||||
|
||||
#: 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 ""
|
||||
"Määrittää pitäisikö kanava lokitiedostot\n"
|
||||
" tallentaa silloin kun ne kirjoitetaan, mielummin kuin käyttöjärjestelmän\n"
|
||||
"puskuroimana."
|
||||
|
||||
#: config.py:52
|
||||
msgid ""
|
||||
"Determines whether formatting characters (such\n"
|
||||
" as bolding, color, etc.) are removed when writing the logs to disk."
|
||||
msgstr ""
|
||||
"Määrittää pitääkö muotoilu merkit (kuten\n"
|
||||
"korostukset, väri, jne.) poistaa kun lokeja kirjoitetaan levylle."
|
||||
|
||||
#: config.py:55
|
||||
msgid ""
|
||||
"Determines whether the logs for this channel are\n"
|
||||
" timestamped with the timestamp in supybot.log.timestampFormat."
|
||||
msgstr ""
|
||||
"Määrittää laitetaanko tämän kanavan lokitiedostoihin\n"
|
||||
"aikaleimat aikaleimalla, joka on määritetty asetuksella supybot.log.timestampFormat."
|
||||
|
||||
#: 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 ""
|
||||
"Määrittää millä merkkiketjulla aloitettuja viestejä\n"
|
||||
"viestejä ei tallenneta lokiin. Jos et halua\n"
|
||||
"merkkiketjua, aseta se tyhjäksi viestiketjuksi."
|
||||
|
||||
#: 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 ""
|
||||
"Määrittää kääntääkö botti automaattisesti\n"
|
||||
"lokit tällä kanavalla. Botti kääntää lokit kun\n"
|
||||
"kun aikaleima lokeille vaihtuu. Aikaleima asetetaan\n"
|
||||
"'filenameTimestamp' asetuksen mukaan."
|
||||
|
||||
#: 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 ""
|
||||
"Määrittää kuinka aikaleima, jota käytetään\n"
|
||||
"tiedostonimenä käännetyille lokeille. Kun tämä aikaleima muuttuu\n"
|
||||
"vanhat lokitiedostot suljetaan ja uudet aloitetaan. Muotomerkit\n"
|
||||
"aikaleimoille ovat time.strftime documenteissa python.org :issa. Saadaksesi\n"
|
||||
"lokisi käännetyksi, sinun täytyy myös ottaa käyttöön\n"
|
||||
"supybot.plugins.ChannelLogger.rotateLogs."
|
||||
|
||||
#: config.py:75
|
||||
msgid ""
|
||||
"Determines whether the bot will partition its\n"
|
||||
" channel logs into separate directories based on different criteria."
|
||||
msgstr ""
|
||||
"Määrittää osioiko botti kanavalokinsa\n"
|
||||
"eri hakemistoihin perustuen eri kriteereihin."
|
||||
|
||||
#: config.py:78
|
||||
msgid ""
|
||||
"Determines whether the bot will use a network\n"
|
||||
" directory if using directories."
|
||||
msgstr ""
|
||||
"Määrittää käyttääkö botti verkkohakemistoa\n"
|
||||
"jos käytetään hakemistoja."
|
||||
|
||||
#: config.py:81
|
||||
msgid ""
|
||||
"Determines whether the bot will use a channel\n"
|
||||
" directory if using directories."
|
||||
msgstr ""
|
||||
"Määrittää käyttääkö botti kanavahakemistoa\n"
|
||||
"jos käytetään hakemistoja."
|
||||
|
||||
#: 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 ""
|
||||
"Määrittää käyttääkö botti aikaleimaa\n"
|
||||
" (supybot.plugins.ChannelLogger.directories.timestamp.format määrittämänä\n"
|
||||
"jos käytetään hakemistoja."
|
||||
|
||||
#: 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 ""
|
||||
"Määrittää mitä aikaleima muotoa käytetöön\n"
|
||||
"hakemistorakenteessa kanavalokeille jos\n"
|
||||
" supybot.plugins.ChannelLogger.directories.timestamp on True."
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 10:02+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -226,10 +226,14 @@ class ChannelLogger(callbacks.Plugin):
|
|||
'*** %s was kicked by %s\n', target, msg.nick)
|
||||
|
||||
def doPart(self, irc, msg):
|
||||
if len(msg.args) > 1:
|
||||
reason = " (%s)" % msg.args[1]
|
||||
else:
|
||||
reason = ""
|
||||
for channel in msg.args[0].split(','):
|
||||
self.doLog(irc, channel,
|
||||
'*** %s <%s> has left %s\n',
|
||||
msg.nick, msg.prefix, channel)
|
||||
'*** %s <%s> has left %s%s\n',
|
||||
msg.nick, msg.prefix, channel, reason)
|
||||
|
||||
def doMode(self, irc, msg):
|
||||
channel = msg.args[0]
|
||||
|
@ -247,13 +251,17 @@ class ChannelLogger(callbacks.Plugin):
|
|||
'*** %s changes topic to "%s"\n', msg.nick, msg.args[1])
|
||||
|
||||
def doQuit(self, irc, msg):
|
||||
if len(msg.args) == 1:
|
||||
reason = " (%s)" % msg.args[0]
|
||||
else:
|
||||
reason = ""
|
||||
if not isinstance(irc, irclib.Irc):
|
||||
irc = irc.getRealIrc()
|
||||
for (channel, chan) in self.lastStates[irc].channels.iteritems():
|
||||
if msg.nick in chan.users:
|
||||
self.doLog(irc, channel,
|
||||
'*** %s <%s> has quit IRC\n',
|
||||
msg.nick, msg.prefix)
|
||||
'*** %s <%s> has quit IRC%s\n',
|
||||
msg.nick, msg.prefix, reason)
|
||||
|
||||
def outFilter(self, irc, msg):
|
||||
# Gotta catch my own messages *somehow* :)
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot ChannelStats\n"
|
||||
"POT-Creation-Date: 2010-10-16 09:41+CEST\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Mika Suomalainen <mika.henrik.mainio@hotmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Finnish\n"
|
||||
"X-Poedit-Country: FINLAND\n"
|
||||
|
||||
#: config.py:60
|
||||
msgid ""
|
||||
"Determines whether the bot will keep channel\n"
|
||||
" statistics on itself, possibly skewing the channel stats (especially in\n"
|
||||
" cases where the bot is relaying between channels on a network)."
|
||||
msgstr ""
|
||||
"Määrittää pitääkö botti kanava\n"
|
||||
"tilastot itsellään, mahdollisesti vinouttaen kanava tilastot (etenkin\n"
|
||||
"tilanteissa, joissa botti on välittämässä kanavien välillä verkossa)."
|
||||
|
||||
#: config.py:64
|
||||
msgid ""
|
||||
"Determines what\n"
|
||||
" words (i.e., pieces of text with no spaces in them) are considered\n"
|
||||
" 'smileys' for the purposes of stats-keeping."
|
||||
msgstr ""
|
||||
"Määrittää mitkä\n"
|
||||
"sanat (esim. tekstin paloja ilman välilyöntiä niiden välissä ) lasketaan\n"
|
||||
" 'hymiöiksi' tilastojen pitämisen takia."
|
||||
|
||||
#: config.py:68
|
||||
msgid ""
|
||||
"Determines what words\n"
|
||||
" (i.e., pieces of text with no spaces in them ) are considered 'frowns' for\n"
|
||||
" the purposes of stats-keeping."
|
||||
msgstr ""
|
||||
"Määrittää mitkä sanat\n"
|
||||
" (esim. paloja tekstiä ilman välilyöntiä välissä ) lasketaan 'surioiksi'\n"
|
||||
"tilastojen pitämistä varten."
|
||||
|
||||
#: plugin.py:246
|
||||
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 ""
|
||||
"[<kanava>] [<nimi>]\n"
|
||||
"\n"
|
||||
" <nimi> <kanavalla>. <kanava> on vaadittu\n"
|
||||
"jos viestiä ei lähetetä kanavalla itsessään. Jos <nimi>\n"
|
||||
" ei ole annettu, se on oletuksena viestin lähettänyt henkilö.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:259
|
||||
msgid "I couldn't find you in my user database."
|
||||
msgstr "Minä en voi löytää sinua käyttäjä tietokannastani."
|
||||
|
||||
#: plugin.py:272
|
||||
#, fuzzy
|
||||
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 on lähettänyt %n; yhteensä %n, %n, %n, ja %n; %s noista viesteistä %s. %s on liittynyt %n, poistunut kanavalta %n, sulkenut %n, potkinut jonkun %n, ollut potkittu %n, vaihtanut aihetta %n, vaihtanut tilaa %n."
|
||||
|
||||
#: plugin.py:279
|
||||
msgid "character"
|
||||
msgstr "merkki"
|
||||
|
||||
#: plugin.py:280
|
||||
#: plugin.py:363
|
||||
msgid "word"
|
||||
msgstr "sana"
|
||||
|
||||
#: plugin.py:281
|
||||
#: plugin.py:364
|
||||
msgid "smiley"
|
||||
msgstr "hymiö"
|
||||
|
||||
#: plugin.py:282
|
||||
#: plugin.py:365
|
||||
msgid "frown"
|
||||
msgstr "surio"
|
||||
|
||||
#: plugin.py:284
|
||||
#: plugin.py:366
|
||||
msgid "was an ACTION"
|
||||
msgstr "oli TOIMINTO"
|
||||
|
||||
#: plugin.py:285
|
||||
#: plugin.py:367
|
||||
msgid "were ACTIONs"
|
||||
msgstr "olivat TOIMINTOja"
|
||||
|
||||
#: plugin.py:287
|
||||
#: plugin.py:288
|
||||
#: plugin.py:289
|
||||
#: plugin.py:290
|
||||
#: plugin.py:291
|
||||
#: plugin.py:292
|
||||
#: plugin.py:293
|
||||
msgid "time"
|
||||
msgstr "aika"
|
||||
|
||||
#: plugin.py:296
|
||||
msgid "I have no stats for that %s in %s."
|
||||
msgstr "Minulla ei ole tilastoja %s:stä %s:ään."
|
||||
|
||||
#: plugin.py:304
|
||||
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 ""
|
||||
"[<kanava>] <tilasto lauseke>\n"
|
||||
"\n"
|
||||
"Palauttaa käyttäjien arvoasteikon perustuen annettuun tilasto lausekkeeseen.\n"
|
||||
"kelvolliset tilasto lausekkeet sisältävät 'msgs', 'chars',\n"
|
||||
"'words', 'smileys', 'frowns', 'actions', 'joins', 'parts', 'quits',\n"
|
||||
"'kicks', 'kicked', 'topics', and 'modes'. Mikä tahansa yksinkertainen matemaattinen\n"
|
||||
" lauseke sisältäen nämä arvot on sallittu.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:315
|
||||
msgid "There's really no reason why you should have underscores or brackets in your mathematical expression. Please remove them."
|
||||
msgstr "Ei ole mitään syytä miksi haluaisit alaviivoja tai sulkuja matemaattisessa lausekkeessa. Ole hyvä ja poista ne."
|
||||
|
||||
#: plugin.py:319
|
||||
#, fuzzy
|
||||
msgid "You can't use lambda in this command."
|
||||
msgstr "Et voi käyttää lambdaa tässä komennossa."
|
||||
|
||||
#: plugin.py:333
|
||||
msgid "stat variable"
|
||||
msgstr "aloita muuttuja"
|
||||
|
||||
#: plugin.py:349
|
||||
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 ""
|
||||
"[<kanava>]\n"
|
||||
"\n"
|
||||
"Palauttaa tilastot <kanavalle>. <Kanava> on vaadittu vain jos viestiä ei lähetetä\n"
|
||||
"kanavalla itsessään.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:357
|
||||
#, fuzzy
|
||||
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 "%s:ssä %h on ollut %i viestiä, sisältäen %i merkkiä, %n, %n, ja %n; %i noista viesteistä %s. On ollut %n, %n, %n, %n, %n, ja %n. %b tällä hetkellä %n kanavalla on huipulla %n."
|
||||
|
||||
#: plugin.py:368
|
||||
msgid "join"
|
||||
msgstr "liity"
|
||||
|
||||
#: plugin.py:369
|
||||
msgid "part"
|
||||
msgstr "poistu"
|
||||
|
||||
#: plugin.py:370
|
||||
msgid "quit"
|
||||
msgstr "poistu"
|
||||
|
||||
#: plugin.py:371
|
||||
msgid "kick"
|
||||
msgstr "potki"
|
||||
|
||||
#: plugin.py:372
|
||||
msgid "mode"
|
||||
msgstr "tila"
|
||||
|
||||
#: plugin.py:372
|
||||
#: plugin.py:373
|
||||
msgid "change"
|
||||
msgstr "vaihdos"
|
||||
|
||||
#: plugin.py:373
|
||||
msgid "topic"
|
||||
msgstr "aihe"
|
||||
|
||||
#: plugin.py:375
|
||||
#: plugin.py:376
|
||||
msgid "user"
|
||||
msgstr "käyttäjä"
|
||||
|
||||
#: plugin.py:379
|
||||
msgid "I've never been on %s."
|
||||
msgstr "En ole ikinä ollut %s:llä."
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-16 09:41+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Insert a description of your plugin here, with any notes, etc. about using it.
|
|
@ -0,0 +1,66 @@
|
|||
###
|
||||
# Copyright (c) 2010, Daniel Folkinshteyn
|
||||
# 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.
|
||||
|
||||
###
|
||||
|
||||
"""
|
||||
Add a description of the plugin (to be presented to the user inside the wizard)
|
||||
here. This should describe *what* the plugin does.
|
||||
"""
|
||||
|
||||
import supybot
|
||||
import supybot.world as world
|
||||
|
||||
# Use this for the version of this plugin. You may wish to put a CVS keyword
|
||||
# in here if you're keeping the plugin in CVS or some similar system.
|
||||
__version__ = "0.1"
|
||||
|
||||
# XXX Replace this with an appropriate author or supybot.Author instance.
|
||||
__author__ = supybot.authors.unknown
|
||||
|
||||
# This is a dictionary mapping supybot.Author instances to lists of
|
||||
# contributions.
|
||||
__contributors__ = {}
|
||||
|
||||
# This is a url where the most recent plugin package can be downloaded.
|
||||
__url__ = '' # 'http://supybot.com/Members/yourname/Conditional/download'
|
||||
|
||||
import config
|
||||
import plugin
|
||||
reload(plugin) # In case we're being reloaded.
|
||||
# Add more reloads here if you add third-party modules and want them to be
|
||||
# reloaded when this plugin is reloaded. Don't forget to import them as well!
|
||||
|
||||
if world.testing:
|
||||
import test
|
||||
|
||||
Class = plugin.Class
|
||||
configure = config.configure
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
|
@ -0,0 +1,59 @@
|
|||
###
|
||||
# Copyright (c) 2010, Daniel Folkinshteyn
|
||||
# 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.
|
||||
|
||||
###
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.registry as registry
|
||||
|
||||
try:
|
||||
from supybot.i18n import PluginInternationalization
|
||||
from supybot.i18n import internationalizeDocstring
|
||||
_ = PluginInternationalization('Conditional')
|
||||
except:
|
||||
# This are useless functions that's allow to run the plugin on a bot
|
||||
# without the i18n plugin
|
||||
_ = lambda x:x
|
||||
internationalizeDocstring = lambda x:x
|
||||
|
||||
def configure(advanced):
|
||||
# This will be called by supybot to configure this module. advanced is
|
||||
# a bool that specifies whether the user identified himself as an advanced
|
||||
# user or not. You should effect your configuration by manipulating the
|
||||
# registry as appropriate.
|
||||
from supybot.questions import expect, anything, something, yn
|
||||
conf.registerPlugin('Conditional', True)
|
||||
|
||||
|
||||
Conditional = conf.registerPlugin('Conditional')
|
||||
# This is where your configuration variables (if any) should go. For example:
|
||||
# conf.registerGlobalValue(Conditional, 'someConfigVariableName',
|
||||
# registry.Boolean(False, """Help for someConfigVariableName."""))
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
|
@ -0,0 +1 @@
|
|||
# Stub so local is a module, used for third-party modules
|
|
@ -0,0 +1,229 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Gribble\n"
|
||||
"POT-Creation-Date: 2010-11-02 11:39+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Français\n"
|
||||
"X-Poedit-Country: France\n"
|
||||
"X-Poedit-SourceCharset: ASCII\n"
|
||||
|
||||
#: plugin.py:64
|
||||
msgid ""
|
||||
"Add the help for \"@plugin help Conditional\" here\n"
|
||||
" This should describe *how* to use this plugin."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:71
|
||||
msgid "Run a command from message, as if command was sent over IRC."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:80
|
||||
msgid ""
|
||||
"<condition> <ifcommand> <elsecommand>\n"
|
||||
" \n"
|
||||
" Runs <ifcommand> if <condition> evaluates to true, runs <elsecommand>\n"
|
||||
" if it evaluates to false.\n"
|
||||
" \n"
|
||||
" Use other logical operators defined in this plugin and command nesting\n"
|
||||
" to your advantage here.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<condition> <commande1> <commande2>\n"
|
||||
"\n"
|
||||
"Exécute la <commande1> si la <condition> est évaluée à true, lance la <commande2> si elle est évaluée à false. Utilisez d'autres opérateurs logiques définis dans ce plugin et l'imbrication de commandes à votre avantage."
|
||||
|
||||
#: plugin.py:97
|
||||
msgid ""
|
||||
"<cond1> [<cond2> ... <condN>]\n"
|
||||
" \n"
|
||||
" Returns true if all conditions supplied evaluate to true.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<condition1> [<condition2> ... <conditionN>]\n"
|
||||
"\n"
|
||||
"Retourne True si toutes les conditions sont évaluées à true."
|
||||
|
||||
#: plugin.py:109
|
||||
msgid ""
|
||||
"<cond1> [<cond2> ... <condN>]\n"
|
||||
" \n"
|
||||
" Returns true if any one of conditions supplied evaluates to true.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<condition1> [<condition2> ... <conditionN>]\n"
|
||||
"\n"
|
||||
"Retourne True si une au moins des conditions est évaluée à true."
|
||||
|
||||
#: plugin.py:121
|
||||
msgid ""
|
||||
"<cond1> [<cond2> ... <condN>]\n"
|
||||
" \n"
|
||||
" Returns true if only one of conditions supplied evaluates to true.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<condition1> [<condition2> ... <conditionN>]\n"
|
||||
"\n"
|
||||
"Retourne True si une seule des conditions est évaluée à true."
|
||||
|
||||
#: plugin.py:133
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if they are equal.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison de chaîne entre <élément1> et <élément2>. Retourne true si ils sont égaux."
|
||||
|
||||
#: plugin.py:146
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if they are not equal.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison de chaîne entre <élément1> et <élément2>. Retourne true si ils sont inégaux."
|
||||
|
||||
#: plugin.py:159
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is greater than <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison de chaîne entre <élément1> et <élément2>. Retourne true si <élément1> est plus grand que <élément2>"
|
||||
|
||||
#: plugin.py:172
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is greater than or equal to <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison de chaîne entre <élément1> et <élément2>. Retourne true si <élément1> est plus grand ou égal à <élément2>"
|
||||
|
||||
#: plugin.py:185
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is less than <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison de chaîne entre <élément1> et <élément2>. Retourne true si <élément1> est plus petit que <élément2>"
|
||||
|
||||
#: plugin.py:198
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is less than or equal to <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison de chaîne entre <élément1> et <élément2>. Retourne true si <élément1> est plus petit ou égal à <élément2>"
|
||||
|
||||
#: plugin.py:211
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Determines if <item1> is a substring of <item2>. \n"
|
||||
" Returns true if <item1> is contained in <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Détermine si <élément1> est une sous-chaîne de <élément2>. Retourne true si <élément1> est contenu dans <élément2>"
|
||||
|
||||
#: plugin.py:224
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if they are equal.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison numérique entre <élément1> et <élément2>. Retourne true si ils sont égaux."
|
||||
|
||||
#: plugin.py:237
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if they are not equal.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison numérique entre <élément1> et <élément2>. Retourne true si ils sont inégaux."
|
||||
|
||||
#: plugin.py:250
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if they <item1> is greater than <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison numérique entre <élément1> et <élément2>. Retourne true si <élément1> est plus grand que <élément2>"
|
||||
|
||||
#: plugin.py:263
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is greater than or equal to <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison numérique entre <élément1> et <élément2>. Retourne true si <élément1> est plus grand ou égal à <élément2>"
|
||||
|
||||
#: plugin.py:276
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is less than <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison numérique entre <élément1> et <élément2>. Retourne true si <élément1> est plus petit que <élément2>"
|
||||
|
||||
#: plugin.py:289
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is less than or equal to <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<élément1> <élément2>\n"
|
||||
"\n"
|
||||
"Fait une comparaison numérique entre <élément1> et <élément2>. Retourne true si <élément1> est plus petit ou égal à <élément2>"
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-11-02 11:39+CET\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:64
|
||||
#, docstring
|
||||
msgid ""
|
||||
"Add the help for \"@plugin help Conditional\" here\n"
|
||||
" This should describe *how* to use this plugin."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:71
|
||||
#, docstring
|
||||
msgid "Run a command from message, as if command was sent over IRC."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:80
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<condition> <ifcommand> <elsecommand>\n"
|
||||
" \n"
|
||||
" Runs <ifcommand> if <condition> evaluates to true, runs <elsecommand>\n"
|
||||
" if it evaluates to false.\n"
|
||||
" \n"
|
||||
" Use other logical operators defined in this plugin and command nesting\n"
|
||||
" to your advantage here.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:97
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<cond1> [<cond2> ... <condN>]\n"
|
||||
" \n"
|
||||
" Returns true if all conditions supplied evaluate to true.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:109
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<cond1> [<cond2> ... <condN>]\n"
|
||||
" \n"
|
||||
" Returns true if any one of conditions supplied evaluates to true.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:121
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<cond1> [<cond2> ... <condN>]\n"
|
||||
" \n"
|
||||
" Returns true if only one of conditions supplied evaluates to true.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:133
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if they are equal.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:146
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if they are not equal.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:159
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is greater than <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:172
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is greater than or equal to <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:185
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is less than <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:198
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a string comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is less than or equal to <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:211
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Determines if <item1> is a substring of <item2>. \n"
|
||||
" Returns true if <item1> is contained in <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:224
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if they are equal.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:237
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if they are not equal.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:250
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if they <item1> is greater than <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:263
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is greater than or equal to <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:276
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is less than <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:289
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<item1> <item2>\n"
|
||||
" \n"
|
||||
" Does a numeric comparison on <item1> and <item2>. \n"
|
||||
" Returns true if <item1> is less than or equal to <item2>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
###
|
||||
# Copyright (c) 2010, Daniel Folkinshteyn
|
||||
# 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.
|
||||
|
||||
###
|
||||
|
||||
import supybot.utils as utils
|
||||
from supybot.commands import *
|
||||
import supybot.plugins as plugins
|
||||
import supybot.ircutils as ircutils
|
||||
import supybot.callbacks as callbacks
|
||||
|
||||
import re
|
||||
|
||||
try:
|
||||
from supybot.i18n import PluginInternationalization
|
||||
from supybot.i18n import internationalizeDocstring
|
||||
_ = PluginInternationalization('Conditional')
|
||||
except:
|
||||
# This are useless functions that's allow to run the plugin on a bot
|
||||
# without the i18n plugin
|
||||
_ = lambda x:x
|
||||
internationalizeDocstring = lambda x:x
|
||||
|
||||
# builtin any is overwritten by callbacks... and python2.4 doesn't have it
|
||||
def _any(iterable):
|
||||
for element in iterable:
|
||||
if element:
|
||||
return True
|
||||
return False
|
||||
# for consistency with above, and for python2.4
|
||||
def _all(iterable):
|
||||
for element in iterable:
|
||||
if not element:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class Conditional(callbacks.Plugin):
|
||||
"""Add the help for "@plugin help Conditional" here
|
||||
This should describe *how* to use this plugin."""
|
||||
threaded = True
|
||||
def __init__(self, irc):
|
||||
callbacks.Plugin.__init__(self, irc)
|
||||
|
||||
def _runCommandFunction(self, irc, msg, command):
|
||||
"""Run a command from message, as if command was sent over IRC."""
|
||||
tokens = callbacks.tokenize(command)
|
||||
try:
|
||||
self.Proxy(irc.irc, msg, tokens)
|
||||
except Exception, e:
|
||||
log.exception('Uncaught exception in requested function:')
|
||||
|
||||
@internationalizeDocstring
|
||||
def cif(self, irc, msg, args, condition, ifcommand, elsecommand):
|
||||
"""<condition> <ifcommand> <elsecommand>
|
||||
|
||||
Runs <ifcommand> if <condition> evaluates to true, runs <elsecommand>
|
||||
if it evaluates to false.
|
||||
|
||||
Use other logical operators defined in this plugin and command nesting
|
||||
to your advantage here.
|
||||
"""
|
||||
if condition:
|
||||
self._runCommandFunction(irc, msg, ifcommand)
|
||||
else:
|
||||
self._runCommandFunction(irc, msg, elsecommand)
|
||||
irc.noReply()
|
||||
cif = wrap(cif, ['boolean', 'something', 'something'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def cand(self, irc, msg, args, conds):
|
||||
"""<cond1> [<cond2> ... <condN>]
|
||||
|
||||
Returns true if all conditions supplied evaluate to true.
|
||||
"""
|
||||
if _all(conds):
|
||||
irc.reply("true")
|
||||
else:
|
||||
irc.reply("false")
|
||||
cand = wrap(cand, [many('boolean'),])
|
||||
|
||||
@internationalizeDocstring
|
||||
def cor(self, irc, msg, args, conds):
|
||||
"""<cond1> [<cond2> ... <condN>]
|
||||
|
||||
Returns true if any one of conditions supplied evaluates to true.
|
||||
"""
|
||||
if _any(conds):
|
||||
irc.reply("true")
|
||||
else:
|
||||
irc.reply("false")
|
||||
cor = wrap(cor, [many('boolean'),])
|
||||
|
||||
@internationalizeDocstring
|
||||
def cxor(self, irc, msg, args, conds):
|
||||
"""<cond1> [<cond2> ... <condN>]
|
||||
|
||||
Returns true if only one of conditions supplied evaluates to true.
|
||||
"""
|
||||
if sum(conds) == 1:
|
||||
irc.reply("true")
|
||||
else:
|
||||
irc.reply("false")
|
||||
cxor = wrap(cxor, [many('boolean'),])
|
||||
|
||||
@internationalizeDocstring
|
||||
def ceq(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a string comparison on <item1> and <item2>.
|
||||
Returns true if they are equal.
|
||||
"""
|
||||
if item1 == item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
ceq = wrap(ceq, ['anything', 'anything'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def ne(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a string comparison on <item1> and <item2>.
|
||||
Returns true if they are not equal.
|
||||
"""
|
||||
if item1 != item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
ne = wrap(ne, ['anything', 'anything'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def gt(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a string comparison on <item1> and <item2>.
|
||||
Returns true if <item1> is greater than <item2>.
|
||||
"""
|
||||
if item1 > item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
gt = wrap(gt, ['anything', 'anything'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def ge(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a string comparison on <item1> and <item2>.
|
||||
Returns true if <item1> is greater than or equal to <item2>.
|
||||
"""
|
||||
if item1 >= item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
ge = wrap(ge, ['anything', 'anything'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def lt(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a string comparison on <item1> and <item2>.
|
||||
Returns true if <item1> is less than <item2>.
|
||||
"""
|
||||
if item1 < item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
lt = wrap(lt, ['anything', 'anything'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def le(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a string comparison on <item1> and <item2>.
|
||||
Returns true if <item1> is less than or equal to <item2>.
|
||||
"""
|
||||
if item1 <= item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
le = wrap(le, ['anything', 'anything'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def match(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Determines if <item1> is a substring of <item2>.
|
||||
Returns true if <item1> is contained in <item2>.
|
||||
"""
|
||||
if item2.find(item1) != -1:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
match = wrap(match, ['something', 'something'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def nceq(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a numeric comparison on <item1> and <item2>.
|
||||
Returns true if they are equal.
|
||||
"""
|
||||
if item1 == item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
nceq = wrap(nceq, ['float', 'float'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def nne(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a numeric comparison on <item1> and <item2>.
|
||||
Returns true if they are not equal.
|
||||
"""
|
||||
if item1 != item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
nne = wrap(nne, ['float', 'float'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def ngt(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a numeric comparison on <item1> and <item2>.
|
||||
Returns true if they <item1> is greater than <item2>.
|
||||
"""
|
||||
if item1 > item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
ngt = wrap(ngt, ['float', 'float'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def nge(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a numeric comparison on <item1> and <item2>.
|
||||
Returns true if <item1> is greater than or equal to <item2>.
|
||||
"""
|
||||
if item1 >= item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
nge = wrap(nge, ['float', 'float'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def nlt(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a numeric comparison on <item1> and <item2>.
|
||||
Returns true if <item1> is less than <item2>.
|
||||
"""
|
||||
if item1 < item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
nlt = wrap(nlt, ['float', 'float'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def nle(self, irc, msg, args, item1, item2):
|
||||
"""<item1> <item2>
|
||||
|
||||
Does a numeric comparison on <item1> and <item2>.
|
||||
Returns true if <item1> is less than or equal to <item2>.
|
||||
"""
|
||||
if item1 <= item2:
|
||||
irc.reply('true')
|
||||
else:
|
||||
irc.reply('false')
|
||||
nle = wrap(nle, ['float', 'float'])
|
||||
Condition = internationalizeDocstring(Conditional)
|
||||
|
||||
Class = Conditional
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
|
@ -0,0 +1,143 @@
|
|||
###
|
||||
# Copyright (c) 2010, Daniel Folkinshteyn
|
||||
# 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.
|
||||
|
||||
###
|
||||
|
||||
from supybot.test import *
|
||||
|
||||
class ConditionalTestCase(PluginTestCase):
|
||||
plugins = ('Conditional','Utilities',)
|
||||
|
||||
def testCif(self):
|
||||
self.assertError('cif stuff')
|
||||
self.assertRegexp('cif [ceq bla bla] "echo moo" "echo foo"', 'moo')
|
||||
self.assertRegexp('cif [ceq bla bar] "echo moo" "echo foo"', 'foo')
|
||||
self.assertRegexp('cif [cand [ceq bla bla] [ne soo boo]] "echo moo" "echo foo"', 'moo')
|
||||
self.assertRegexp('cif [ceq [echo $nick] "test"] "echo yay" "echo nay"', 'yay')
|
||||
|
||||
def testCand(self):
|
||||
self.assertRegexp('cand true true', 'true')
|
||||
self.assertRegexp('cand false true', 'false')
|
||||
self.assertRegexp('cand true false', 'false')
|
||||
self.assertRegexp('cand false false', 'false')
|
||||
self.assertRegexp('cand true true true', 'true')
|
||||
|
||||
def testCor(self):
|
||||
self.assertRegexp('cor true true', 'true')
|
||||
self.assertRegexp('cor false true', 'true')
|
||||
self.assertRegexp('cor true false', 'true')
|
||||
self.assertRegexp('cor false false', 'false')
|
||||
self.assertRegexp('cor true true true', 'true')
|
||||
|
||||
def testCxor(self):
|
||||
self.assertRegexp('cxor true true', 'false')
|
||||
self.assertRegexp('cxor false true', 'true')
|
||||
self.assertRegexp('cxor true false', 'true')
|
||||
self.assertRegexp('cxor false false', 'false')
|
||||
self.assertRegexp('cxor true true true', 'false')
|
||||
|
||||
def testCeq(self):
|
||||
self.assertRegexp('ceq bla bla', 'true')
|
||||
self.assertRegexp('ceq bla moo', 'false')
|
||||
self.assertError('ceq bla bla bla')
|
||||
|
||||
def testNe(self):
|
||||
self.assertRegexp('ne bla bla', 'false')
|
||||
self.assertRegexp('ne bla moo', 'true')
|
||||
self.assertError('ne bla bla bla')
|
||||
|
||||
def testGt(self):
|
||||
self.assertRegexp('gt bla bla', 'false')
|
||||
self.assertRegexp('gt bla moo', 'false')
|
||||
self.assertRegexp('gt moo bla', 'true')
|
||||
self.assertError('gt bla bla bla')
|
||||
|
||||
def testGe(self):
|
||||
self.assertRegexp('ge bla bla', 'true')
|
||||
self.assertRegexp('ge bla moo', 'false')
|
||||
self.assertRegexp('ge moo bla', 'true')
|
||||
self.assertError('ge bla bla bla')
|
||||
|
||||
def testLt(self):
|
||||
self.assertRegexp('lt bla bla', 'false')
|
||||
self.assertRegexp('lt bla moo', 'true')
|
||||
self.assertRegexp('lt moo bla', 'false')
|
||||
self.assertError('lt bla bla bla')
|
||||
|
||||
def testLe(self):
|
||||
self.assertRegexp('le bla bla', 'true')
|
||||
self.assertRegexp('le bla moo', 'true')
|
||||
self.assertRegexp('le moo bla', 'false')
|
||||
self.assertError('le bla bla bla')
|
||||
|
||||
def testMatch(self):
|
||||
self.assertRegexp('match bla mooblafoo', 'true')
|
||||
self.assertRegexp('match bla mooblfoo', 'false')
|
||||
self.assertError('match bla bla stuff')
|
||||
|
||||
def testNceq(self):
|
||||
self.assertRegexp('nceq 10.0 10', 'true')
|
||||
self.assertRegexp('nceq 4 5', 'false')
|
||||
self.assertError('nceq 1 2 3')
|
||||
self.assertError('nceq bla 1')
|
||||
|
||||
def testNne(self):
|
||||
self.assertRegexp('nne 1 1', 'false')
|
||||
self.assertRegexp('nne 2.2 3', 'true')
|
||||
self.assertError('nne 1 2 3')
|
||||
self.assertError('nne bla 3')
|
||||
|
||||
def testNgt(self):
|
||||
self.assertRegexp('ngt 3 3', 'false')
|
||||
self.assertRegexp('ngt 2 3', 'false')
|
||||
self.assertRegexp('ngt 4 3', 'true')
|
||||
self.assertError('ngt 1 2 3')
|
||||
self.assertError('ngt 3 bla')
|
||||
|
||||
def testNge(self):
|
||||
self.assertRegexp('nge 3 3', 'true')
|
||||
self.assertRegexp('nge 3 4', 'false')
|
||||
self.assertRegexp('nge 5 4.3', 'true')
|
||||
self.assertError('nge 3 4.5 4')
|
||||
self.assertError('nge 45 bla')
|
||||
|
||||
def testNlt(self):
|
||||
self.assertRegexp('nlt 3 3', 'false')
|
||||
self.assertRegexp('nlt 3 4.5', 'true')
|
||||
self.assertRegexp('nlt 5 3', 'false')
|
||||
self.assertError('nlt 2 3 4')
|
||||
self.assertError('nlt bla bla')
|
||||
|
||||
def testNle(self):
|
||||
self.assertRegexp('nle 2 2', 'true')
|
||||
self.assertRegexp('nle 2 3.5', 'true')
|
||||
self.assertRegexp('nle 4 3', 'false')
|
||||
self.assertError('nle 3 4 5')
|
||||
self.assertError('nle 1 bla')
|
||||
|
||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
|
@ -0,0 +1,176 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Finnish translation of Config plugin in Supybot\n"
|
||||
"POT-Creation-Date: 2010-12-12 15:02+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Mika Suomalainen <mika.henrik.mainio@hotmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Finnish\n"
|
||||
"X-Poedit-Country: FINLAND\n"
|
||||
|
||||
#: plugin.py:103
|
||||
msgid "configuration variable"
|
||||
msgstr "asetusarvo"
|
||||
|
||||
#: plugin.py:109
|
||||
msgid "settable configuration variable"
|
||||
msgstr "asetettava asetusarvo"
|
||||
|
||||
#: plugin.py:136
|
||||
msgid ""
|
||||
"<group>\n"
|
||||
"\n"
|
||||
" Returns the configuration variables available under the given\n"
|
||||
" configuration <group>. If a variable has values under it, it is\n"
|
||||
" preceded by an '@' sign. If a variable is a 'ChannelValue', that is,\n"
|
||||
" it can be separately configured for each channel using the 'channel'\n"
|
||||
" command in this plugin, it is preceded by an '#' sign.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<ryhmä>\n"
|
||||
"\n"
|
||||
"Palauttaa asetusarvot, jotka ovat annetun\n"
|
||||
"asetus <ryhmän> alla. Jos arvolla on toisia arvoja allaan, se on\n"
|
||||
" merkitty '@' merkillä. Jos arvo on 'ChannelValue', se voi olla,\n"
|
||||
"erikseen määritelty jokaiselle kanavalle käyttämällä 'channel'\n"
|
||||
"komentoa tässä lisäosassa, se on merkitty '#' merkillä.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:148
|
||||
msgid "There don't seem to be any values in %s."
|
||||
msgstr "%s:ssä ei näytä olevan yhtään asetusarvoja."
|
||||
|
||||
#: plugin.py:154
|
||||
msgid ""
|
||||
"<word>\n"
|
||||
"\n"
|
||||
" Searches for <word> in the current configuration variables.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<sana>\n"
|
||||
"\n"
|
||||
"Etsii <sanaa> nykyisistä asetus arvoista.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:167
|
||||
msgid "There were no matching configuration variables."
|
||||
msgstr "Täsmääviä asetusarvoja ei löytynyt."
|
||||
|
||||
#: plugin.py:174
|
||||
msgid "Global: %s; %s: %s"
|
||||
msgstr "Globaali: %s; %s: %s"
|
||||
|
||||
#: plugin.py:185
|
||||
msgid "That registry variable has no value. Use the list command in this plugin to see what variables are available in this group."
|
||||
msgstr "Sillä rekisteriarvolla ei ole arvoa. Käytä list komentoa tässä lisäosassa nähdäksesi mitä arvoja on saatavilla tässä ryhmässä."
|
||||
|
||||
#: plugin.py:200
|
||||
msgid ""
|
||||
"[<channel>] <name> [<value>]\n"
|
||||
"\n"
|
||||
" If <value> is given, sets the channel configuration variable for <name>\n"
|
||||
" to <value> for <channel>. Otherwise, returns the current channel\n"
|
||||
" configuration value of <name>. <channel> is only necessary if the\n"
|
||||
" message isn't sent in the channel itself."
|
||||
msgstr ""
|
||||
"[<kanava>] <nimi> [<arvo>]\n"
|
||||
"\n"
|
||||
"Jos <arvo> on annettu, asettaa <nimen> kanavan asetusarvon\n"
|
||||
"<arvoksi> <kanavalle>. Muutoin, palauttaa nykyisen \n"
|
||||
"<nimen> nykyisen kanava asetusarvon. <Kanava> on vaadittu vain\n"
|
||||
"jos viestiä ei lähetetä kanavalla itsellään."
|
||||
|
||||
#: plugin.py:207
|
||||
msgid "That configuration variable is not a channel-specific configuration variable."
|
||||
msgstr "Tällä asetusarvolla ei ole kanava kohtaista asetusarvoa."
|
||||
|
||||
#: plugin.py:220
|
||||
msgid ""
|
||||
"<name> [<value>]\n"
|
||||
"\n"
|
||||
" If <value> is given, sets the value of <name> to <value>. Otherwise,\n"
|
||||
" returns the current value of <name>. You may omit the leading\n"
|
||||
" \"supybot.\" in the name if you so choose.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<kanava> [<arvo>]\n"
|
||||
"\n"
|
||||
"Jos <arvo> on annettu, asettaa <nimen> arvon <arvoksi>. Muutoin palauttaa,\n"
|
||||
"<nimen> nykyisen arvon. Voit jättää pois seuraavan rivin pois \n"
|
||||
" \"supybot.\" .\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:234
|
||||
msgid ""
|
||||
"<name>\n"
|
||||
"\n"
|
||||
" Returns the description of the configuration variable <name>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<nimi>\n"
|
||||
"\n"
|
||||
" Palauttaa asetusarvon kuvauksen <nimi>.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:242
|
||||
msgid " (Current value: %s)"
|
||||
msgstr " (Nykyinen arvo: %s)"
|
||||
|
||||
#: plugin.py:245
|
||||
msgid "That configuration group exists, but seems to have no help. Try \"config list %s\" to see if it has any children values."
|
||||
msgstr "Tuo asetusryhmä on olemassa, mutta sillä ei näytä olevan ohjetta. Käytä komentoa \"config list %s\" nähdäksesi onko sillä yhtään alempia arvoja."
|
||||
|
||||
#: plugin.py:249
|
||||
msgid "%s has no help."
|
||||
msgstr "%s:llä ei ole ohjetta."
|
||||
|
||||
#: plugin.py:254
|
||||
msgid ""
|
||||
"<name>\n"
|
||||
"\n"
|
||||
" Returns the default value of the configuration variable <name>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<name>\n"
|
||||
"\n"
|
||||
"Palauttaa asetusarvon oletusarvon <nimi>.\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:264
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
" Reloads the various configuration files (user database, channel\n"
|
||||
" database, registry, etc.).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"ei ota parametrejä\n"
|
||||
"\n"
|
||||
"Lataa uudelleen joitain asetustiedostoja(käyttäjä tietokanta, kanava\n"
|
||||
" tietokanta, rekisteri, jne.).\n"
|
||||
" "
|
||||
|
||||
#: plugin.py:275
|
||||
msgid ""
|
||||
"<filename>\n"
|
||||
"\n"
|
||||
" Exports the public variables of your configuration to <filename>.\n"
|
||||
" If you want to show someone your configuration file, but you don't\n"
|
||||
" want that person to be able to see things like passwords, etc., this\n"
|
||||
" command will export a \"sanitized\" configuration file suitable for\n"
|
||||
" showing publicly.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<tiedostonimi>\n"
|
||||
"\n"
|
||||
"Vie julkiset asetusarvot asetustiedostostasi <tiedostonimeen>.\n"
|
||||
" Jos haluat näyttää jollekulle asetustiedostosi, mutta et\n"
|
||||
"halua tuon henkilön näkevän salasanojasi, jne., tämä\n"
|
||||
"komento vie \"järjellistetyn\" asetustiedoston, joka sopii\n"
|
||||
"julkisesti näyttämiseen.\n"
|
||||
" "
|
||||
|
|
@ -152,5 +152,5 @@ msgid ""
|
|||
msgstr ""
|
||||
"<nom de fichier>\n"
|
||||
"\n"
|
||||
"Exporte les variables de configuration publiques dans le fichier<nom de fichier. Si vous voulez donner à quelqu'un votre fichierde configuration, mais que vous ne voulez pas que cette personnepuisse voir des choses comme les mot de passe, ... cette commandedébarrasse le fichier de configuration exporté des données qui nedoivent pas être publiques."
|
||||
"Exporte les variables de configuration publiques dans le fichier<nom de fichier. Si vous voulez donner à quelqu'un votre fichier de configuration, mais que vous ne voulez pas que cette personne puisse voir des choses comme les mots de passe, ... cette commande débarrasse le fichier de configuration exporté des données qui ne doivent pas être publiques."
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-12-12 15:02+CET\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot-fr\n"
|
||||
"POT-Creation-Date: 2010-10-26 18:57+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
|
@ -13,7 +13,46 @@ msgstr ""
|
|||
"X-Poedit-Country: France\n"
|
||||
"X-Poedit-SourceCharset: ASCII\n"
|
||||
|
||||
#: plugin.py:77
|
||||
msgid "PING ?(.*)"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:86
|
||||
msgid "VERSION"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:91
|
||||
msgid "USERINFO"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:96
|
||||
msgid "TIME"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:101
|
||||
msgid "FINGER"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:104
|
||||
msgid "Supybot, the best Python IRC bot in existence!"
|
||||
msgstr "Supybot, le meilleur bot IRC en Python au monde !"
|
||||
|
||||
#: plugin.py:107
|
||||
msgid "SOURCE"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:123
|
||||
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 ""
|
||||
"[<canal>] [--nicks]\n"
|
||||
"\n"
|
||||
"Envoie un CTCP VERSION au canal, et renvoie les différentes réponses reçues. Il attend 10 secondes avant de renvoyer les réponses reçues jusqu'alors. Si --nicks est donné, les nicks sont associés à la chaîne de version ; sinon, seules les chaînes sont données."
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-26 18:57+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -15,7 +15,50 @@ msgstr ""
|
|||
"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 "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 ""
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot-fr\n"
|
||||
"POT-Creation-Date: 2010-10-17 10:39+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
|
@ -34,7 +34,7 @@ msgid ""
|
|||
" will use all dictionaries to define words."
|
||||
msgstr "Détermine le dictionnaire par défaut dans lequel le bot cherchera les définitions. Si la valeur est '*' (sans les guillemets), le bot utilisera tous les dictionnaires pour définir le mot."
|
||||
|
||||
#: plugin.py:52
|
||||
#: plugin.py:54
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
|
@ -45,7 +45,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne les dictionnaires valides pour la commande dict."
|
||||
|
||||
#: plugin.py:68
|
||||
#: plugin.py:70
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
|
@ -56,7 +56,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne un dictionnaire valide aléatoire."
|
||||
|
||||
#: plugin.py:83
|
||||
#: plugin.py:85
|
||||
msgid ""
|
||||
"[<dictionary>] <word>\n"
|
||||
"\n"
|
||||
|
@ -68,19 +68,33 @@ msgstr ""
|
|||
"\n"
|
||||
"Recherche la définition du mot sur le serveur dictd spécifié par la variable de configuration supybot.plugins.Dict.server."
|
||||
|
||||
#: plugin.py:106
|
||||
#: plugin.py:108
|
||||
msgid "You must give a word to define."
|
||||
msgstr "Vous devez donner un mot à définir."
|
||||
|
||||
#: plugin.py:112
|
||||
#: plugin.py:114
|
||||
msgid "No definition for %q could be found."
|
||||
msgstr "La définition de %q ne peut être trouvée."
|
||||
|
||||
#: plugin.py:115
|
||||
#: plugin.py:117
|
||||
msgid "No definition for %q could be found in %s"
|
||||
msgstr "La définition de %q ne peut être trouvée dans %s."
|
||||
|
||||
#: plugin.py:127
|
||||
#: plugin.py:129
|
||||
msgid "%L responded: %s"
|
||||
msgstr "%L a répondu : %s"
|
||||
|
||||
#: plugin.py:136
|
||||
msgid ""
|
||||
"<word> [<word> ...]\n"
|
||||
" Gets a random synonym from the Moby Thesaurus (moby-thes) database.\n"
|
||||
" \n"
|
||||
" If given many words, gets a random synonym for each of them.\n"
|
||||
" \n"
|
||||
" Quote phrases to have them treated as one lookup word.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<mot> [<mot> ...]\n"
|
||||
"\n"
|
||||
"Récupère un synonyme aléatoire à partir de la base de données de Moby Thesaurus (moby-thes).Si plusieurs mots sont donnés, récupère un synonyme aléatoire pour chaque d'eux.Mettez les phrases entre guillemets pour qu'elles soient considérées comme un seul mot."
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 10:39+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -36,7 +36,7 @@ msgid ""
|
|||
" will use all dictionaries to define words."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:52
|
||||
#: plugin.py:54
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
|
@ -45,7 +45,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:68
|
||||
#: plugin.py:70
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
|
@ -54,7 +54,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:83
|
||||
#: plugin.py:85
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<dictionary>] <word>\n"
|
||||
|
@ -64,19 +64,31 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:106
|
||||
#: plugin.py:108
|
||||
msgid "You must give a word to define."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:112
|
||||
#: plugin.py:114
|
||||
msgid "No definition for %q could be found."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:115
|
||||
#: plugin.py:117
|
||||
msgid "No definition for %q could be found in %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:127
|
||||
#: plugin.py:129
|
||||
msgid "%L responded: %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:136
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<word> [<word> ...]\n"
|
||||
" Gets a random synonym from the Moby Thesaurus (moby-thes) database.\n"
|
||||
" \n"
|
||||
" If given many words, gets a random synonym for each of them.\n"
|
||||
" \n"
|
||||
" Quote phrases to have them treated as one lookup word.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ import supybot.callbacks as callbacks
|
|||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization('Dict')
|
||||
|
||||
import random
|
||||
|
||||
try:
|
||||
dictclient = utils.python.universalImport('dictclient', 'local.dictclient')
|
||||
except ImportError:
|
||||
|
@ -130,6 +132,33 @@ class Dict(callbacks.Plugin):
|
|||
irc.reply(s)
|
||||
dict = wrap(dict, [many('something')])
|
||||
|
||||
def synonym(self, irc, msg, args, words):
|
||||
"""<word> [<word> ...]
|
||||
Gets a random synonym from the Moby Thesaurus (moby-thes) database.
|
||||
|
||||
If given many words, gets a random synonym for each of them.
|
||||
|
||||
Quote phrases to have them treated as one lookup word.
|
||||
"""
|
||||
try:
|
||||
server = conf.supybot.plugins.Dict.server()
|
||||
conn = dictclient.Connection(server)
|
||||
except socket.error, e:
|
||||
irc.error(utils.web.strError(e), Raise=True)
|
||||
|
||||
dictionary = 'moby-thes'
|
||||
response = []
|
||||
for word in words:
|
||||
definitions = conn.define(dictionary, word)
|
||||
if not definitions:
|
||||
asynonym = word
|
||||
else:
|
||||
defstr = definitions[0].getdefstr()
|
||||
synlist = ' '.join(defstr.split('\n')).split(': ', 1)[1].split(',')
|
||||
asynonym = random.choice(synlist).strip()
|
||||
response.append(asynonym)
|
||||
irc.reply(' '.join(response))
|
||||
synonym = wrap(synonym, [many('something')])
|
||||
|
||||
Class = Dict
|
||||
|
||||
|
|
|
@ -44,4 +44,9 @@ class DictTestCase(PluginTestCase):
|
|||
self.assertNotError('random')
|
||||
self.assertNotError('dict [random] moo')
|
||||
|
||||
def testSynonym(self):
|
||||
self.assertNotError('synonym stuff')
|
||||
self.assertNotError('synonym someone goes home')
|
||||
self.assertRegexp('synonym nanotube', 'nanotube')
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 10:48+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -21,7 +21,7 @@ msgid ""
|
|||
" of the user giving an invalid command to the \"dunno\" response."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:38
|
||||
#: plugin.py:37
|
||||
#, docstring
|
||||
msgid ""
|
||||
"This plugin was written initially to work with MoobotFactoids, the two\n"
|
||||
|
|
|
@ -60,10 +60,20 @@ conf.registerChannelValue(Factoids, 'replyWhenInvalidCommand',
|
|||
registry.Boolean(True, _("""Determines whether the bot will reply to invalid
|
||||
commands by searching for a factoid; basically making the whatis
|
||||
unnecessary when you want all factoids for a given key.""")))
|
||||
conf.registerChannelValue(Factoids, 'replyApproximateSearchKeys',
|
||||
registry.Boolean(True, _("""If you try to look up a nonexistent factoid,
|
||||
this setting make the bot try to find some possible matching keys through
|
||||
several approximate matching algorithms and return a list of matching keys,
|
||||
before giving up.""")))
|
||||
conf.registerChannelValue(Factoids, 'format',
|
||||
FactoidFormat(_('$key could be $value.'), _("""Determines the format of
|
||||
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"
|
||||
for the factoid's value.""")))
|
||||
|
||||
conf.registerChannelValue(Factoids, 'keepRankInfo',
|
||||
registry.Boolean(True, """Determines whether we keep updating the usage
|
||||
count for each factoid, for popularity ranking."""))
|
||||
conf.registerChannelValue(Factoids, 'rankListLength',
|
||||
registry.Integer(20, """Determines the number of factoid keys returned
|
||||
by the factrank command."""))
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot-fr\n"
|
||||
"POT-Creation-Date: 2010-11-11 12:37+CET\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:58+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
|
@ -42,10 +42,18 @@ msgid ""
|
|||
msgstr "Détermine si le bot répondra aux commandes invalides lors de la recherche d'une factoid ; permet simplement de rendre la commande 'whatis' inutile lorsque vous voulez toutes les factoids d'un clef donnée."
|
||||
|
||||
#: config.py:64
|
||||
msgid ""
|
||||
"If you try to look up a nonexistent factoid,\n"
|
||||
" this setting make the bot try to find some possible matching keys through\n"
|
||||
" several approximate matching algorithms and return a list of matching keys,\n"
|
||||
" before giving up."
|
||||
msgstr "Si vous essayez de chercher une factoid inexistante, cette option permet de faire en sorte que le bot recherche les clefs de factoids dont le nom est proche, et qu'il les affiche."
|
||||
|
||||
#: config.py:69
|
||||
msgid "$key could be $value."
|
||||
msgstr "$key semble être $value."
|
||||
|
||||
#: config.py:64
|
||||
#: config.py:69
|
||||
msgid ""
|
||||
"Determines the format of\n"
|
||||
" the response given when a factoid's value is requested. All the standard\n"
|
||||
|
@ -53,7 +61,7 @@ msgid ""
|
|||
" for the factoid's value."
|
||||
msgstr "Détermine le format de la réponse donnée lorsqu'une valeur de factoid est demandée. Tous les substitus standards s'appliquent, en plus de \"$key\" pour la clef de la factoid et \"$value\" pour la valeur de la factoid."
|
||||
|
||||
#: plugin.py:153
|
||||
#: plugin.py:179
|
||||
msgid ""
|
||||
"[<channel>] <key> %s <value>\n"
|
||||
"\n"
|
||||
|
@ -68,35 +76,95 @@ msgstr ""
|
|||
"\n"
|
||||
"Associer la <clef> avec la <valeur>. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même. Le mot '%s' est nécessaire pour séparer la clef de la valeur. Il peut être modifié avec la valeur de registre learnSeparator."
|
||||
|
||||
#: plugin.py:179
|
||||
#: plugin.py:199
|
||||
msgid ""
|
||||
"Try to typo-match input to possible factoids.\n"
|
||||
" \n"
|
||||
" Assume first letter is correct, to reduce processing time. \n"
|
||||
" First, try a simple wildcard search.\n"
|
||||
" If that fails, use the Damerau-Levenshtein edit-distance metric.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:257
|
||||
#: plugin.py:391
|
||||
msgid "That's not a valid number for that key."
|
||||
msgstr "Ce n'est pas un nombre valide pour cette clef."
|
||||
|
||||
#: plugin.py:199
|
||||
#: plugin.py:345
|
||||
#: plugin.py:279
|
||||
#: plugin.py:377
|
||||
#: plugin.py:604
|
||||
msgid "No factoid matches that key."
|
||||
msgstr "Aucune factoid ne correspond à cette clef."
|
||||
|
||||
#: plugin.py:211
|
||||
#: plugin.py:304
|
||||
msgid ""
|
||||
"[<channel>] <key> [<number>]\n"
|
||||
"[<channel>] [--raw] <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"
|
||||
" number, will return only that exact factoid. If '--raw' option is\n"
|
||||
" given, no variable substitution will take place on the factoid.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel\n"
|
||||
" itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>] <clef> [<nombre>]\n"
|
||||
"\n"
|
||||
"Regarde la valeur de la <clef> dans la base de données de factoids. Si un <nombre> est donné, retourne la factoid exacte. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
"Regarde la valeur de la <clef> dans la base de données de factoids. Si un <nombre> est donné, retourne la factoid exacte.Si l'option --raw est donnée, aucune substitution de variable ne sera effectuée avant d'afficher la factoid.<canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:222
|
||||
#: plugin.py:273
|
||||
#: plugin.py:384
|
||||
#: plugin.py:321
|
||||
#: plugin.py:529
|
||||
msgid "key id"
|
||||
msgstr "id de clef"
|
||||
|
||||
#: plugin.py:230
|
||||
#: plugin.py:339
|
||||
msgid ""
|
||||
"[<channel>] <oldkey> <newkey> [<number>]\n"
|
||||
"\n"
|
||||
" Adds a new key <newkey> for factoid associated with <oldkey>.\n"
|
||||
" <number> is only necessary if there's more than one factoid associated\n"
|
||||
" with <oldkey>.\n"
|
||||
"\n"
|
||||
" The same action can be accomplished by using the 'learn' function with\n"
|
||||
" a new key but an existing (verbatim) factoid content.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>] <ancienne clef> <nouvelle clef> [<nombre>]\n"
|
||||
"\n"
|
||||
"Ajoute une <nouvelle clef> à la factoid correspondant à l'<ancienne clef>.Le <nombre> n'est nécessaire que si il y a plus d'une factoid associée à l'<ancienne clef>.La même action peut être accomplie en utilisant la fonction 'learn' avec la <nouvelle clef>, sans le contenu actuel de la factoid."
|
||||
|
||||
#: plugin.py:386
|
||||
#: plugin.py:403
|
||||
msgid "This key-factoid relationship already exists."
|
||||
msgstr "Cette relation clef-factoid existe déjà."
|
||||
|
||||
#: plugin.py:394
|
||||
msgid "This key has more than one factoid associated with it, but you have not provided a number."
|
||||
msgstr "Cette clef a plus d'une factoid associée, mais vous n'avez pas fourni un nombre."
|
||||
|
||||
#: plugin.py:409
|
||||
msgid ""
|
||||
"[<channel>] [--plain] [--alpha] [<number>]\n"
|
||||
"\n"
|
||||
" Returns a list of top-ranked factoid keys, sorted by usage count\n"
|
||||
" (rank). If <number> is not provided, the default number of factoid keys\n"
|
||||
" returned is set by the rankListLength registry value.\n"
|
||||
"\n"
|
||||
" If --plain option is given, rank numbers and usage counts are not\n"
|
||||
" included in output.\n"
|
||||
"\n"
|
||||
" If --alpha option is given in addition to --plain, keys are sorted\n"
|
||||
" alphabetically, instead of by rank.\n"
|
||||
"\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel\n"
|
||||
" itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>] [--plain] [--alpha] [<nombre>]\n"
|
||||
"\n"
|
||||
"Retourne une liste des factoids les plus utilisées. Si le <nombre> n'est pas fourni, il correspond par défaut au nombre de clefs de factoids défini dans la clef de registre rankListLength.Si --plain est donné, le numéro des rangs et le comptage des utilisations n'est pas inclu dans la sortie.Si --alpha est donné, en plus de --plain, les clefs seront triées alphabétiquement, au lieu de l'être par leur rang.<canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:454
|
||||
msgid ""
|
||||
"[<channel>] <key>\n"
|
||||
"\n"
|
||||
|
@ -109,7 +177,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Verrouille la/les factoid(s) associé(e) à la <clef>, pour qu'elles ne puissent plus être supprimées ou modifiées. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:245
|
||||
#: plugin.py:472
|
||||
msgid ""
|
||||
"[<channel>] <key>\n"
|
||||
"\n"
|
||||
|
@ -122,34 +190,39 @@ msgstr ""
|
|||
"\n"
|
||||
"Verrouille la/les factoid(s) associé(e) à la <clef>, pour qu'elles puissent être supprimées ou modifiées. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:260
|
||||
#: plugin.py:511
|
||||
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"
|
||||
" Removes a key-fact relationship for key <key> from the factoids\n"
|
||||
" database. If there is more than one such relationship for this key,\n"
|
||||
" a number is necessary to determine which one should be removed.\n"
|
||||
" A * can be used to remove all relationships for <key>.\n"
|
||||
"\n"
|
||||
" If as a result, the key (factoid) remains without any relationships to\n"
|
||||
" a factoid (key), it shall be removed from the database.\n"
|
||||
"\n"
|
||||
" <channel> is only necessary if\n"
|
||||
" the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>] <clef> [<nombre>|*]\n"
|
||||
"\n"
|
||||
"Enlève la factoid <clef> de la base de données. Si il y a plus d'une factoid avec cette clef, un <nombre> est requis pour déterminer laquelle sera supprimée. Un joker * peut être utilisé pour enlever toutes les factoids avec cette clef. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
"Enlève la factoid <clef> de la base de données. Si il y a plus d'une factoid avec cette clef, un <nombre> est requis pour déterminer laquelle sera supprimée. Un joker * peut être utilisé pour enlever toutes les factoids avec cette clef.Si, en tant que résultat, la clef (factoid) n'a plus aucune relation avec une autre factoid (clef), elle devrait être supprimée de la base de données.<canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:285
|
||||
#: plugin.py:543
|
||||
msgid "There is no such factoid."
|
||||
msgstr "Cette factoid n'existe pas."
|
||||
|
||||
#: plugin.py:298
|
||||
#: plugin.py:553
|
||||
msgid "Invalid factoid number."
|
||||
msgstr "Numéro de factoid invalide."
|
||||
|
||||
#: plugin.py:304
|
||||
#: plugin.py:558
|
||||
msgid "%s factoids have that key. Please specify which one to remove, or use * to designate all of them."
|
||||
msgstr "%s factoids ont cette clef. Veuillez spécifier laquelle vous voulez supprimer ou utiliser * pour toutes les désigner."
|
||||
|
||||
#: plugin.py:312
|
||||
#: plugin.py:566
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
|
@ -161,11 +234,11 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne une factoid aléatoire de la base de données pour le canal. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:330
|
||||
#: plugin.py:588
|
||||
msgid "I couldn't find a factoid."
|
||||
msgstr "Je ne peux trouver une factoid"
|
||||
|
||||
#: plugin.py:335
|
||||
#: plugin.py:593
|
||||
msgid ""
|
||||
"[<channel>] <key>\n"
|
||||
"\n"
|
||||
|
@ -178,11 +251,15 @@ msgstr ""
|
|||
"\n"
|
||||
"Donne des informations sur la/les factoid(s) associée(s) à la <clef>. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:358
|
||||
msgid "#%i was added by %s at %s"
|
||||
msgstr "#%i a été ajouté par %s le %s"
|
||||
#: plugin.py:619
|
||||
msgid "#%i was added by %s at %s, and has been recalled %n"
|
||||
msgstr "#%i a été ajouté par %s le %s, et il y a eu %n."
|
||||
|
||||
#: plugin.py:369
|
||||
#: plugin.py:622
|
||||
msgid "time"
|
||||
msgstr "rappel"
|
||||
|
||||
#: plugin.py:632
|
||||
msgid ""
|
||||
"[<channel>] <key> <number> <regexp>\n"
|
||||
"\n"
|
||||
|
@ -194,11 +271,11 @@ msgstr ""
|
|||
"\n"
|
||||
"Change la factoid <nombre> associée à la <clef>, en accord avec l'<expression régulière>. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:381
|
||||
#: plugin.py:646
|
||||
msgid "I couldn't find any key %q"
|
||||
msgstr "Je ne peux trouver de clef %q"
|
||||
|
||||
#: plugin.py:396
|
||||
#: plugin.py:661
|
||||
msgid ""
|
||||
"[<channel>] [--values] [--{regexp} <value>] [<glob> ...]\n"
|
||||
"\n"
|
||||
|
@ -211,11 +288,13 @@ msgstr ""
|
|||
"\n"
|
||||
"Recherche les clefs correspondant au <glob>. Si --regexp est donné, recherche les clefs correspondantes à l'<expression régulière>. Si --values est donné, recherche parmi les valeurs, plutôt que parmi les clefs. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:431
|
||||
#: plugin.py:698
|
||||
#: plugin.py:707
|
||||
msgid "No keys matched that query."
|
||||
msgstr "Aucune clef ne correspond à cette requête."
|
||||
|
||||
#: plugin.py:436
|
||||
#: plugin.py:703
|
||||
#: plugin.py:712
|
||||
msgid "More than 100 keys matched that query; please narrow your query."
|
||||
msgstr "Plus de 100 clefs correspondent à votre requête ; veuillez la préciser."
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-11-11 12:37+CET\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:58+CET\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"
|
||||
|
@ -45,10 +45,18 @@ msgid ""
|
|||
msgstr ""
|
||||
|
||||
#: config.py:64
|
||||
msgid ""
|
||||
"If you try to look up a nonexistent factoid,\n"
|
||||
" this setting make the bot try to find some possible matching keys through\n"
|
||||
" several approximate matching algorithms and return a list of matching keys,\n"
|
||||
" before giving up."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:69
|
||||
msgid "$key could be $value."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:64
|
||||
#: config.py:69
|
||||
msgid ""
|
||||
"Determines the format of\n"
|
||||
" the response given when a factoid's value is requested. All the standard\n"
|
||||
|
@ -56,7 +64,7 @@ msgid ""
|
|||
" for the factoid's value."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:153
|
||||
#: plugin.py:179
|
||||
msgid ""
|
||||
"[<channel>] <key> %s <value>\n"
|
||||
"\n"
|
||||
|
@ -68,30 +76,85 @@ msgid ""
|
|||
" "
|
||||
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
|
||||
#: plugin.py:199
|
||||
#, 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"
|
||||
"Try to typo-match input to possible factoids.\n"
|
||||
" \n"
|
||||
" Assume first letter is correct, to reduce processing time. \n"
|
||||
" First, try a simple wildcard search.\n"
|
||||
" If that fails, use the Damerau-Levenshtein edit-distance metric.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:222 plugin.py:273 plugin.py:384
|
||||
#: plugin.py:257 plugin.py:391
|
||||
msgid "That's not a valid number for that key."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:279 plugin.py:377 plugin.py:604
|
||||
msgid "No factoid matches that key."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:304
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] [--raw] <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. If '--raw' option is\n"
|
||||
" given, no variable substitution will take place on the factoid.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel\n"
|
||||
" itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:321 plugin.py:529
|
||||
msgid "key id"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:230
|
||||
#: plugin.py:339
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <oldkey> <newkey> [<number>]\n"
|
||||
"\n"
|
||||
" Adds a new key <newkey> for factoid associated with <oldkey>.\n"
|
||||
" <number> is only necessary if there's more than one factoid associated\n"
|
||||
" with <oldkey>.\n"
|
||||
"\n"
|
||||
" The same action can be accomplished by using the 'learn' function with\n"
|
||||
" a new key but an existing (verbatim) factoid content.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:386 plugin.py:403
|
||||
msgid "This key-factoid relationship already exists."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:394
|
||||
msgid "This key has more than one factoid associated with it, but you have not provided a number."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:409
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] [--plain] [--alpha] [<number>]\n"
|
||||
"\n"
|
||||
" Returns a list of top-ranked factoid keys, sorted by usage count\n"
|
||||
" (rank). If <number> is not provided, the default number of factoid keys\n"
|
||||
" returned is set by the rankListLength registry value.\n"
|
||||
"\n"
|
||||
" If --plain option is given, rank numbers and usage counts are not\n"
|
||||
" included in output.\n"
|
||||
"\n"
|
||||
" If --alpha option is given in addition to --plain, keys are sorted\n"
|
||||
" alphabetically, instead of by rank.\n"
|
||||
"\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel\n"
|
||||
" itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:454
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <key>\n"
|
||||
|
@ -102,7 +165,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:245
|
||||
#: plugin.py:472
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <key>\n"
|
||||
|
@ -113,32 +176,37 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:260
|
||||
#: plugin.py:511
|
||||
#, 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"
|
||||
" Removes a key-fact relationship for key <key> from the factoids\n"
|
||||
" database. If there is more than one such relationship for this key,\n"
|
||||
" a number is necessary to determine which one should be removed.\n"
|
||||
" A * can be used to remove all relationships for <key>.\n"
|
||||
"\n"
|
||||
" If as a result, the key (factoid) remains without any relationships to\n"
|
||||
" a factoid (key), it shall be removed from the database.\n"
|
||||
"\n"
|
||||
" <channel> is only necessary if\n"
|
||||
" the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:285
|
||||
#: plugin.py:543
|
||||
msgid "There is no such factoid."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:298
|
||||
#: plugin.py:553
|
||||
msgid "Invalid factoid number."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:304
|
||||
#: plugin.py:558
|
||||
msgid "%s factoids have that key. Please specify which one to remove, or use * to designate all of them."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:312
|
||||
#: plugin.py:566
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
|
@ -148,11 +216,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:330
|
||||
#: plugin.py:588
|
||||
msgid "I couldn't find a factoid."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:335
|
||||
#: plugin.py:593
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <key>\n"
|
||||
|
@ -163,11 +231,15 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:358
|
||||
msgid "#%i was added by %s at %s"
|
||||
#: plugin.py:619
|
||||
msgid "#%i was added by %s at %s, and has been recalled %n"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:369
|
||||
#: plugin.py:622
|
||||
msgid "time"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:632
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <key> <number> <regexp>\n"
|
||||
|
@ -177,11 +249,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:381
|
||||
#: plugin.py:646
|
||||
msgid "I couldn't find any key %q"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:396
|
||||
#: plugin.py:661
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] [--values] [--{regexp} <value>] [<glob> ...]\n"
|
||||
|
@ -192,11 +264,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:431
|
||||
#: plugin.py:698 plugin.py:707
|
||||
msgid "No keys matched that query."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:436
|
||||
#: plugin.py:703 plugin.py:712
|
||||
msgid "More than 100 keys matched that query; please narrow your query."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -43,11 +43,12 @@ from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
|||
_ = PluginInternationalization('Factoids')
|
||||
|
||||
try:
|
||||
import sqlite
|
||||
import sqlite3
|
||||
except ImportError:
|
||||
raise callbacks.Error, 'You need to have PySQLite installed to use this ' \
|
||||
'plugin. Download it at ' \
|
||||
'<http://code.google.com/p/pysqlite/>'
|
||||
from pysqlite2 import dbapi2 as sqlite3 # for python2.4
|
||||
|
||||
import re
|
||||
from supybot.utils.seq import dameraulevenshtein
|
||||
|
||||
def getFactoid(irc, msg, args, state):
|
||||
assert not state.channel
|
||||
|
@ -85,27 +86,29 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
|
||||
def makeDb(self, filename):
|
||||
if os.path.exists(filename):
|
||||
return sqlite.connect(filename)
|
||||
db = sqlite.connect(filename)
|
||||
db = sqlite3.connect(filename)
|
||||
db.text_factory = str
|
||||
return db
|
||||
db = sqlite3.connect(filename)
|
||||
db.text_factory = str
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""CREATE TABLE keys (
|
||||
id INTEGER PRIMARY KEY,
|
||||
key TEXT UNIQUE ON CONFLICT IGNORE,
|
||||
locked BOOLEAN
|
||||
key TEXT UNIQUE ON CONFLICT REPLACE
|
||||
)""")
|
||||
cursor.execute("""CREATE TABLE factoids (
|
||||
id INTEGER PRIMARY KEY,
|
||||
key_id INTEGER,
|
||||
added_by TEXT,
|
||||
added_at TIMESTAMP,
|
||||
fact TEXT
|
||||
fact TEXT UNIQUE ON CONFLICT REPLACE,
|
||||
locked BOOLEAN
|
||||
)""")
|
||||
cursor.execute("""CREATE TABLE relations (
|
||||
id INTEGER PRIMARY KEY,
|
||||
key_id INTEGER,
|
||||
fact_id INTEGER,
|
||||
usage_count INTEGER
|
||||
)""")
|
||||
cursor.execute("""CREATE TRIGGER remove_factoids
|
||||
BEFORE DELETE ON keys
|
||||
BEGIN
|
||||
DELETE FROM factoids WHERE key_id = old.id;
|
||||
END
|
||||
""")
|
||||
db.commit()
|
||||
return db
|
||||
|
||||
|
@ -127,28 +130,51 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
name=callbacks.formatCommand(command))
|
||||
return super(Factoids, self).getCommandHelp(command, simpleSyntax)
|
||||
|
||||
def learn(self, irc, msg, args, channel, key, factoid):
|
||||
def _getKeyAndFactId(self, channel, key, factoid):
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("SELECT id, locked FROM keys WHERE key LIKE %s", key)
|
||||
if cursor.rowcount == 0:
|
||||
cursor.execute("""INSERT INTO keys VALUES (NULL, %s, 0)""", key)
|
||||
cursor.execute("SELECT id FROM keys WHERE key=?", (key,))
|
||||
keyresults = cursor.fetchall()
|
||||
cursor.execute("SELECT id FROM factoids WHERE fact=?", (factoid,))
|
||||
factresults = cursor.fetchall()
|
||||
return (keyresults, factresults,)
|
||||
|
||||
def learn(self, irc, msg, args, channel, key, factoid):
|
||||
|
||||
# if neither key nor factoid exist, add them.
|
||||
# if key exists but factoid doesn't, add factoid, link it to existing key
|
||||
# if factoid exists but key doesn't, add key, link it to existing factoid
|
||||
# if both key and factoid already exist, and are linked, do nothing, print nice message
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
(keyid, factid) = self._getKeyAndFactId(channel, key, factoid)
|
||||
|
||||
if len(keyid) == 0:
|
||||
cursor.execute("""INSERT INTO keys VALUES (NULL, ?)""", (key,))
|
||||
db.commit()
|
||||
cursor.execute("SELECT id, locked FROM keys WHERE key LIKE %s",key)
|
||||
(id, locked) = map(int, cursor.fetchone())
|
||||
capability = ircdb.makeChannelCapability(channel, 'factoids')
|
||||
if not locked:
|
||||
if len(factid) == 0:
|
||||
if ircdb.users.hasUser(msg.prefix):
|
||||
name = ircdb.users.getUser(msg.prefix).name
|
||||
else:
|
||||
name = msg.nick
|
||||
cursor.execute("""INSERT INTO factoids VALUES
|
||||
(NULL, %s, %s, %s, %s)""",
|
||||
id, name, int(time.time()), factoid)
|
||||
(NULL, ?, ?, ?, ?)""",
|
||||
(name, int(time.time()), factoid, 0))
|
||||
db.commit()
|
||||
(keyid, factid) = self._getKeyAndFactId(channel, key, factoid)
|
||||
|
||||
cursor.execute("""SELECT id, key_id, fact_id from relations
|
||||
WHERE key_id=? AND fact_id=?""",
|
||||
(keyid[0][0], factid[0][0],))
|
||||
existingrelation = cursor.fetchall()
|
||||
if len(existingrelation) == 0:
|
||||
cursor.execute("""INSERT INTO relations VALUES (NULL, ?, ?, ?)""",
|
||||
(keyid[0][0],factid[0][0],0,))
|
||||
db.commit()
|
||||
irc.replySuccess()
|
||||
else:
|
||||
irc.error('That factoid is locked.')
|
||||
irc.error("This key-factoid relationship already exists.")
|
||||
|
||||
learn = wrap(learn, ['factoid'])
|
||||
learn._fake__doc__ = _("""[<channel>] <key> %s <value>
|
||||
|
||||
|
@ -163,18 +189,70 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
def _lookupFactoid(self, channel, key):
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT factoids.fact FROM factoids, keys
|
||||
WHERE keys.key LIKE %s AND factoids.key_id=keys.id
|
||||
cursor.execute("""SELECT factoids.fact, factoids.id, relations.id FROM factoids, keys, relations
|
||||
WHERE keys.key LIKE ? AND relations.key_id=keys.id AND relations.fact_id=factoids.id
|
||||
ORDER BY factoids.id
|
||||
LIMIT 20""", key)
|
||||
return [t[0] for t in cursor.fetchall()]
|
||||
LIMIT 20""", (key,))
|
||||
return cursor.fetchall()
|
||||
|
||||
def _searchFactoid(self, channel, key):
|
||||
"""Try to typo-match input to possible factoids.
|
||||
|
||||
Assume first letter is correct, to reduce processing time.
|
||||
First, try a simple wildcard search.
|
||||
If that fails, use the Damerau-Levenshtein edit-distance metric.
|
||||
"""
|
||||
# if you made a typo in a two-character key, boo on you.
|
||||
if len(key) < 3:
|
||||
return []
|
||||
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT key FROM keys WHERE key LIKE ?""", ('%' + key + '%',))
|
||||
wildcardkeys = cursor.fetchall()
|
||||
if len(wildcardkeys) > 0:
|
||||
return [line[0] for line in wildcardkeys]
|
||||
|
||||
cursor.execute("""SELECT key FROM keys WHERE key LIKE ?""", (key[0] + '%',))
|
||||
flkeys = cursor.fetchall()
|
||||
if len(flkeys) == 0:
|
||||
return []
|
||||
flkeys = [line[0] for line in flkeys]
|
||||
dl_metrics = [dameraulevenshtein(key, sourcekey) for sourcekey in flkeys]
|
||||
dict_metrics = dict(zip(flkeys, dl_metrics))
|
||||
if min(dl_metrics) <= 2:
|
||||
return [key for key,item in dict_metrics.iteritems() if item <= 2]
|
||||
if min(dl_metrics) <= 3:
|
||||
return [key for key,item in dict_metrics.iteritems() if item <= 3]
|
||||
|
||||
return []
|
||||
|
||||
def _updateRank(self, channel, factoids):
|
||||
if self.registryValue('keepRankInfo', channel):
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
for (fact,factid,relationid) in factoids:
|
||||
cursor.execute("""SELECT relations.usage_count
|
||||
FROM relations
|
||||
WHERE relations.id=?""", (relationid,))
|
||||
old_count = cursor.fetchall()[0][0]
|
||||
cursor.execute("UPDATE relations SET usage_count=? WHERE id=?",
|
||||
(old_count + 1, relationid,))
|
||||
db.commit()
|
||||
|
||||
def _replyFactoids(self, irc, msg, key, channel, factoids,
|
||||
number=0, error=True, raw=False):
|
||||
def format_fact(text):
|
||||
if raw:
|
||||
return text
|
||||
else:
|
||||
return ircutils.standardSubstitute(irc, msg, text)
|
||||
|
||||
def _replyFactoids(self, irc, msg, key, factoids,
|
||||
number=0, error=True):
|
||||
if factoids:
|
||||
if number:
|
||||
try:
|
||||
irc.reply(factoids[number-1])
|
||||
irc.reply(format_fact(factoids[number-1][0]))
|
||||
self._updateRank(channel, [factoids[number-1]])
|
||||
except IndexError:
|
||||
irc.error(_('That\'s not a valid number for that key.'))
|
||||
return
|
||||
|
@ -186,34 +264,55 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
return ircutils.standardSubstitute(irc, msg,
|
||||
formatter, env)
|
||||
if len(factoids) == 1:
|
||||
irc.reply(prefixer(factoids[0]))
|
||||
irc.reply(format_fact(prefixer(factoids[0][0])))
|
||||
else:
|
||||
factoidsS = []
|
||||
counter = 1
|
||||
for factoid in factoids:
|
||||
factoidsS.append(format('(#%i) %s', counter, factoid))
|
||||
factoidsS.append(format('(#%i) %s', counter,
|
||||
format_fact(factoid[0])))
|
||||
counter += 1
|
||||
irc.replies(factoidsS, prefixer=prefixer,
|
||||
joiner=', or ', onlyPrefixFirst=True)
|
||||
self._updateRank(channel, factoids)
|
||||
elif error:
|
||||
irc.error(_('No factoid matches that key.'))
|
||||
|
||||
def _replyApproximateFactoids(self, irc, msg, channel, key, error=True):
|
||||
if self.registryValue('replyApproximateSearchKeys'):
|
||||
factoids = self._searchFactoid(channel, key)
|
||||
if factoids:
|
||||
keylist = ["'%s'" % (fact,) for fact in factoids]
|
||||
keylist = ', '.join(keylist)
|
||||
irc.reply("I do not know about '%s', but I do know about these similar topics: %s" % (key, keylist))
|
||||
elif error:
|
||||
irc.error('No factoid matches that key.')
|
||||
|
||||
def invalidCommand(self, irc, msg, tokens):
|
||||
if irc.isChannel(msg.args[0]):
|
||||
channel = msg.args[0]
|
||||
if self.registryValue('replyWhenInvalidCommand', channel):
|
||||
key = ' '.join(tokens)
|
||||
factoids = self._lookupFactoid(channel, key)
|
||||
self._replyFactoids(irc, msg, key, factoids, error=False)
|
||||
if factoids:
|
||||
self._replyFactoids(irc, msg, key, channel, factoids, error=False)
|
||||
else:
|
||||
self._replyApproximateFactoids(irc, msg, channel, key, error=False)
|
||||
|
||||
@internationalizeDocstring
|
||||
def whatis(self, irc, msg, args, channel, words):
|
||||
"""[<channel>] <key> [<number>]
|
||||
def whatis(self, irc, msg, args, channel, optlist, words):
|
||||
"""[<channel>] [--raw] <key> [<number>]
|
||||
|
||||
Looks up the value of <key> in the factoid database. If given a
|
||||
number, will return only that exact factoid. <channel> is only
|
||||
necessary if the message isn't sent in the channel itself.
|
||||
number, will return only that exact factoid. If '--raw' option is
|
||||
given, no variable substitution will take place on the factoid.
|
||||
<channel> is only necessary if the message isn't sent in the channel
|
||||
itself.
|
||||
"""
|
||||
raw = False
|
||||
for (option, arg) in optlist:
|
||||
if option == 'raw':
|
||||
raw = True
|
||||
number = None
|
||||
if len(words) > 1:
|
||||
if words[-1].isdigit():
|
||||
|
@ -222,9 +321,131 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
irc.errorInvalid(_('key id'))
|
||||
key = ' '.join(words)
|
||||
factoids = self._lookupFactoid(channel, key)
|
||||
self._replyFactoids(irc, msg, key, factoids, number)
|
||||
if factoids:
|
||||
self._replyFactoids(irc, msg, key, channel, factoids, number, raw=raw)
|
||||
else:
|
||||
self._replyApproximateFactoids(irc, msg, channel, key)
|
||||
whatis = wrap(whatis, ['channel', many('something')])
|
||||
|
||||
whatis = wrap(whatis, ['channel',
|
||||
getopts({'raw': '',}),
|
||||
many('something')])
|
||||
|
||||
@internationalizeDocstring
|
||||
def alias(self, irc, msg, args, channel, oldkey, newkey, number):
|
||||
"""[<channel>] <oldkey> <newkey> [<number>]
|
||||
|
||||
Adds a new key <newkey> for factoid associated with <oldkey>.
|
||||
<number> is only necessary if there's more than one factoid associated
|
||||
with <oldkey>.
|
||||
|
||||
The same action can be accomplished by using the 'learn' function with
|
||||
a new key but an existing (verbatim) factoid content.
|
||||
"""
|
||||
def _getNewKey(channel, newkey, arelation):
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT id FROM keys WHERE key=?""", (newkey,))
|
||||
newkey_info = cursor.fetchall()
|
||||
if len(newkey_info) == 1:
|
||||
# check if we already have the requested relation
|
||||
cursor.execute("""SELECT id FROM relations WHERE
|
||||
key_id=? and fact_id=?""",
|
||||
(arelation[1], arelation[2]))
|
||||
existentrelation = cursor.fetchall()
|
||||
if len(existentrelation) != 0:
|
||||
newkey_info = False
|
||||
if len(newkey_info) == 0:
|
||||
cursor.execute("""INSERT INTO keys VALUES (NULL, ?)""",
|
||||
(newkey,))
|
||||
db.commit()
|
||||
cursor.execute("""SELECT id FROM keys WHERE key=?""", (newkey,))
|
||||
newkey_info = cursor.fetchall()
|
||||
return newkey_info
|
||||
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT relations.id, relations.key_id, relations.fact_id
|
||||
FROM keys, relations
|
||||
WHERE keys.key=? AND
|
||||
relations.key_id=keys.id""", (oldkey,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
irc.error(_('No factoid matches that key.'))
|
||||
return
|
||||
elif len(results) == 1:
|
||||
newkey_info = _getNewKey(channel, newkey, results[0])
|
||||
if newkey_info is not False:
|
||||
cursor.execute("""INSERT INTO relations VALUES(NULL, ?, ?, ?)""",
|
||||
(newkey_info[0][0], results[0][2], 0,))
|
||||
irc.replySuccess()
|
||||
else:
|
||||
irc.error(_('This key-factoid relationship already exists.'))
|
||||
elif len(results) > 1:
|
||||
try:
|
||||
arelation = results[number-1]
|
||||
except IndexError:
|
||||
irc.error(_("That's not a valid number for that key."))
|
||||
return
|
||||
except TypeError:
|
||||
irc.error(_("This key has more than one factoid associated "
|
||||
"with it, but you have not provided a number."))
|
||||
return
|
||||
newkey_info = _getNewKey(channel, newkey, arelation)
|
||||
if newkey_info is not False:
|
||||
cursor.execute("""INSERT INTO relations VALUES(NULL, ?, ?, ?)""",
|
||||
(newkey_info[0][0], arelation[2], 0,))
|
||||
irc.replySuccess()
|
||||
else:
|
||||
irc.error(_('This key-factoid relationship already exists.'))
|
||||
|
||||
alias = wrap(alias, ['channel', 'something', 'something', optional('int')])
|
||||
|
||||
@internationalizeDocstring
|
||||
def rank(self, irc, msg, args, channel, optlist, number):
|
||||
"""[<channel>] [--plain] [--alpha] [<number>]
|
||||
|
||||
Returns a list of top-ranked factoid keys, sorted by usage count
|
||||
(rank). If <number> is not provided, the default number of factoid keys
|
||||
returned is set by the rankListLength registry value.
|
||||
|
||||
If --plain option is given, rank numbers and usage counts are not
|
||||
included in output.
|
||||
|
||||
If --alpha option is given in addition to --plain, keys are sorted
|
||||
alphabetically, instead of by rank.
|
||||
|
||||
<channel> is only necessary if the message isn't sent in the channel
|
||||
itself.
|
||||
"""
|
||||
if not number:
|
||||
number = self.registryValue('rankListLength', channel)
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT keys.key, relations.usage_count
|
||||
FROM keys, relations
|
||||
WHERE relations.key_id=keys.id
|
||||
ORDER BY relations.usage_count DESC
|
||||
LIMIT ?""", (number,))
|
||||
factkeys = cursor.fetchall()
|
||||
plain=False
|
||||
alpha=False
|
||||
for (option, arg) in optlist:
|
||||
if option == 'plain':
|
||||
plain = True
|
||||
elif option =='alpha':
|
||||
alpha = True
|
||||
if plain:
|
||||
s = [ "%s" % (key[0],) for i, key in enumerate(factkeys) ]
|
||||
if alpha:
|
||||
s.sort()
|
||||
else:
|
||||
s = [ "#%d %s (%d)" % (i+1, key[0], key[1]) for i, key in enumerate(factkeys) ]
|
||||
irc.reply(", ".join(s))
|
||||
rank = wrap(rank, ['channel',
|
||||
getopts({'plain': '', 'alpha': '',}),
|
||||
optional('int')])
|
||||
|
||||
@internationalizeDocstring
|
||||
def lock(self, irc, msg, args, channel, key):
|
||||
"""[<channel>] <key>
|
||||
|
@ -235,7 +456,10 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
"""
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("UPDATE keys SET locked=1 WHERE key LIKE %s", key)
|
||||
cursor.execute("UPDATE factoids, keys, relations "
|
||||
"SET factoids.locked=1 WHERE key LIKE ? AND "
|
||||
"factoids.id=relations.fact_id AND "
|
||||
"keys.id=relations.key_id", (key,))
|
||||
db.commit()
|
||||
irc.replySuccess()
|
||||
lock = wrap(lock, ['channel', 'text'])
|
||||
|
@ -250,19 +474,48 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
"""
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("UPDATE keys SET locked=0 WHERE key LIKE %s", key)
|
||||
cursor.execute("""UPDATE factoids, keys, relations
|
||||
SET factoids.locked=1 WHERE key LIKE ? AND
|
||||
factoids.id=relations.fact_id AND
|
||||
keys.id=relations.key_id""", (key,))
|
||||
db.commit()
|
||||
irc.replySuccess()
|
||||
unlock = wrap(unlock, ['channel', 'text'])
|
||||
|
||||
def _deleteRelation(self, channel, relationlist):
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
for (keyid, factid, relationid) in relationlist:
|
||||
cursor.execute("""DELETE FROM relations where relations.id=?""",
|
||||
(relationid,))
|
||||
db.commit()
|
||||
|
||||
cursor.execute("""SELECT id FROM relations
|
||||
WHERE relations.key_id=?""", (keyid,))
|
||||
remaining_key_relations = cursor.fetchall()
|
||||
if len(remaining_key_relations) == 0:
|
||||
cursor.execute("""DELETE FROM keys where id=?""", (keyid,))
|
||||
|
||||
cursor.execute("""SELECT id FROM relations
|
||||
WHERE relations.fact_id=?""", (factid,))
|
||||
remaining_fact_relations = cursor.fetchall()
|
||||
if len(remaining_fact_relations) == 0:
|
||||
cursor.execute("""DELETE FROM factoids where id=?""", (factid,))
|
||||
db.commit()
|
||||
|
||||
@internationalizeDocstring
|
||||
def forget(self, irc, msg, args, channel, words):
|
||||
"""[<channel>] <key> [<number>|*]
|
||||
|
||||
Removes the factoid <key> from the factoids database. If there are
|
||||
more than one factoid with such a key, a number is necessary to
|
||||
determine which one should be removed. A * can be used to remove all
|
||||
factoids associated with a key. <channel> is only necessary if
|
||||
Removes a key-fact relationship for key <key> from the factoids
|
||||
database. If there is more than one such relationship for this key,
|
||||
a number is necessary to determine which one should be removed.
|
||||
A * can be used to remove all relationships for <key>.
|
||||
|
||||
If as a result, the key (factoid) remains without any relationships to
|
||||
a factoid (key), it shall be removed from the database.
|
||||
|
||||
<channel> is only necessary if
|
||||
the message isn't sent in the channel itself.
|
||||
"""
|
||||
number = None
|
||||
|
@ -277,34 +530,32 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
key = ' '.join(words)
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT keys.id, factoids.id
|
||||
FROM keys, factoids
|
||||
WHERE key LIKE %s AND
|
||||
factoids.key_id=keys.id""", key)
|
||||
if cursor.rowcount == 0:
|
||||
cursor.execute("""SELECT keys.id, factoids.id, relations.id
|
||||
FROM keys, factoids, relations
|
||||
WHERE key LIKE ? AND
|
||||
relations.key_id=keys.id AND
|
||||
relations.fact_id=factoids.id""", (key,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
irc.error(_('There is no such factoid.'))
|
||||
elif cursor.rowcount == 1 or number is True:
|
||||
(id, foo) = cursor.fetchone()
|
||||
cursor.execute("""DELETE FROM factoids WHERE key_id=%s""", id)
|
||||
cursor.execute("""DELETE FROM keys WHERE key LIKE %s""", key)
|
||||
db.commit()
|
||||
elif len(results) == 1 or number is True:
|
||||
self._deleteRelation(channel, results)
|
||||
irc.replySuccess()
|
||||
else:
|
||||
if number is not None:
|
||||
results = cursor.fetchall()
|
||||
#results = cursor.fetchall()
|
||||
try:
|
||||
(foo, id) = results[number-1]
|
||||
arelation = results[number-1]
|
||||
except IndexError:
|
||||
irc.error(_('Invalid factoid number.'))
|
||||
return
|
||||
cursor.execute("DELETE FROM factoids WHERE id=%s", id)
|
||||
db.commit()
|
||||
self._deleteRelation(channel, [arelation,])
|
||||
irc.replySuccess()
|
||||
else:
|
||||
irc.error(_('%s factoids have that key. '
|
||||
'Please specify which one to remove, '
|
||||
'or use * to designate all of them.') %
|
||||
cursor.rowcount)
|
||||
len(results))
|
||||
forget = wrap(forget, ['channel', many('something')])
|
||||
|
||||
@internationalizeDocstring
|
||||
|
@ -316,14 +567,18 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
"""
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT fact, key_id FROM factoids
|
||||
cursor.execute("""SELECT id, key_id, fact_id FROM relations
|
||||
ORDER BY random()
|
||||
LIMIT 3""")
|
||||
if cursor.rowcount != 0:
|
||||
results = cursor.fetchall()
|
||||
if len(results) != 0:
|
||||
L = []
|
||||
for (factoid, id) in cursor.fetchall():
|
||||
cursor.execute("""SELECT key FROM keys WHERE id=%s""", id)
|
||||
(key,) = cursor.fetchone()
|
||||
for (relationid, keyid, factid) in results:
|
||||
cursor.execute("""SELECT keys.key, factoids.fact
|
||||
FROM keys, factoids
|
||||
WHERE factoids.id=? AND
|
||||
keys.id=?""", (factid,keyid,))
|
||||
(key,factoid) = cursor.fetchall()[0]
|
||||
L.append('"%s": %s' % (ircutils.bold(key), factoid))
|
||||
irc.reply('; '.join(L))
|
||||
else:
|
||||
|
@ -340,23 +595,28 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
"""
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("SELECT id, locked FROM keys WHERE key LIKE %s", key)
|
||||
if cursor.rowcount == 0:
|
||||
cursor.execute("SELECT id FROM keys WHERE key LIKE ?", (key,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
irc.error(_('No factoid matches that key.'))
|
||||
return
|
||||
(id, locked) = map(int, cursor.fetchone())
|
||||
cursor.execute("""SELECT added_by, added_at FROM factoids
|
||||
WHERE key_id=%s
|
||||
ORDER BY id""", id)
|
||||
id = results[0][0]
|
||||
cursor.execute("""SELECT factoids.added_by, factoids.added_at, factoids.locked, relations.usage_count
|
||||
FROM factoids, relations
|
||||
WHERE relations.key_id=? AND
|
||||
relations.fact_id=factoids.id
|
||||
ORDER BY relations.id""", (id,))
|
||||
factoids = cursor.fetchall()
|
||||
L = []
|
||||
counter = 0
|
||||
for (added_by, added_at) in factoids:
|
||||
for (added_by, added_at, locked, usage_count) in factoids:
|
||||
counter += 1
|
||||
added_at = time.strftime(conf.supybot.reply.format.time(),
|
||||
time.localtime(int(added_at)))
|
||||
L.append(format(_('#%i was added by %s at %s'),
|
||||
counter, added_by, added_at))
|
||||
L.append(format(_('#%i was added by %s at %s, and has been '
|
||||
'recalled %n'),
|
||||
counter, added_by, added_at,
|
||||
(usage_count, _('time'))))
|
||||
factoids = '; '.join(L)
|
||||
s = format('Key %q is %s and has %n associated with it: %s',
|
||||
key, locked and 'locked' or 'not locked',
|
||||
|
@ -374,17 +634,19 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT factoids.id, factoids.fact
|
||||
FROM keys, factoids
|
||||
WHERE keys.key LIKE %s AND
|
||||
keys.id=factoids.key_id""", key)
|
||||
if cursor.rowcount == 0:
|
||||
FROM keys, factoids, relations
|
||||
WHERE keys.key LIKE ? AND
|
||||
keys.id=relations.key_id AND
|
||||
factoids.id=relations.fact_id""", (key,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
irc.error(format(_('I couldn\'t find any key %q'), key))
|
||||
return
|
||||
elif cursor.rowcount < number:
|
||||
irc.errorInvalid(_('key id'))
|
||||
(id, fact) = cursor.fetchall()[number-1]
|
||||
elif len(results) < number:
|
||||
irc.errorInvalid('key id')
|
||||
(id, fact) = results[number-1]
|
||||
newfact = replacer(fact)
|
||||
cursor.execute("UPDATE factoids SET fact=%s WHERE id=%s", newfact, id)
|
||||
cursor.execute("UPDATE factoids SET fact=? WHERE id=?", (newfact, id))
|
||||
db.commit()
|
||||
irc.replySuccess()
|
||||
change = wrap(change, ['channel', 'something',
|
||||
|
@ -412,7 +674,8 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
target = 'factoids.fact'
|
||||
if 'factoids' not in tables:
|
||||
tables.append('factoids')
|
||||
criteria.append('factoids.key_id=keys.id')
|
||||
tables.append('relations')
|
||||
criteria.append('factoids.id=relations.fact_id AND keys.id=relations.key_id')
|
||||
elif option == 'regexp':
|
||||
criteria.append('%s(TARGET)' % predicateName)
|
||||
def p(s, r=arg):
|
||||
|
@ -420,11 +683,12 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
db.create_function(predicateName, 1, p)
|
||||
predicateName += 'p'
|
||||
for glob in globs:
|
||||
criteria.append('TARGET LIKE %s')
|
||||
criteria.append('TARGET LIKE ?')
|
||||
formats.append(glob.translate(self._sqlTrans))
|
||||
cursor = db.cursor()
|
||||
sql = """SELECT keys.key FROM %s WHERE %s""" % \
|
||||
(', '.join(tables), ' AND '.join(criteria))
|
||||
sql = sql + " ORDER BY keys.key"
|
||||
sql = sql.replace('TARGET', target)
|
||||
cursor.execute(sql, formats)
|
||||
if cursor.rowcount == 0:
|
||||
|
@ -435,8 +699,17 @@ class Factoids(callbacks.Plugin, plugins.ChannelDBHandler):
|
|||
elif cursor.rowcount > 100:
|
||||
irc.reply(_('More than 100 keys matched that query; '
|
||||
'please narrow your query.'))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
irc.reply(_('No keys matched that query.'))
|
||||
elif len(results) == 1 and \
|
||||
self.registryValue('showFactoidIfOnlyOneMatch', channel):
|
||||
self.whatis(irc, msg, [channel, results[0][0]])
|
||||
elif len(results) > 100:
|
||||
irc.reply(_('More than 100 keys matched that query; '
|
||||
'please narrow your query.'))
|
||||
else:
|
||||
keys = [repr(t[0]) for t in cursor.fetchall()]
|
||||
keys = [repr(t[0]) for t in results]
|
||||
s = format('%L', keys)
|
||||
irc.reply(s)
|
||||
search = wrap(search, ['channel',
|
||||
|
|
|
@ -31,12 +31,11 @@
|
|||
from supybot.test import *
|
||||
|
||||
try:
|
||||
import sqlite
|
||||
import sqlite3
|
||||
except ImportError:
|
||||
sqlite = None
|
||||
from pysqlite2 import dbapi2 as sqlite3 # for python2.4
|
||||
|
||||
if sqlite:
|
||||
class FactoidsTestCase(ChannelPluginTestCase):
|
||||
class FactoidsTestCase(ChannelPluginTestCase):
|
||||
plugins = ('Factoids',)
|
||||
def testRandomfactoid(self):
|
||||
self.assertError('random')
|
||||
|
@ -99,8 +98,8 @@ if sqlite:
|
|||
self.assertRegexp('factoids search --regexp m/^j/ *ss*',
|
||||
'jamessan')
|
||||
self.assertRegexp('factoids search --regexp /^j/',
|
||||
'jemfinch.*jamessan')
|
||||
self.assertRegexp('factoids search j*', 'jemfinch.*jamessan')
|
||||
'jamessan.*jemfinch')
|
||||
self.assertRegexp('factoids search j*', 'jamessan.*jemfinch')
|
||||
self.assertRegexp('factoids search *ke*',
|
||||
'inkedmn.*strike|strike.*inkedmn')
|
||||
self.assertRegexp('factoids search ke',
|
||||
|
@ -126,6 +125,12 @@ if sqlite:
|
|||
self.assertNotError('learn foo as bar')
|
||||
self.assertNotRegexp('info foo', '2 factoids')
|
||||
|
||||
def testInfoUsageCount(self):
|
||||
self.assertNotError('learn moo as cow')
|
||||
self.assertRegexp('info moo', 'recalled 0 times')
|
||||
self.assertNotError('whatis moo')
|
||||
self.assertRegexp('info moo', 'recalled 1 time')
|
||||
|
||||
def testLearnSeparator(self):
|
||||
self.assertError('learn foo is bar')
|
||||
self.assertNotError('learn foo as bar')
|
||||
|
@ -152,15 +157,52 @@ if sqlite:
|
|||
showFactoidIfOnlyOneMatch.setValue(orig)
|
||||
|
||||
def testInvalidCommand(self):
|
||||
orig = conf.supybot.plugins.Factoids.replyWhenInvalidCommand()
|
||||
try:
|
||||
conf.supybot.plugins.Factoids.\
|
||||
replyWhenInvalidCommand.setValue(True)
|
||||
self.assertNotError('learn foo as bar')
|
||||
self.assertRegexp('foo', 'bar')
|
||||
finally:
|
||||
conf.supybot.plugins.Factoids.\
|
||||
replyWhenInvalidCommand.setValue(orig)
|
||||
self.assertNotError('learn mooz as cowz')
|
||||
self.assertRegexp('moo', 'mooz')
|
||||
self.assertRegexp('mzo', 'mooz')
|
||||
self.assertRegexp('moz', 'mooz')
|
||||
self.assertNotError('learn moped as pretty fast')
|
||||
self.assertRegexp('moe', 'mooz.*moped')
|
||||
self.assertError('nosuchthing')
|
||||
|
||||
def testWhatis(self):
|
||||
self.assertNotError('learn foo as bar')
|
||||
self.assertRegexp('whatis foo', 'bar')
|
||||
self.assertRegexp('whatis foob', 'foo')
|
||||
self.assertNotError('learn foob as barb')
|
||||
self.assertRegexp('whatis foom', 'foo.*foob')
|
||||
|
||||
def testStandardSubstitute(self):
|
||||
self.assertNotError('learn foo as this is $channel, and hour is $hour')
|
||||
self.assertRegexp('whatis foo', 'this is #test, and hour is \d{1,2}')
|
||||
self.assertRegexp('whatis --raw foo', 'this is \$channel, and hour is \$hour')
|
||||
self.assertNotError('learn bar as this is $$channel escaped')
|
||||
self.assertRegexp('whatis bar', 'this is \$channel')
|
||||
self.assertNotError('learn bar as this is $minute')
|
||||
self.assertRegexp('whatis bar', '\$channel.*\d{1,2}')
|
||||
|
||||
def testAlias(self):
|
||||
self.assertNotError('learn foo as bar')
|
||||
self.assertNotError('alias foo zoog')
|
||||
self.assertRegexp('whatis zoog', 'bar')
|
||||
self.assertNotError('learn foo as snorp')
|
||||
self.assertError('alias foo gnoop')
|
||||
self.assertNotError('alias foo gnoop 2')
|
||||
self.assertRegexp('whatis gnoop', 'snorp')
|
||||
|
||||
def testRank(self):
|
||||
self.assertNotError('learn foo as bar')
|
||||
self.assertNotError('learn moo as cow')
|
||||
self.assertRegexp('factoids rank', '#1 foo \(0\), #2 moo \(0\)')
|
||||
self.assertRegexp('whatis moo', '.*cow.*')
|
||||
self.assertRegexp('factoids rank', '#1 moo \(1\), #2 foo \(0\)')
|
||||
self.assertRegexp('factoids rank 1', '#1 moo \(1\)')
|
||||
self.assertNotRegexp('factoids rank 1', 'foo')
|
||||
self.assertRegexp('factoids rank --plain', 'moo, foo')
|
||||
self.assertRegexp('factoids rank --plain --alpha', 'foo, moo')
|
||||
self.assertResponse('factoids rank --plain 1', 'moo')
|
||||
|
||||
def testQuoteHandling(self):
|
||||
self.assertNotError('learn foo as "\\"bar\\""')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot-fr\n"
|
||||
"POT-Creation-Date: 2010-10-17 11:48+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
|
@ -37,7 +37,7 @@ msgid ""
|
|||
" in a word before it will be shrunken by the shrink command/filter."
|
||||
msgstr "Détermine le nombre minimum de lettre dans un mot pour qu'il soit coupé par la commande/le filtre shrink."
|
||||
|
||||
#: plugin.py:51
|
||||
#: plugin.py:50
|
||||
msgid ""
|
||||
"This plugin offers several commands which transform text in some way.\n"
|
||||
" It also provides the capability of using such commands to 'filter' the\n"
|
||||
|
@ -46,7 +46,7 @@ msgid ""
|
|||
" Not very useful, but definitely quite fun :)"
|
||||
msgstr "Ce plugin offre quelques commandes qui peuvent être utilisées pour transformer du texte de différentes façons. Il fourni également la possiblité d'utiliser ces commandes pour 'filtrer' la sortie du bot ; par exemple, vous pouvez faire en sorte que tout ce que le bot dit le soit en l33tsp34k, en Morse, ou n'importe lequel des autres filtres. Pas très utile, mais plutôt fun :)"
|
||||
|
||||
#: plugin.py:85
|
||||
#: plugin.py:84
|
||||
msgid ""
|
||||
"[<channel>] [<command>]\n"
|
||||
"\n"
|
||||
|
@ -59,11 +59,11 @@ msgstr ""
|
|||
"\n"
|
||||
"Définit le filtre de sortie de ce plugin pour être <commande>. Si aucune commande n'est définie, supprime le filtre de sortie. <canal> n'est nécessaire que si la commande n'est pas envoyée sur le canal lui-même."
|
||||
|
||||
#: plugin.py:98
|
||||
#: plugin.py:97
|
||||
msgid "That's not a valid filter command."
|
||||
msgstr "Ce n'est pas une commande de filtre valide"
|
||||
|
||||
#: plugin.py:108
|
||||
#: plugin.py:107
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -76,7 +76,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retire toutes les voyelles du <texte> (si vous êtes curieux de pourquoi elle s'appelle 'hebrew', c'est parce que je (jemfinch) pense que que en Hébreux, il manque souvent les voyelles)."
|
||||
|
||||
#: plugin.py:120
|
||||
#: plugin.py:119
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -87,7 +87,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Supprime tous les espaces du <texte>."
|
||||
|
||||
#: plugin.py:130
|
||||
#: plugin.py:129
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -98,7 +98,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Renvoie le texte, avec toutes les lettres consécutives dupliquées supprimées."
|
||||
|
||||
#: plugin.py:143
|
||||
#: plugin.py:142
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -109,7 +109,19 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne la représentation binaire du <texte>."
|
||||
|
||||
#: plugin.py:169
|
||||
#: plugin.py:168
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
" Returns the character representation of binary <text>.\n"
|
||||
" Assumes ASCII, 8 digits per character.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<texte>\n"
|
||||
"\n"
|
||||
"Retourne la représentation binaire du <texte>. Considère qu'il s'agit d'ASCII, 8 bits par caractère."
|
||||
|
||||
#: plugin.py:179
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -121,7 +133,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne une chaîne héxadécimale à partir de la chaîne donnée ; une chaîne héxadécimale est une chaîne composée de la valeur héxadécimale de chaque caractère de la chaîne."
|
||||
|
||||
#: plugin.py:179
|
||||
#: plugin.py:189
|
||||
msgid ""
|
||||
"<hexstring>\n"
|
||||
"\n"
|
||||
|
@ -133,11 +145,11 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne la chaîne correspondant à la <chaîne hexadécimale>. Bien sûr, <chaîne hexadécimale> ne doit contenir que des caractères hexadécimaux."
|
||||
|
||||
#: plugin.py:187
|
||||
#: plugin.py:197
|
||||
msgid "Invalid input."
|
||||
msgstr "Entrée invalide."
|
||||
|
||||
#: plugin.py:192
|
||||
#: plugin.py:202
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -150,7 +162,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Déplace chaque caractère du <texte> de 13 places vers la droite de l'alphabet. Rot13 est courremment utilisé pour les textes qui doivent être cachés des yeux indiscrets, mais être facilement reversible."
|
||||
|
||||
#: plugin.py:203
|
||||
#: plugin.py:213
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -161,7 +173,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne la version zézéyée du texte."
|
||||
|
||||
#: plugin.py:234
|
||||
#: plugin.py:244
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -172,7 +184,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne la version l33t du <texte>."
|
||||
|
||||
#: plugin.py:254
|
||||
#: plugin.py:264
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -183,7 +195,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Répond avec une traduction k-rad du <texte>."
|
||||
|
||||
#: plugin.py:270
|
||||
#: plugin.py:280
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -195,7 +207,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Répond avec une chaîne où chaque mot est mélangé ; c'est à dire que chaque lettre interne (=toute lettre qui n'est pas la première ni la dernière) est mélangée avec les autres."
|
||||
|
||||
#: plugin.py:335
|
||||
#: plugin.py:345
|
||||
msgid ""
|
||||
"<Morse code text>\n"
|
||||
"\n"
|
||||
|
@ -206,7 +218,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Fait l'inverse de la commande morse."
|
||||
|
||||
#: plugin.py:352
|
||||
#: plugin.py:362
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -217,7 +229,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Donne le code Morse équivalent à la chaîne donnée."
|
||||
|
||||
#: plugin.py:364
|
||||
#: plugin.py:374
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -228,7 +240,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Inverse le <texte>."
|
||||
|
||||
#: plugin.py:381
|
||||
#: plugin.py:391
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -239,7 +251,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le <texte> avec chaque caractère coloré de façon aléatoire."
|
||||
|
||||
#: plugin.py:391
|
||||
#: plugin.py:401
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -250,7 +262,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le texte colorisé comme un arc-en-ciel."
|
||||
|
||||
#: plugin.py:402
|
||||
#: plugin.py:412
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -261,7 +273,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le texte en retirant tous les codes de couleur"
|
||||
|
||||
#: plugin.py:411
|
||||
#: plugin.py:421
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -272,7 +284,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le <texte> comme si un AOLuser l'avait dit."
|
||||
|
||||
#: plugin.py:438
|
||||
#: plugin.py:448
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -283,279 +295,279 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le <texte> comme si JeffK l'avait dit lui-même."
|
||||
|
||||
#: plugin.py:534
|
||||
#: plugin.py:544
|
||||
msgid "ay"
|
||||
msgstr "ah"
|
||||
|
||||
#: plugin.py:534
|
||||
#: plugin.py:544
|
||||
msgid "bee"
|
||||
msgstr "bé"
|
||||
|
||||
#: plugin.py:534
|
||||
#: plugin.py:544
|
||||
msgid "dee"
|
||||
msgstr "dé"
|
||||
|
||||
#: plugin.py:534
|
||||
#: plugin.py:544
|
||||
msgid "see"
|
||||
msgstr "cé"
|
||||
|
||||
#: plugin.py:535
|
||||
#: plugin.py:545
|
||||
msgid "aych"
|
||||
msgstr "ache"
|
||||
|
||||
#: plugin.py:535
|
||||
#: plugin.py:545
|
||||
msgid "ee"
|
||||
msgstr "euh"
|
||||
|
||||
#: plugin.py:535
|
||||
#: plugin.py:545
|
||||
msgid "eff"
|
||||
msgstr "èf"
|
||||
|
||||
#: plugin.py:535
|
||||
#: plugin.py:545
|
||||
msgid "gee"
|
||||
msgstr "gé"
|
||||
|
||||
#: plugin.py:536
|
||||
#: plugin.py:546
|
||||
msgid "ell"
|
||||
msgstr "èl"
|
||||
|
||||
#: plugin.py:536
|
||||
#: plugin.py:546
|
||||
msgid "eye"
|
||||
msgstr "ih"
|
||||
|
||||
#: plugin.py:536
|
||||
#: plugin.py:546
|
||||
msgid "jay"
|
||||
msgstr "ji"
|
||||
|
||||
#: plugin.py:536
|
||||
#: plugin.py:546
|
||||
msgid "kay"
|
||||
msgstr "ka"
|
||||
|
||||
#: plugin.py:537
|
||||
#: plugin.py:547
|
||||
msgid "cue"
|
||||
msgstr "cu"
|
||||
|
||||
#: plugin.py:537
|
||||
#: plugin.py:547
|
||||
msgid "em"
|
||||
msgstr "èm"
|
||||
|
||||
#: plugin.py:537
|
||||
#: plugin.py:547
|
||||
msgid "en"
|
||||
msgstr "èn"
|
||||
|
||||
#: plugin.py:537
|
||||
#: plugin.py:547
|
||||
msgid "oh"
|
||||
msgstr "oh"
|
||||
|
||||
#: plugin.py:537
|
||||
#: plugin.py:547
|
||||
msgid "pee"
|
||||
msgstr "pé"
|
||||
|
||||
#: plugin.py:538
|
||||
#: plugin.py:548
|
||||
msgid "arr"
|
||||
msgstr "ère"
|
||||
|
||||
#: plugin.py:538
|
||||
#: plugin.py:548
|
||||
msgid "ess"
|
||||
msgstr "èce"
|
||||
|
||||
#: plugin.py:538
|
||||
#: plugin.py:548
|
||||
msgid "tee"
|
||||
msgstr "té"
|
||||
|
||||
#: plugin.py:538
|
||||
#: plugin.py:548
|
||||
msgid "you"
|
||||
msgstr "uh"
|
||||
|
||||
#: plugin.py:539
|
||||
#: plugin.py:549
|
||||
msgid "double-you"
|
||||
msgstr "double-vé"
|
||||
|
||||
#: plugin.py:539
|
||||
#: plugin.py:549
|
||||
msgid "ecks"
|
||||
msgstr "icks"
|
||||
|
||||
#: plugin.py:539
|
||||
#: plugin.py:549
|
||||
msgid "vee"
|
||||
msgstr "vé"
|
||||
|
||||
#: plugin.py:539
|
||||
#: plugin.py:549
|
||||
msgid "why"
|
||||
msgstr "i-grec"
|
||||
|
||||
#: plugin.py:540
|
||||
#: plugin.py:550
|
||||
msgid "zee"
|
||||
msgstr "zèd"
|
||||
|
||||
#: plugin.py:545
|
||||
#: plugin.py:555
|
||||
msgid "exclamation point"
|
||||
msgstr "point d'exclamation"
|
||||
|
||||
#: plugin.py:546
|
||||
#: plugin.py:556
|
||||
msgid "quote"
|
||||
msgstr "guillemet double"
|
||||
|
||||
#: plugin.py:547
|
||||
#: plugin.py:557
|
||||
msgid "pound"
|
||||
msgstr "livre"
|
||||
|
||||
#: plugin.py:548
|
||||
#: plugin.py:558
|
||||
msgid "dollar sign"
|
||||
msgstr "signe du dollar"
|
||||
|
||||
#: plugin.py:549
|
||||
#: plugin.py:559
|
||||
msgid "percent"
|
||||
msgstr "pourcent"
|
||||
|
||||
#: plugin.py:550
|
||||
#: plugin.py:560
|
||||
msgid "ampersand"
|
||||
msgstr "espèrluette"
|
||||
|
||||
#: plugin.py:551
|
||||
#: plugin.py:561
|
||||
msgid "single quote"
|
||||
msgstr "guillemet"
|
||||
|
||||
#: plugin.py:552
|
||||
#: plugin.py:562
|
||||
msgid "left paren"
|
||||
msgstr "parenthèse ouvrante"
|
||||
|
||||
#: plugin.py:553
|
||||
#: plugin.py:563
|
||||
msgid "right paren"
|
||||
msgstr "parenthèse fermante"
|
||||
|
||||
#: plugin.py:554
|
||||
#: plugin.py:564
|
||||
msgid "asterisk"
|
||||
msgstr "asterisque"
|
||||
|
||||
#: plugin.py:555
|
||||
#: plugin.py:565
|
||||
msgid "plus"
|
||||
msgstr "plus"
|
||||
|
||||
#: plugin.py:556
|
||||
#: plugin.py:566
|
||||
msgid "comma"
|
||||
msgstr "virgule"
|
||||
|
||||
#: plugin.py:557
|
||||
#: plugin.py:567
|
||||
msgid "minus"
|
||||
msgstr "moins"
|
||||
|
||||
#: plugin.py:558
|
||||
#: plugin.py:568
|
||||
msgid "period"
|
||||
msgstr "point"
|
||||
|
||||
#: plugin.py:559
|
||||
#: plugin.py:569
|
||||
msgid "slash"
|
||||
msgstr "slash"
|
||||
|
||||
#: plugin.py:560
|
||||
#: plugin.py:570
|
||||
msgid "colon"
|
||||
msgstr "double-point"
|
||||
|
||||
#: plugin.py:561
|
||||
#: plugin.py:571
|
||||
msgid "semicolon"
|
||||
msgstr "point-virgule"
|
||||
|
||||
#: plugin.py:562
|
||||
#: plugin.py:572
|
||||
msgid "less than"
|
||||
msgstr "inférieur"
|
||||
|
||||
#: plugin.py:563
|
||||
#: plugin.py:573
|
||||
msgid "equals"
|
||||
msgstr "moins que"
|
||||
|
||||
#: plugin.py:564
|
||||
#: plugin.py:574
|
||||
msgid "greater than"
|
||||
msgstr "supérieur"
|
||||
|
||||
#: plugin.py:565
|
||||
#: plugin.py:575
|
||||
msgid "question mark"
|
||||
msgstr "point d'exclamation"
|
||||
|
||||
#: plugin.py:566
|
||||
#: plugin.py:576
|
||||
msgid "at"
|
||||
msgstr "arobase"
|
||||
|
||||
#: plugin.py:567
|
||||
#: plugin.py:577
|
||||
msgid "left bracket"
|
||||
msgstr "crochet ouvrant"
|
||||
|
||||
#: plugin.py:568
|
||||
#: plugin.py:578
|
||||
msgid "backslash"
|
||||
msgstr "anti-slash"
|
||||
|
||||
#: plugin.py:569
|
||||
#: plugin.py:579
|
||||
msgid "right bracket"
|
||||
msgstr "crochet fermant"
|
||||
|
||||
#: plugin.py:570
|
||||
#: plugin.py:580
|
||||
msgid "caret"
|
||||
msgstr "accent circonflexe"
|
||||
|
||||
#: plugin.py:571
|
||||
#: plugin.py:581
|
||||
msgid "underscore"
|
||||
msgstr "underscore"
|
||||
|
||||
#: plugin.py:572
|
||||
#: plugin.py:582
|
||||
msgid "backtick"
|
||||
msgstr "accent grave"
|
||||
|
||||
#: plugin.py:573
|
||||
#: plugin.py:583
|
||||
msgid "left brace"
|
||||
msgstr "crochet ouvrant"
|
||||
|
||||
#: plugin.py:574
|
||||
#: plugin.py:584
|
||||
msgid "pipe"
|
||||
msgstr "pipe"
|
||||
|
||||
#: plugin.py:575
|
||||
#: plugin.py:585
|
||||
msgid "right brace"
|
||||
msgstr "crochet fermant"
|
||||
|
||||
#: plugin.py:576
|
||||
#: plugin.py:586
|
||||
msgid "tilde"
|
||||
msgstr "tilde"
|
||||
|
||||
#: plugin.py:579
|
||||
#: plugin.py:589
|
||||
msgid "one"
|
||||
msgstr "un"
|
||||
|
||||
#: plugin.py:579
|
||||
#: plugin.py:589
|
||||
msgid "three"
|
||||
msgstr "trois"
|
||||
|
||||
#: plugin.py:579
|
||||
#: plugin.py:589
|
||||
msgid "two"
|
||||
msgstr "deux"
|
||||
|
||||
#: plugin.py:579
|
||||
#: plugin.py:589
|
||||
msgid "zero"
|
||||
msgstr "zéro"
|
||||
|
||||
#: plugin.py:580
|
||||
#: plugin.py:590
|
||||
msgid "five"
|
||||
msgstr "cinq"
|
||||
|
||||
#: plugin.py:580
|
||||
#: plugin.py:590
|
||||
msgid "four"
|
||||
msgstr "quatre"
|
||||
|
||||
#: plugin.py:580
|
||||
#: plugin.py:590
|
||||
msgid "seven"
|
||||
msgstr "sept"
|
||||
|
||||
#: plugin.py:580
|
||||
#: plugin.py:590
|
||||
msgid "six"
|
||||
msgstr "six"
|
||||
|
||||
#: plugin.py:581
|
||||
#: plugin.py:591
|
||||
msgid "eight"
|
||||
msgstr "huit"
|
||||
|
||||
#: plugin.py:581
|
||||
#: plugin.py:591
|
||||
msgid "nine"
|
||||
msgstr "neuf"
|
||||
|
||||
#: plugin.py:585
|
||||
#: plugin.py:595
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -566,7 +578,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le <texte>, épellé phonétiquement"
|
||||
|
||||
#: plugin.py:615
|
||||
#: plugin.py:625
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -577,7 +589,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le <texte> comme si GNU/RMS l'avait dite."
|
||||
|
||||
#: plugin.py:624
|
||||
#: plugin.py:634
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -590,7 +602,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le texte avec chaque mot plus long que supybot.plugins.Filter.shrink.minimum découpé (par exemple, \"internationalization\" devient i18n)"
|
||||
|
||||
#: plugin.py:643
|
||||
#: plugin.py:653
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -601,7 +613,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le <texte> avec les I transormés en r et les r transformés en I."
|
||||
|
||||
#: plugin.py:692
|
||||
#: plugin.py:702
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 11:48+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -39,7 +39,7 @@ msgid ""
|
|||
" in a word before it will be shrunken by the shrink command/filter."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:51
|
||||
#: plugin.py:50
|
||||
#, docstring
|
||||
msgid ""
|
||||
"This plugin offers several commands which transform text in some way.\n"
|
||||
|
@ -49,7 +49,7 @@ msgid ""
|
|||
" Not very useful, but definitely quite fun :)"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:85
|
||||
#: plugin.py:84
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] [<command>]\n"
|
||||
|
@ -60,11 +60,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:98
|
||||
#: plugin.py:97
|
||||
msgid "That's not a valid filter command."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:108
|
||||
#: plugin.py:107
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -75,7 +75,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:120
|
||||
#: plugin.py:119
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -84,7 +84,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:130
|
||||
#: plugin.py:129
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -93,7 +93,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:143
|
||||
#: plugin.py:142
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -102,7 +102,17 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:169
|
||||
#: plugin.py:168
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
" Returns the character representation of binary <text>.\n"
|
||||
" Assumes ASCII, 8 digits per character.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:179
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -112,7 +122,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:179
|
||||
#: plugin.py:189
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<hexstring>\n"
|
||||
|
@ -122,11 +132,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:187
|
||||
#: plugin.py:197
|
||||
msgid "Invalid input."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:192
|
||||
#: plugin.py:202
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -137,7 +147,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:203
|
||||
#: plugin.py:213
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -146,7 +156,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:234
|
||||
#: plugin.py:244
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -155,7 +165,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:254
|
||||
#: plugin.py:264
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -164,7 +174,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:270
|
||||
#: plugin.py:280
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -174,7 +184,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:335
|
||||
#: plugin.py:345
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<Morse code text>\n"
|
||||
|
@ -183,7 +193,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:352
|
||||
#: plugin.py:362
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -192,7 +202,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:364
|
||||
#: plugin.py:374
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -201,7 +211,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:381
|
||||
#: plugin.py:391
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -210,7 +220,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:391
|
||||
#: plugin.py:401
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -219,7 +229,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:402
|
||||
#: plugin.py:412
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -228,7 +238,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:411
|
||||
#: plugin.py:421
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -237,7 +247,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:438
|
||||
#: plugin.py:448
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -246,279 +256,279 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:534
|
||||
#: plugin.py:544
|
||||
msgid "ay"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:534
|
||||
#: plugin.py:544
|
||||
msgid "bee"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:534
|
||||
#: plugin.py:544
|
||||
msgid "dee"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:534
|
||||
#: plugin.py:544
|
||||
msgid "see"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:535
|
||||
#: plugin.py:545
|
||||
msgid "aych"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:535
|
||||
#: plugin.py:545
|
||||
msgid "ee"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:535
|
||||
#: plugin.py:545
|
||||
msgid "eff"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:535
|
||||
#: plugin.py:545
|
||||
msgid "gee"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:536
|
||||
#: plugin.py:546
|
||||
msgid "ell"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:536
|
||||
#: plugin.py:546
|
||||
msgid "eye"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:536
|
||||
#: plugin.py:546
|
||||
msgid "jay"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:536
|
||||
#: plugin.py:546
|
||||
msgid "kay"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:537
|
||||
#: plugin.py:547
|
||||
msgid "cue"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:537
|
||||
#: plugin.py:547
|
||||
msgid "em"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:537
|
||||
#: plugin.py:547
|
||||
msgid "en"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:537
|
||||
#: plugin.py:547
|
||||
msgid "oh"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:537
|
||||
#: plugin.py:547
|
||||
msgid "pee"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:538
|
||||
#: plugin.py:548
|
||||
msgid "arr"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:538
|
||||
#: plugin.py:548
|
||||
msgid "ess"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:538
|
||||
#: plugin.py:548
|
||||
msgid "tee"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:538
|
||||
#: plugin.py:548
|
||||
msgid "you"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:539
|
||||
#: plugin.py:549
|
||||
msgid "double-you"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:539
|
||||
#: plugin.py:549
|
||||
msgid "ecks"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:539
|
||||
#: plugin.py:549
|
||||
msgid "vee"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:539
|
||||
#: plugin.py:549
|
||||
msgid "why"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:540
|
||||
#: plugin.py:550
|
||||
msgid "zee"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:545
|
||||
#: plugin.py:555
|
||||
msgid "exclamation point"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:546
|
||||
#: plugin.py:556
|
||||
msgid "quote"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:547
|
||||
#: plugin.py:557
|
||||
msgid "pound"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:548
|
||||
#: plugin.py:558
|
||||
msgid "dollar sign"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:549
|
||||
#: plugin.py:559
|
||||
msgid "percent"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:550
|
||||
#: plugin.py:560
|
||||
msgid "ampersand"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:551
|
||||
#: plugin.py:561
|
||||
msgid "single quote"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:552
|
||||
#: plugin.py:562
|
||||
msgid "left paren"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:553
|
||||
#: plugin.py:563
|
||||
msgid "right paren"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:554
|
||||
#: plugin.py:564
|
||||
msgid "asterisk"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:555
|
||||
#: plugin.py:565
|
||||
msgid "plus"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:556
|
||||
#: plugin.py:566
|
||||
msgid "comma"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:557
|
||||
#: plugin.py:567
|
||||
msgid "minus"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:558
|
||||
#: plugin.py:568
|
||||
msgid "period"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:559
|
||||
#: plugin.py:569
|
||||
msgid "slash"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:560
|
||||
#: plugin.py:570
|
||||
msgid "colon"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:561
|
||||
#: plugin.py:571
|
||||
msgid "semicolon"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:562
|
||||
#: plugin.py:572
|
||||
msgid "less than"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:563
|
||||
#: plugin.py:573
|
||||
msgid "equals"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:564
|
||||
#: plugin.py:574
|
||||
msgid "greater than"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:565
|
||||
#: plugin.py:575
|
||||
msgid "question mark"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:566
|
||||
#: plugin.py:576
|
||||
msgid "at"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:567
|
||||
#: plugin.py:577
|
||||
msgid "left bracket"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:568
|
||||
#: plugin.py:578
|
||||
msgid "backslash"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:569
|
||||
#: plugin.py:579
|
||||
msgid "right bracket"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:570
|
||||
#: plugin.py:580
|
||||
msgid "caret"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:571
|
||||
#: plugin.py:581
|
||||
msgid "underscore"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:572
|
||||
#: plugin.py:582
|
||||
msgid "backtick"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:573
|
||||
#: plugin.py:583
|
||||
msgid "left brace"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:574
|
||||
#: plugin.py:584
|
||||
msgid "pipe"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:575
|
||||
#: plugin.py:585
|
||||
msgid "right brace"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:576
|
||||
#: plugin.py:586
|
||||
msgid "tilde"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:579
|
||||
#: plugin.py:589
|
||||
msgid "one"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:579
|
||||
#: plugin.py:589
|
||||
msgid "three"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:579
|
||||
#: plugin.py:589
|
||||
msgid "two"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:579
|
||||
#: plugin.py:589
|
||||
msgid "zero"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:580
|
||||
#: plugin.py:590
|
||||
msgid "five"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:580
|
||||
#: plugin.py:590
|
||||
msgid "four"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:580
|
||||
#: plugin.py:590
|
||||
msgid "seven"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:580
|
||||
#: plugin.py:590
|
||||
msgid "six"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:581
|
||||
#: plugin.py:591
|
||||
msgid "eight"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:581
|
||||
#: plugin.py:591
|
||||
msgid "nine"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:585
|
||||
#: plugin.py:595
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -527,7 +537,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:615
|
||||
#: plugin.py:625
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -536,7 +546,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:624
|
||||
#: plugin.py:634
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -547,7 +557,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:643
|
||||
#: plugin.py:653
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -556,7 +566,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:692
|
||||
#: plugin.py:702
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
|
|
@ -163,6 +163,17 @@ class Filter(callbacks.Plugin):
|
|||
irc.reply(''.join(L))
|
||||
binary = wrap(binary, ['text'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def unbinary(self, irc, msg, args, text):
|
||||
"""<text>
|
||||
|
||||
Returns the character representation of binary <text>.
|
||||
Assumes ASCII, 8 digits per character.
|
||||
"""
|
||||
L = [chr(int(text[i:(i+8)], 2)) for i in xrange(0, len(text), 8)]
|
||||
irc.reply(''.join(L))
|
||||
unbinary = wrap(unbinary, ['text'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def hexlify(self, irc, msg, args, text):
|
||||
"""<text>
|
||||
|
|
|
@ -87,6 +87,9 @@ class FilterTest(ChannelPluginTestCase):
|
|||
def testBinary(self):
|
||||
self.assertResponse('binary A', '01000001')
|
||||
|
||||
def testUnbinary(self):
|
||||
self.assertResponse('unbinary 011011010110111101101111', 'moo')
|
||||
|
||||
def testRot13(self):
|
||||
for s in map(str, range(1000, 1010)):
|
||||
self.assertResponse('rot13 [rot13 %s]' % s, s)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot-fr\n"
|
||||
"POT-Creation-Date: 2010-10-17 12:46+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
|
@ -88,6 +88,18 @@ msgstr "<caractères à remplacer> doit être de la même taille que <caractère
|
|||
|
||||
#: plugin.py:103
|
||||
msgid ""
|
||||
"<substring to translate> <substring to replace it with> <text>\n"
|
||||
"\n"
|
||||
" Replaces all non-overlapping occurrences of <substring to translate>\n"
|
||||
" with <substring to replace it with> in <text>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<sous-chaîne à remplacer> <sous-chaîne de remplacement> <texte>\n"
|
||||
"\n"
|
||||
"Replace toutes les occurences de <sous-chaîne à remplacer> (à condition qu'elles n'entrent pas en conflit) par les <sous-chaîne de remplacement> dans le <texte>."
|
||||
|
||||
#: plugin.py:112
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
" Returns <text> uppercased.\n"
|
||||
|
@ -97,7 +109,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le texte, en majuscules"
|
||||
|
||||
#: plugin.py:112
|
||||
#: plugin.py:121
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -108,7 +120,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le texte, en minuscules"
|
||||
|
||||
#: plugin.py:121
|
||||
#: plugin.py:130
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -119,7 +131,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le texte, capitalisé"
|
||||
|
||||
#: plugin.py:130
|
||||
#: plugin.py:139
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -130,7 +142,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le texte, mis en majuscules de titre."
|
||||
|
||||
#: plugin.py:139
|
||||
#: plugin.py:148
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
|
@ -141,7 +153,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le texte, entouré de doubles guillemets."
|
||||
|
||||
#: plugin.py:148
|
||||
#: plugin.py:157
|
||||
msgid ""
|
||||
"<string 1> <string 2>\n"
|
||||
"\n"
|
||||
|
@ -154,7 +166,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Concatène les deux chaînes. Notez que ce n'est pas la même chose que de les joindre avec \"\", car, si <chaîne 2> contient des espaces, ils ne seront pas supprimés par la concaténation."
|
||||
|
||||
#: plugin.py:159
|
||||
#: plugin.py:168
|
||||
msgid ""
|
||||
"<size> <text>\n"
|
||||
"\n"
|
||||
|
@ -167,7 +179,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Coup le <texte> en morceaux de <taille>, en découpant les caractères dépassant la <taille>. Si la <taille> est un nombre négatif, il coupe en comptant à partir de la fin du texte."
|
||||
|
||||
#: plugin.py:170
|
||||
#: plugin.py:179
|
||||
msgid ""
|
||||
"<number> <text>\n"
|
||||
"\n"
|
||||
|
@ -179,7 +191,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne le <nombre>-ième élément (séparé par des espaces) du <texte>. C'est à dire que si le texte est \"foo bar baz\" et que <nombre> est 2, \"bar\" sera retourné."
|
||||
|
||||
#: plugin.py:183
|
||||
#: plugin.py:192
|
||||
msgid ""
|
||||
"<format string> [<arg> ...]\n"
|
||||
"\n"
|
||||
|
@ -191,7 +203,7 @@ msgstr ""
|
|||
"<chaîne de formattage> [<arg> ...]\n"
|
||||
"\n"
|
||||
|
||||
#: plugin.py:197
|
||||
#: plugin.py:206
|
||||
msgid "Not enough arguments for the format string."
|
||||
msgstr "Pas assez d'arguments pour formatter la chaîne."
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 12:46+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -79,9 +79,10 @@ msgstr ""
|
|||
#: plugin.py:103
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"<substring to translate> <substring to replace it with> <text>\n"
|
||||
"\n"
|
||||
" Returns <text> uppercased.\n"
|
||||
" Replaces all non-overlapping occurrences of <substring to translate>\n"
|
||||
" with <substring to replace it with> in <text>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
|
@ -90,7 +91,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
" Returns <text> lowercased.\n"
|
||||
" Returns <text> uppercased.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
|
@ -99,7 +100,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
" Returns <text> capitalized.\n"
|
||||
" Returns <text> lowercased.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
|
@ -108,7 +109,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
" Returns <text> titlecased.\n"
|
||||
" Returns <text> capitalized.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
|
@ -117,13 +118,22 @@ msgstr ""
|
|||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
" Returns the text surrounded by double quotes.\n"
|
||||
" Returns <text> titlecased.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:148
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
"\n"
|
||||
" Returns the text surrounded by double quotes.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:157
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<string 1> <string 2>\n"
|
||||
"\n"
|
||||
" Concatenates two strings. Do keep in mind that this is *not* the same\n"
|
||||
|
@ -132,7 +142,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:159
|
||||
#: plugin.py:168
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<size> <text>\n"
|
||||
|
@ -143,7 +153,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:170
|
||||
#: plugin.py:179
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<number> <text>\n"
|
||||
|
@ -153,7 +163,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:183
|
||||
#: plugin.py:192
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<format string> [<arg> ...]\n"
|
||||
|
@ -164,7 +174,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:197
|
||||
#: plugin.py:206
|
||||
msgid "Not enough arguments for the format string."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -99,6 +99,15 @@ class Format(callbacks.Plugin):
|
|||
translate = wrap(translate, ['something', 'something', 'text'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def replace(self, irc, msg, args, bad, good, text):
|
||||
"""<substring to translate> <substring to replace it with> <text>
|
||||
|
||||
Replaces all non-overlapping occurrences of <substring to translate>
|
||||
with <substring to replace it with> in <text>.
|
||||
"""
|
||||
irc.reply(text.replace(bad, good))
|
||||
replace = wrap(replace, ['something', 'something', 'text'])
|
||||
|
||||
def upper(self, irc, msg, args, text):
|
||||
"""<text>
|
||||
|
||||
|
|
|
@ -54,6 +54,10 @@ class FormatTestCase(PluginTestCase):
|
|||
|
||||
def testTranslate(self):
|
||||
self.assertResponse('translate 123 456 1234567890', '4564567890')
|
||||
self.assertError('translate 123 1234 123125151')
|
||||
|
||||
def testReplace(self):
|
||||
self.assertResponse('replace # %23 bla#foo', 'bla%23foo')
|
||||
|
||||
def testUpper(self):
|
||||
self.assertResponse('upper foo', 'FOO')
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 13:16+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -72,7 +72,8 @@ class Language(registry.OnlySomeStrings):
|
|||
'Tamil': 'ta', 'Tagalog': 'tl', 'Telugu': 'te',
|
||||
'Thai': 'th', 'Tibetan': 'bo', 'Turkish': 'tr',
|
||||
'Ukranian': 'uk', 'Urdu': 'ur', 'Uzbek': 'uz',
|
||||
'Uighur': 'ug', 'Vietnamese': 'vi'}
|
||||
'Uighur': 'ug', 'Vietnamese': 'vi',
|
||||
'Detect language': 'auto'}
|
||||
validStrings = ['lang_' + s for s in transLangs.values()]
|
||||
validStrings.append('')
|
||||
def normalize(self, s):
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2011-02-14 18:30+CET\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -27,12 +27,12 @@ msgstr ""
|
|||
msgid "Do you want the Google search snarfer enabled by default?"
|
||||
msgstr ""
|
||||
|
||||
#: config.py:88
|
||||
#: config.py:89
|
||||
#, docstring
|
||||
msgid "Value must be 1 <= n <= 8"
|
||||
msgstr ""
|
||||
|
||||
#: config.py:99
|
||||
#: config.py:100
|
||||
msgid ""
|
||||
"Determines the URL that will be sent to Google for\n"
|
||||
" the Referer field of the search requests. If this value is empty, a\n"
|
||||
|
@ -40,7 +40,7 @@ msgid ""
|
|||
" http://$server/$botName"
|
||||
msgstr ""
|
||||
|
||||
#: config.py:104
|
||||
#: config.py:105
|
||||
msgid ""
|
||||
"Determines whether the search snarfer is\n"
|
||||
" enabled. If so, messages (even unaddressed ones) beginning with the word\n"
|
||||
|
@ -48,33 +48,33 @@ msgid ""
|
|||
" channel."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:109
|
||||
#: config.py:110
|
||||
msgid ""
|
||||
"Determines whether the word 'google' in the\n"
|
||||
" bot's output will be made colorful (like Google's logo)."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:112
|
||||
#: config.py:113
|
||||
msgid "Determines whether results are bolded."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:114
|
||||
#: config.py:115
|
||||
msgid ""
|
||||
"Determines the maximum number of results returned\n"
|
||||
" from the google command."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:117
|
||||
#: config.py:118
|
||||
msgid ""
|
||||
"Determines what default language is used in\n"
|
||||
" searches. If left empty, no specific language will be requested."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:117
|
||||
#: config.py:118
|
||||
msgid "en"
|
||||
msgstr ""
|
||||
|
||||
#: config.py:120
|
||||
#: config.py:121
|
||||
msgid ""
|
||||
"Determines what level of search filtering to use\n"
|
||||
" by default. 'active' - most filtering, 'moderate' - default filtering,\n"
|
||||
|
@ -174,12 +174,12 @@ msgstr ""
|
|||
msgid "to language"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:297
|
||||
#: plugin.py:314
|
||||
#, docstring
|
||||
msgid "^google\\s+(.*)$"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:320
|
||||
#: plugin.py:336
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<expression>\n"
|
||||
|
@ -188,11 +188,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:337
|
||||
#: plugin.py:353
|
||||
msgid "Google's calculator didn't come up with anything."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:343
|
||||
#: plugin.py:359
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<phone number>\n"
|
||||
|
@ -201,7 +201,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:357
|
||||
#: plugin.py:373
|
||||
msgid "Google's phonebook didn't come up with anything."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -282,6 +282,11 @@ class Google(callbacks.PluginRegexp):
|
|||
lang.transLangs.keys()))
|
||||
else:
|
||||
toLang = lang.normalize('lang_'+toLang)[5:]
|
||||
if fromLang == 'auto':
|
||||
fromLang = ''
|
||||
if toLang == 'auto':
|
||||
irc.error("Destination language cannot be 'auto'.")
|
||||
return
|
||||
opts['langpair'] = '%s|%s' % (fromLang, toLang)
|
||||
fd = utils.web.getUrlFd('%s?%s' % (self._gtranslateUrl,
|
||||
urllib.urlencode(opts)),
|
||||
|
@ -289,8 +294,20 @@ class Google(callbacks.PluginRegexp):
|
|||
json = simplejson.load(fd)
|
||||
fd.close()
|
||||
if json['responseStatus'] != 200:
|
||||
raise callbacks.Error, 'We broke The Google!'
|
||||
raise callbacks.Error, 'Google says: Response Status %s: %s.' % \
|
||||
(json['responseStatus'], json['responseDetails'],)
|
||||
if fromLang != '':
|
||||
irc.reply(json['responseData']['translatedText'].encode('utf-8'))
|
||||
else:
|
||||
detected_language = json['responseData']['detectedSourceLanguage'].encode('utf-8')
|
||||
translation = json['responseData']['translatedText'].encode('utf-8')
|
||||
try:
|
||||
long_lang_name = [k for k,v in lang.transLangs.iteritems() if v == detected_language][0]
|
||||
except IndexError: #just in case google adds langs we don't know about
|
||||
long_lang_name = detected_language
|
||||
responsestring = "(Detected source language: %s) %s" % \
|
||||
(long_lang_name, translation)
|
||||
irc.reply(responsestring)
|
||||
translate = wrap(translate, ['something', 'to', 'something', 'text'])
|
||||
|
||||
def googleSnarfer(self, irc, msg, match):
|
||||
|
@ -310,8 +327,7 @@ class Google(callbacks.PluginRegexp):
|
|||
url = r'http://google.com/search?q=' + s
|
||||
return url
|
||||
|
||||
_calcRe1 = re.compile(r'<table.*class="?obcontainer"?[^>]*>(.*?)</table>', re.I)
|
||||
_calcRe2 = re.compile(r'<h\d class="?r"?.*?<b>(.*?)</b>', re.I)
|
||||
_calcRe = re.compile(r'<h\d class="?r"?.*?<b>(.*?)</b>', re.I)
|
||||
_calcSupRe = re.compile(r'<sup>(.*?)</sup>', re.I)
|
||||
_calcFontRe = re.compile(r'<font size=-2>(.*?)</font>')
|
||||
_calcTimesRe = re.compile(r'&(?:times|#215);')
|
||||
|
@ -323,9 +339,7 @@ class Google(callbacks.PluginRegexp):
|
|||
"""
|
||||
url = self._googleUrl(expr)
|
||||
html = utils.web.getUrl(url)
|
||||
match = self._calcRe1.search(html)
|
||||
if match is None:
|
||||
match = self._calcRe2.search(html)
|
||||
match = self._calcRe.search(html)
|
||||
if match is not None:
|
||||
s = match.group(1)
|
||||
s = self._calcSupRe.sub(r'^(\1)', s)
|
||||
|
|
|
@ -39,7 +39,6 @@ class GoogleTestCase(ChannelPluginTestCase):
|
|||
def testCalc(self):
|
||||
self.assertNotRegexp('google calc e^(i*pi)+1', r'didn\'t')
|
||||
self.assertNotRegexp('google calc 1 usd in gbp', r'didn\'t')
|
||||
self.assertRegexp('google calc current time in usa', r'Time in.*USA')
|
||||
|
||||
def testHtmlHandled(self):
|
||||
self.assertNotRegexp('google calc '
|
||||
|
@ -61,6 +60,8 @@ class GoogleTestCase(ChannelPluginTestCase):
|
|||
|
||||
def testTranslate(self):
|
||||
self.assertRegexp('translate en es hello world', 'mundo')
|
||||
self.assertRegexp('translate auto en ciao', 'Italian.*hello')
|
||||
self.assertError('translate en to auto stuff')
|
||||
|
||||
def testCalcDoesNotHaveExtraSpaces(self):
|
||||
self.assertNotRegexp('google calc 1000^2', r'\s+,\s+')
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 15:21+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 15:20+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -15,12 +15,12 @@ msgstr ""
|
|||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: plugin.py:43
|
||||
#: plugin.py:42
|
||||
#, docstring
|
||||
msgid "Add the help for \"@help Internet\" here."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:47
|
||||
#: plugin.py:46
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<host|ip>\n"
|
||||
|
@ -29,11 +29,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:54 plugin.py:61 plugin.py:65
|
||||
#: plugin.py:53 plugin.py:60 plugin.py:64
|
||||
msgid "Host not found."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:77
|
||||
#: plugin.py:76
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<domain>\n"
|
||||
|
@ -42,39 +42,39 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:83
|
||||
#: plugin.py:82
|
||||
msgid "domain"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:112
|
||||
#: plugin.py:111
|
||||
msgid "updated %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:115
|
||||
#: plugin.py:114
|
||||
msgid "registered %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:118
|
||||
#: plugin.py:117
|
||||
msgid "expires %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:138
|
||||
#: plugin.py:137
|
||||
msgid " <registered at %s>"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:140
|
||||
#: plugin.py:139
|
||||
msgid " <registered by %s>"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:145
|
||||
#: plugin.py:144
|
||||
msgid "%s%s is %L."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:148
|
||||
#: plugin.py:147
|
||||
msgid "I couldn't find such a domain."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:153
|
||||
#: plugin.py:152
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<ip>\n"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-28 15:19+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -51,11 +51,11 @@ msgid ""
|
|||
" increase/decrease karma without being addressed."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:243 plugin.py:251
|
||||
#: plugin.py:247 plugin.py:255
|
||||
msgid "You're not allowed to adjust your own karma."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:280
|
||||
#: plugin.py:284
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] [<thing> ...]\n"
|
||||
|
@ -69,35 +69,35 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:293
|
||||
#: plugin.py:297
|
||||
msgid "%s has neutral karma."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:300
|
||||
#: plugin.py:304
|
||||
msgid "Karma for %q has been increased %n and decreased %n for a total karma of %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:302 plugin.py:303
|
||||
#: plugin.py:306 plugin.py:307
|
||||
msgid "time"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:316
|
||||
#: plugin.py:320
|
||||
msgid "I didn't know the karma for any of those things."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:326 plugin.py:355
|
||||
#: plugin.py:330 plugin.py:359
|
||||
msgid "I have no karma for this channel."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:331
|
||||
#: plugin.py:335
|
||||
msgid " You (%s) are ranked %i out of %i."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:335
|
||||
#: plugin.py:339
|
||||
msgid "Highest karma: %L. Lowest karma: %L.%s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:343
|
||||
#: plugin.py:347
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] {increased,decreased,active}\n"
|
||||
|
@ -108,7 +108,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:361
|
||||
#: plugin.py:365
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <name>\n"
|
||||
|
@ -117,7 +117,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:371
|
||||
#: plugin.py:375
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <filename>\n"
|
||||
|
@ -128,7 +128,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:383
|
||||
#: plugin.py:387
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <filename>\n"
|
||||
|
|
|
@ -41,6 +41,11 @@ import supybot.callbacks as callbacks
|
|||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization('Karma')
|
||||
|
||||
try:
|
||||
import sqlite3
|
||||
except ImportError:
|
||||
from pysqlite2 import dbapi2 as sqlite3 # for python2.4
|
||||
|
||||
class SqliteKarmaDB(object):
|
||||
def __init__(self, filename):
|
||||
self.dbs = ircutils.IrcDict()
|
||||
|
@ -51,19 +56,16 @@ class SqliteKarmaDB(object):
|
|||
db.close()
|
||||
|
||||
def _getDb(self, channel):
|
||||
try:
|
||||
import sqlite
|
||||
except ImportError:
|
||||
raise callbacks.Error, 'You need to have PySQLite installed to ' \
|
||||
'use Karma. Download it at ' \
|
||||
'<http://code.google.com/p/pysqlite/>'
|
||||
filename = plugins.makeChannelFilename(self.filename, channel)
|
||||
if filename in self.dbs:
|
||||
return self.dbs[filename]
|
||||
if os.path.exists(filename):
|
||||
self.dbs[filename] = sqlite.connect(filename)
|
||||
return self.dbs[filename]
|
||||
db = sqlite.connect(filename)
|
||||
db = sqlite3.connect(filename)
|
||||
db.text_factory = str
|
||||
self.dbs[filename] = db
|
||||
return db
|
||||
db = sqlite3.connect(filename)
|
||||
db.text_factory = str
|
||||
self.dbs[filename] = db
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""CREATE TABLE karma (
|
||||
|
@ -84,20 +86,21 @@ class SqliteKarmaDB(object):
|
|||
thing = thing.lower()
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT added, subtracted FROM karma
|
||||
WHERE normalized=%s""", thing)
|
||||
if cursor.rowcount == 0:
|
||||
WHERE normalized=?""", (thing,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
return None
|
||||
else:
|
||||
return map(int, cursor.fetchone())
|
||||
return map(int, results[0])
|
||||
|
||||
def gets(self, channel, things):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
normalizedThings = dict(zip(map(lambda s: s.lower(), things), things))
|
||||
criteria = ' OR '.join(['normalized=%s'] * len(normalizedThings))
|
||||
criteria = ' OR '.join(['normalized=?'] * len(normalizedThings))
|
||||
sql = """SELECT name, added-subtracted FROM karma
|
||||
WHERE %s ORDER BY added-subtracted DESC""" % criteria
|
||||
cursor.execute(sql, *normalizedThings)
|
||||
cursor.execute(sql, normalizedThings.keys())
|
||||
L = [(name, int(karma)) for (name, karma) in cursor.fetchall()]
|
||||
for (name, _) in L:
|
||||
del normalizedThings[name.lower()]
|
||||
|
@ -109,26 +112,27 @@ class SqliteKarmaDB(object):
|
|||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT name, added-subtracted FROM karma
|
||||
ORDER BY added-subtracted DESC LIMIT %s""", limit)
|
||||
ORDER BY added-subtracted DESC LIMIT ?""", (limit,))
|
||||
return [(t[0], int(t[1])) for t in cursor.fetchall()]
|
||||
|
||||
def bottom(self, channel, limit):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT name, added-subtracted FROM karma
|
||||
ORDER BY added-subtracted ASC LIMIT %s""", limit)
|
||||
ORDER BY added-subtracted ASC LIMIT ?""", (limit,))
|
||||
return [(t[0], int(t[1])) for t in cursor.fetchall()]
|
||||
|
||||
def rank(self, channel, thing):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT added-subtracted FROM karma
|
||||
WHERE name=%s""", thing)
|
||||
if cursor.rowcount == 0:
|
||||
WHERE name=?""", (thing,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
return None
|
||||
karma = int(cursor.fetchone()[0])
|
||||
karma = int(results[0][0])
|
||||
cursor.execute("""SELECT COUNT(*) FROM karma
|
||||
WHERE added-subtracted > %s""", karma)
|
||||
WHERE added-subtracted > ?""", (karma,))
|
||||
rank = int(cursor.fetchone()[0])
|
||||
return rank+1
|
||||
|
||||
|
@ -142,20 +146,20 @@ class SqliteKarmaDB(object):
|
|||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
normalized = name.lower()
|
||||
cursor.execute("""INSERT INTO karma VALUES (NULL, %s, %s, 0, 0)""",
|
||||
name, normalized)
|
||||
cursor.execute("""INSERT INTO karma VALUES (NULL, ?, ?, 0, 0)""",
|
||||
(name, normalized,))
|
||||
cursor.execute("""UPDATE karma SET added=added+1
|
||||
WHERE normalized=%s""", normalized)
|
||||
WHERE normalized=?""", (normalized,))
|
||||
db.commit()
|
||||
|
||||
def decrement(self, channel, name):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
normalized = name.lower()
|
||||
cursor.execute("""INSERT INTO karma VALUES (NULL, %s, %s, 0, 0)""",
|
||||
name, normalized)
|
||||
cursor.execute("""INSERT INTO karma VALUES (NULL, ?, ?, 0, 0)""",
|
||||
(name, normalized,))
|
||||
cursor.execute("""UPDATE karma SET subtracted=subtracted+1
|
||||
WHERE normalized=%s""", normalized)
|
||||
WHERE normalized=?""", (normalized,))
|
||||
db.commit()
|
||||
|
||||
def most(self, channel, kind, limit):
|
||||
|
@ -179,7 +183,7 @@ class SqliteKarmaDB(object):
|
|||
cursor = db.cursor()
|
||||
normalized = name.lower()
|
||||
cursor.execute("""UPDATE karma SET subtracted=0, added=0
|
||||
WHERE normalized=%s""", normalized)
|
||||
WHERE normalized=?""", (normalized,))
|
||||
db.commit()
|
||||
|
||||
def dump(self, channel, filename):
|
||||
|
@ -203,13 +207,13 @@ class SqliteKarmaDB(object):
|
|||
for (name, added, subtracted) in reader:
|
||||
normalized = name.lower()
|
||||
cursor.execute("""INSERT INTO karma
|
||||
VALUES (NULL, %s, %s, %s, %s)""",
|
||||
name, normalized, added, subtracted)
|
||||
VALUES (NULL, ?, ?, ?, ?)""",
|
||||
(name, normalized, added, subtracted,))
|
||||
db.commit()
|
||||
fd.close()
|
||||
|
||||
KarmaDB = plugins.DB('Karma',
|
||||
{'sqlite': SqliteKarmaDB})
|
||||
{'sqlite3': SqliteKarmaDB})
|
||||
|
||||
class Karma(callbacks.Plugin):
|
||||
callBefore = ('Factoids', 'MoobotFactoids', 'Infobot')
|
||||
|
|
|
@ -30,12 +30,11 @@
|
|||
from supybot.test import *
|
||||
|
||||
try:
|
||||
import sqlite
|
||||
import sqlite3
|
||||
except ImportError:
|
||||
sqlite = None
|
||||
from pysqlite2 import dbapi2 as sqlite3 # for python2.4
|
||||
|
||||
if sqlite is not None:
|
||||
class KarmaTestCase(ChannelPluginTestCase):
|
||||
class KarmaTestCase(ChannelPluginTestCase):
|
||||
plugins = ('Karma',)
|
||||
def testKarma(self):
|
||||
self.assertError('karma')
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 15:21+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -48,5 +48,12 @@ conf.registerGlobalValue(Later, 'maximum',
|
|||
conf.registerGlobalValue(Later, 'private',
|
||||
registry.Boolean(True, _("""Determines whether users will be notified in
|
||||
the first place in which they're seen, or in private.""")))
|
||||
conf.registerGlobalValue(Later, 'tellOnJoin',
|
||||
registry.Boolean(True, _("""Determines whether users will be notified upon
|
||||
joining any channel the bot is in, or only upon sending a message.""")))
|
||||
conf.registerGlobalValue(Later, 'messageExpiry',
|
||||
registry.NonNegativeInteger(30, _("""Determines the maximum number of
|
||||
days that a message will remain queued for a user. After this time elapses,
|
||||
the message will be deleted. If this value is 0, there is no maximum.""")))
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot-fr\n"
|
||||
"POT-Creation-Date: 2010-10-28 16:15+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
|
@ -26,6 +26,19 @@ msgid ""
|
|||
" the first place in which they're seen, or in private."
|
||||
msgstr "Détermine si les utilisateurs seront notifiés au premier endroit où ils sont vus, ou en privé."
|
||||
|
||||
#: config.py:52
|
||||
msgid ""
|
||||
"Determines whether users will be notified upon\n"
|
||||
" joining any channel the bot is in, or only upon sending a message."
|
||||
msgstr "Détermine si les utilisateurs seront notifiés au premier endroit où ils sont vus, ou seulement lorsqu'ils envoient un message."
|
||||
|
||||
#: config.py:55
|
||||
msgid ""
|
||||
"Determines the maximum number of\n"
|
||||
" days that a message will remain queued for a user. After this time elapses,\n"
|
||||
" the message will be deleted. If this value is 0, there is no maximum."
|
||||
msgstr "Détermine le nombre maximum de messages en attente d'un utilisateur. Après que ce temps se soit écoulé, le message sera supprimé. Si la valeur est 0, il n'y a pas de maximum."
|
||||
|
||||
#: plugin.py:46
|
||||
msgid ""
|
||||
"Used to do things later; currently, it only allows the sending of\n"
|
||||
|
@ -42,7 +55,22 @@ msgstr "il y a %s"
|
|||
msgid "just now"
|
||||
msgstr "à l'instant"
|
||||
|
||||
#: plugin.py:107
|
||||
#: plugin.py:106
|
||||
msgid ""
|
||||
"Validate nick according to the IRC RFC 2812 spec.\n"
|
||||
"\n"
|
||||
" Reference: http://tools.ietf.org/rfcmarkup?doc=2812#section-2.3.1\n"
|
||||
"\n"
|
||||
" Some irc clients' tab-completion feature appends 'address' characters\n"
|
||||
" to nick, such as ':' or ','. We try correcting for that by trimming\n"
|
||||
" a char off the end.\n"
|
||||
"\n"
|
||||
" If nick incorrigibly invalid, return False, otherwise,\n"
|
||||
" return (possibly trimmed) nick.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:151
|
||||
msgid ""
|
||||
"<nick> <text>\n"
|
||||
"\n"
|
||||
|
@ -55,15 +83,15 @@ msgstr ""
|
|||
"\n"
|
||||
"Dit le <texte> à <nick> la prochaine fois qu'il est vu. <nick> peut contenir des jokers, et le premier nick correspondant recevra la note."
|
||||
|
||||
#: plugin.py:114
|
||||
#: plugin.py:159
|
||||
msgid "I can't send notes to myself."
|
||||
msgstr "Je ne peux m'envoyer de notes à moi-même."
|
||||
|
||||
#: plugin.py:120
|
||||
#: plugin.py:169
|
||||
msgid "That person's message queue is already full."
|
||||
msgstr "La file d'attente des messages de cette personne est déjà pleine."
|
||||
|
||||
#: plugin.py:125
|
||||
#: plugin.py:174
|
||||
msgid ""
|
||||
"[<nick>]\n"
|
||||
"\n"
|
||||
|
@ -75,19 +103,19 @@ msgstr ""
|
|||
"\n"
|
||||
"Si le <nick> est donné, répond avec les notes en attente pour <nick> ; sinon, répond avec les nicks ayant des notes en attente."
|
||||
|
||||
#: plugin.py:136
|
||||
#: plugin.py:185
|
||||
msgid "I have no notes for that nick."
|
||||
msgstr "Je n'ai pas de note pour ce nick."
|
||||
|
||||
#: plugin.py:141
|
||||
#: plugin.py:190
|
||||
msgid "I currently have notes waiting for %L."
|
||||
msgstr "J'ai actuellement des notes en attente pour %L."
|
||||
|
||||
#: plugin.py:144
|
||||
#: plugin.py:193
|
||||
msgid "I have no notes waiting to be delivered."
|
||||
msgstr "Je n'ai pas de note à délivrer."
|
||||
|
||||
#: plugin.py:149
|
||||
#: plugin.py:198
|
||||
msgid ""
|
||||
"<nick>\n"
|
||||
"\n"
|
||||
|
@ -98,11 +126,11 @@ msgstr ""
|
|||
"\n"
|
||||
"Supprime les notes en attente pour <nick>."
|
||||
|
||||
#: plugin.py:158
|
||||
#: plugin.py:207
|
||||
msgid "There were no notes for %r"
|
||||
msgstr "Il n'y a pas de note pour %r"
|
||||
|
||||
#: plugin.py:182
|
||||
#: plugin.py:231
|
||||
msgid "Sent %s: <%s> %s"
|
||||
msgstr "Envoyé %s : <%s> %s"
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-28 16:15+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -28,6 +28,19 @@ msgid ""
|
|||
" the first place in which they're seen, or in private."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:52
|
||||
msgid ""
|
||||
"Determines whether users will be notified upon\n"
|
||||
" joining any channel the bot is in, or only upon sending a message."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:55
|
||||
msgid ""
|
||||
"Determines the maximum number of\n"
|
||||
" days that a message will remain queued for a user. After this time elapses,\n"
|
||||
" the message will be deleted. If this value is 0, there is no maximum."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:46
|
||||
#, docstring
|
||||
msgid ""
|
||||
|
@ -45,7 +58,23 @@ msgstr ""
|
|||
msgid "just now"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:107
|
||||
#: plugin.py:106
|
||||
#, docstring
|
||||
msgid ""
|
||||
"Validate nick according to the IRC RFC 2812 spec.\n"
|
||||
"\n"
|
||||
" Reference: http://tools.ietf.org/rfcmarkup?doc=2812#section-2.3.1\n"
|
||||
"\n"
|
||||
" Some irc clients' tab-completion feature appends 'address' characters\n"
|
||||
" to nick, such as ':' or ','. We try correcting for that by trimming\n"
|
||||
" a char off the end.\n"
|
||||
"\n"
|
||||
" If nick incorrigibly invalid, return False, otherwise,\n"
|
||||
" return (possibly trimmed) nick.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:151
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<nick> <text>\n"
|
||||
|
@ -56,15 +85,15 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:114
|
||||
#: plugin.py:159
|
||||
msgid "I can't send notes to myself."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:120
|
||||
#: plugin.py:169
|
||||
msgid "That person's message queue is already full."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:125
|
||||
#: plugin.py:174
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<nick>]\n"
|
||||
|
@ -74,19 +103,19 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:136
|
||||
#: plugin.py:185
|
||||
msgid "I have no notes for that nick."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:141
|
||||
#: plugin.py:190
|
||||
msgid "I currently have notes waiting for %L."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:144
|
||||
#: plugin.py:193
|
||||
msgid "I have no notes waiting to be delivered."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:149
|
||||
#: plugin.py:198
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<nick>\n"
|
||||
|
@ -95,11 +124,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:158
|
||||
#: plugin.py:207
|
||||
msgid "There were no notes for %r"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:182
|
||||
#: plugin.py:231
|
||||
msgid "Sent %s: <%s> %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
import csv
|
||||
import time
|
||||
import datetime
|
||||
|
||||
import supybot.log as log
|
||||
import supybot.conf as conf
|
||||
|
@ -41,7 +42,6 @@ import supybot.callbacks as callbacks
|
|||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization('Later')
|
||||
|
||||
|
||||
class Later(callbacks.Plugin):
|
||||
"""Used to do things later; currently, it only allows the sending of
|
||||
nick-based notes. Do note (haha!) that these notes are *not* private
|
||||
|
@ -102,6 +102,50 @@ class Later(callbacks.Plugin):
|
|||
self.wildcards.append(nick)
|
||||
self._flushNotes()
|
||||
|
||||
def _validateNick(self, irc, nick):
|
||||
"""Validate nick according to the IRC RFC 2812 spec.
|
||||
|
||||
Reference: http://tools.ietf.org/rfcmarkup?doc=2812#section-2.3.1
|
||||
|
||||
Some irc clients' tab-completion feature appends 'address' characters
|
||||
to nick, such as ':' or ','. We try correcting for that by trimming
|
||||
a char off the end.
|
||||
|
||||
If nick incorrigibly invalid, return False, otherwise,
|
||||
return (possibly trimmed) nick.
|
||||
"""
|
||||
if not irc.isNick(nick):
|
||||
if not irc.isNick(nick[:-1]):
|
||||
return False
|
||||
else:
|
||||
return nick[:-1]
|
||||
return nick
|
||||
|
||||
def _deleteExpired(self):
|
||||
expiry = self.registryValue('messageExpiry')
|
||||
curtime = time.time()
|
||||
nickremovals=[]
|
||||
for (nick, notes) in self._notes.iteritems():
|
||||
removals = []
|
||||
for (notetime, whence, text) in notes:
|
||||
td = datetime.timedelta(seconds=(curtime - notetime))
|
||||
if td.days > expiry:
|
||||
removals.append((notetime, whence, text))
|
||||
for note in removals:
|
||||
notes.remove(note)
|
||||
if len(notes) == 0:
|
||||
nickremovals.append(nick)
|
||||
for nick in nickremovals:
|
||||
del self._notes[nick]
|
||||
self._flushNotes()
|
||||
|
||||
## Note: we call _deleteExpired from 'tell'. This means that it's possible
|
||||
## for expired notes to remain in the database for longer than the maximum,
|
||||
## if no tell's are called.
|
||||
## However, the whole point of this is to avoid crud accumulation in the
|
||||
## database, so it's fine that we only delete expired notes when we try
|
||||
## adding new ones.
|
||||
|
||||
@internationalizeDocstring
|
||||
def tell(self, irc, msg, args, nick, text):
|
||||
"""<nick> <text>
|
||||
|
@ -110,11 +154,16 @@ class Later(callbacks.Plugin):
|
|||
contain wildcard characters, and the first matching nick will be
|
||||
given the note.
|
||||
"""
|
||||
self._deleteExpired()
|
||||
if ircutils.strEqual(nick, irc.nick):
|
||||
irc.error(_('I can\'t send notes to myself.'))
|
||||
return
|
||||
validnick = self._validateNick(irc, nick)
|
||||
if validnick is False:
|
||||
irc.error('That is an invalid IRC nick. Please check your input.')
|
||||
return
|
||||
try:
|
||||
self._addNote(nick, msg.nick, text)
|
||||
self._addNote(validnick, msg.nick, text)
|
||||
irc.replySuccess()
|
||||
except ValueError:
|
||||
irc.error(_('That person\'s message queue is already full.'))
|
||||
|
@ -180,8 +229,11 @@ class Later(callbacks.Plugin):
|
|||
|
||||
def _formatNote(self, when, whence, note):
|
||||
return _('Sent %s: <%s> %s') % (self._timestamp(when), whence, note)
|
||||
Later = internationalizeDocstring(Later)
|
||||
|
||||
def doJoin(self, irc, msg):
|
||||
if self.registryValue('tellOnJoin'):
|
||||
self.doPrivmsg(irc, msg)
|
||||
Later = internationalizeDocstring(Later)
|
||||
|
||||
Class = Later
|
||||
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
###
|
||||
|
||||
from supybot.test import *
|
||||
import time
|
||||
|
||||
class LaterTestCase(PluginTestCase):
|
||||
class LaterTestCase(ChannelPluginTestCase):
|
||||
plugins = ('Later',)
|
||||
def testLaterWorksTwice(self):
|
||||
self.assertNotError('later tell foo bar')
|
||||
|
@ -43,6 +44,35 @@ class LaterTestCase(PluginTestCase):
|
|||
self.assertNotRegexp('later notes', 'bar.*foo')
|
||||
self.assertRegexp('later notes', 'foo')
|
||||
|
||||
def testNickValidation(self):
|
||||
origconf = conf.supybot.protocols.irc.strictRfc()
|
||||
conf.supybot.protocols.irc.strictRfc.setValue('True')
|
||||
self.assertError('later tell 1foo bar')
|
||||
self.assertError('later tell foo$moo zoob')
|
||||
self.assertNotError('later tell foo: baz')
|
||||
self.assertRegexp('later notes', 'foo\.')
|
||||
conf.supybot.protocols.irc.strictRfc.setValue(origconf)
|
||||
|
||||
def testNoteExpiry(self):
|
||||
cb = self.irc.getCallback('Later')
|
||||
# add a note 40 days in the past
|
||||
cb._addNote('foo', 'test', 'some stuff', at=(time.time() - 3456000))
|
||||
self.assertRegexp('later notes', 'foo')
|
||||
self.assertNotError('later tell moo stuff')
|
||||
self.assertNotRegexp('later notes', 'foo')
|
||||
self.assertRegexp('later notes', 'moo')
|
||||
|
||||
def testNoteSend(self):
|
||||
self.assertNotError('later tell foo stuff')
|
||||
self.assertNotError('later tell bar more stuff')
|
||||
self.assertRegexp('later notes', 'bar.*foo')
|
||||
testPrefix = 'foo!bar@baz'
|
||||
self.irc.feedMsg(ircmsgs.privmsg(self.channel, 'something',
|
||||
prefix=testPrefix))
|
||||
m = self.getMsg(' ')
|
||||
self.failUnless(str(m).startswith('PRIVMSG foo :Sent just now: <test> stuff'))
|
||||
self.assertNotRegexp('later notes', 'foo')
|
||||
self.assertRegexp('later notes', 'bar')
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 15:35+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -36,7 +36,7 @@ msgid ""
|
|||
" larger than supybot.plugins.Limiter.limit.minimumExcess."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:40
|
||||
#: plugin.py:39
|
||||
#, docstring
|
||||
msgid ""
|
||||
"In order to use this plugin, its config values need to be properly\n"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 15:35+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
The MessageParser plugin allows you to set custom regexp triggers, which will trigger the bot to respond if they match anywhere in the message. This is useful for those cases when you want a bot response even when the bot was not explicitly addressed by name or prefix character.
|
||||
|
||||
An updated page of this plugin's documentation is located here: http://sourceforge.net/apps/mediawiki/gribble/index.php?title=MessageParser_Plugin
|
|
@ -0,0 +1,67 @@
|
|||
###
|
||||
# Copyright (c) 2010, Daniel Folkinshteyn
|
||||
# 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.
|
||||
|
||||
###
|
||||
|
||||
"""
|
||||
MessageParser can be configured to run commands when a message matches a
|
||||
given trigger.
|
||||
"""
|
||||
|
||||
import supybot
|
||||
import supybot.world as world
|
||||
|
||||
# Use this for the version of this plugin. You may wish to put a CVS keyword
|
||||
# in here if you're keeping the plugin in CVS or some similar system.
|
||||
__version__ = "0.1"
|
||||
|
||||
# XXX Replace this with an appropriate author or supybot.Author instance.
|
||||
__author__ = supybot.authors.unknown
|
||||
|
||||
|
||||
# This is a dictionary mapping supybot.Author instances to lists of
|
||||
# contributions.
|
||||
__contributors__ = {}
|
||||
|
||||
# This is a url where the most recent plugin package can be downloaded.
|
||||
__url__ = '' # 'http://supybot.com/Members/yourname/MessageParser/download'
|
||||
|
||||
import config
|
||||
import plugin
|
||||
reload(plugin) # In case we're being reloaded.
|
||||
# Add more reloads here if you add third-party modules and want them to be
|
||||
# reloaded when this plugin is reloaded. Don't forget to import them as well!
|
||||
|
||||
if world.testing:
|
||||
import test
|
||||
|
||||
Class = plugin.Class
|
||||
configure = config.configure
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
|
@ -0,0 +1,80 @@
|
|||
###
|
||||
# Copyright (c) 2010, Daniel Folkinshteyn
|
||||
# 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.
|
||||
|
||||
###
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.registry as registry
|
||||
|
||||
try:
|
||||
from supybot.i18n import PluginInternationalization
|
||||
from supybot.i18n import internationalizeDocstring
|
||||
_ = PluginInternationalization('MessageParser')
|
||||
except:
|
||||
# This are useless functions that's allow to run the plugin on a bot
|
||||
# without the i18n plugin
|
||||
_ = lambda x:x
|
||||
internationalizeDocstring = lambda x:x
|
||||
|
||||
def configure(advanced):
|
||||
# This will be called by supybot to configure this module. advanced is
|
||||
# a bool that specifies whether the user identified himself as an advanced
|
||||
# user or not. You should effect your configuration by manipulating the
|
||||
# registry as appropriate.
|
||||
from supybot.questions import expect, anything, something, yn
|
||||
conf.registerPlugin('MessageParser', True)
|
||||
|
||||
MessageParser = conf.registerPlugin('MessageParser')
|
||||
# This is where your configuration variables (if any) should go. For example:
|
||||
# conf.registerGlobalValue(MessageParser, 'someConfigVariableName',
|
||||
# registry.Boolean(False, """Help for someConfigVariableName."""))
|
||||
conf.registerChannelValue(MessageParser, 'enable',
|
||||
registry.Boolean(True, _("""Determines whether the
|
||||
message parser is enabled. If enabled, will trigger on regexps
|
||||
added to the regexp db.""")))
|
||||
conf.registerChannelValue(MessageParser, 'keepRankInfo',
|
||||
registry.Boolean(True, _("""Determines whether we keep updating the usage
|
||||
count for each regexp, for popularity ranking.""")))
|
||||
conf.registerChannelValue(MessageParser, 'rankListLength',
|
||||
registry.Integer(20, _("""Determines the number of regexps returned
|
||||
by the triggerrank command.""")))
|
||||
conf.registerChannelValue(MessageParser, 'requireVacuumCapability',
|
||||
registry.String('admin', _("""Determines the capability required (if any) to
|
||||
vacuum the database.""")))
|
||||
conf.registerChannelValue(MessageParser, 'requireManageCapability',
|
||||
registry.String('admin; channel,op', _("""Determines the
|
||||
capabilities required (if any) to manage the regexp database,
|
||||
including add, remove, lock, unlock. Use 'channel,capab' for
|
||||
channel-level capabilities.
|
||||
Note that absence of an explicit anticapability means user has
|
||||
capability.""")))
|
||||
conf.registerChannelValue(MessageParser, 'listSeparator',
|
||||
registry.String(', ', _("""Determines the separator used between rexeps when
|
||||
shown by the list command.""")))
|
||||
|
||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
|
@ -0,0 +1 @@
|
|||
# Stub so local is a module, used for third-party modules
|
|
@ -0,0 +1,241 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Gribble\n"
|
||||
"POT-Creation-Date: 2011-02-26 11:47+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Français\n"
|
||||
"X-Poedit-Country: France\n"
|
||||
"X-Poedit-SourceCharset: Gribble\n"
|
||||
|
||||
#: config.py:49
|
||||
msgid ""
|
||||
"Determines whether the\n"
|
||||
" message parser is enabled. If enabled, will trigger on regexps\n"
|
||||
" added to the regexp db."
|
||||
msgstr "Détermine si le parseur de messages est activé. S'il l'est, il réagira aux expressions régulières qui sont dans la base de données d'expressions régulières."
|
||||
|
||||
#: config.py:53
|
||||
msgid ""
|
||||
"Determines whether we keep updating the usage\n"
|
||||
" count for each regexp, for popularity ranking."
|
||||
msgstr "Détermine si on met à jour le compteur d'utilisation de chaque expression régulière, pour un classement de popularité"
|
||||
|
||||
#: config.py:56
|
||||
msgid ""
|
||||
"Determines the number of regexps returned\n"
|
||||
" by the triggerrank command."
|
||||
msgstr "Détermine le nombre d'expressions régulières retournées par la commande triggerrank"
|
||||
|
||||
#: config.py:59
|
||||
msgid ""
|
||||
"Determines the capability required (if any) to\n"
|
||||
" vacuum the database."
|
||||
msgstr "Détermine la capacité requise (s'il y en a une) pour faire un vacuum de la base de données."
|
||||
|
||||
#: config.py:62
|
||||
msgid ""
|
||||
"Determines the\n"
|
||||
" capabilities required (if any) to manage the regexp database,\n"
|
||||
" including add, remove, lock, unlock. Use 'channel,capab' for\n"
|
||||
" channel-level capabilities.\n"
|
||||
" Note that absence of an explicit anticapability means user has\n"
|
||||
" capability."
|
||||
msgstr "Détermine les capacités requises (s'il y en a) pour gérer la base de données d'expressions régulières, ce qui inclue l'ajout, la suppression, le verrouillage, et le déverrouillage. Utilisez 'canal,capa' pour des permissions par canal. Notez que l'absence de toute anti-capacité explicite signifit que l'utilisateur peut le faire."
|
||||
|
||||
#: config.py:69
|
||||
msgid ""
|
||||
"Determines the separator used between rexeps when\n"
|
||||
" shown by the list command."
|
||||
msgstr "Détermine le séparateur utilisé entre les expressions régulières affichées par la commande list."
|
||||
|
||||
#: plugin.py:75
|
||||
msgid ""
|
||||
"This plugin can set regexp triggers to activate the bot.\n"
|
||||
" Use 'add' command to add regexp trigger, 'remove' to remove."
|
||||
msgstr "Ce plugin peut définir les triggers pour activer le bot. Utilisez la commande 'add' pour ajouter un trigger et 'remove' pour en retirer un."
|
||||
|
||||
#: plugin.py:83
|
||||
msgid "Create the database and connect to it."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:106
|
||||
msgid "Use this to get a database for a specific channel."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:129
|
||||
msgid "Run a command from message, as if command was sent over IRC."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:137
|
||||
msgid ""
|
||||
"Check if the user has any of the required capabilities to manage\n"
|
||||
" the regexp database."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:179
|
||||
msgid ""
|
||||
"[<channel>] <regexp> <action>\n"
|
||||
"\n"
|
||||
" Associates <regexp> with <action>. <channel> is only\n"
|
||||
" necessary if the message isn't sent on the channel\n"
|
||||
" itself. Action is echoed upon regexp match, with variables $1, $2, \n"
|
||||
" etc. being interpolated from the regexp match groups."
|
||||
msgstr ""
|
||||
"[<canal>] <expression régulière> <action>\n"
|
||||
"\n"
|
||||
"Associe l'<expression régulière> à l'<action>. <action> est affiché après la correspondance avec l'<expression régulière>, avec les variables $1, $2, etc, récupérés à partir des groupes de correspondance de l'<expression régulière>.<canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:201
|
||||
msgid "Invalid python regexp: %s"
|
||||
msgstr "Expression régulière Python invalide : %s"
|
||||
|
||||
#: plugin.py:213
|
||||
msgid "That trigger is locked."
|
||||
msgstr "Ce trigger est bloqué."
|
||||
|
||||
#: plugin.py:219
|
||||
msgid ""
|
||||
"[<channel>] [--id] <regexp>]\n"
|
||||
"\n"
|
||||
" Removes the trigger for <regexp> from the triggers database. \n"
|
||||
" <channel> is only necessary if\n"
|
||||
" the message isn't sent in the channel itself.\n"
|
||||
" If option --id specified, will retrieve by regexp id, not content.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>] [--id] <expression régulière>\n"
|
||||
"\n"
|
||||
"Supprime le déclencheur pour l'<expression régulière> de la base de données des déclencheurs. Si l'option --id est spécifiée, l'id de l'<expression régulière> sera récupéré, et non le contenu."
|
||||
|
||||
#: plugin.py:241
|
||||
#: plugin.py:271
|
||||
#: plugin.py:294
|
||||
#: plugin.py:322
|
||||
#: plugin.py:352
|
||||
msgid "There is no such regexp trigger."
|
||||
msgstr "Cette expression régulière n'existe pas."
|
||||
|
||||
#: plugin.py:245
|
||||
msgid "This regexp trigger is locked."
|
||||
msgstr "Cette expression régulière est verrouillée"
|
||||
|
||||
#: plugin.py:257
|
||||
msgid ""
|
||||
"[<channel>] <regexp>\n"
|
||||
"\n"
|
||||
" Locks the <regexp> so that it cannot be\n"
|
||||
" removed or overwritten to. <channel> is only necessary if the message isn't\n"
|
||||
" sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>] <expression régulière>\n"
|
||||
"\n"
|
||||
"Verrouille l'<expression régulière>, ce qui fait que l'on ne puisse plus la supprimer ou la modifier. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:280
|
||||
msgid ""
|
||||
"[<channel>] <regexp>\n"
|
||||
"\n"
|
||||
" Unlocks the entry associated with <regexp> so that it can be\n"
|
||||
" removed or overwritten. <channel> is only necessary if the message isn't\n"
|
||||
" sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>] <expression régulière>\n"
|
||||
"\n"
|
||||
"Déverrouille l'<expression régulière>, ce qui fait que l'on peut à nouveau la supprimer ou la modifier. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:303
|
||||
msgid ""
|
||||
"[<channel>] [--id] <regexp>\n"
|
||||
"\n"
|
||||
" Looks up the value of <regexp> in the triggers database.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel \n"
|
||||
" itself.\n"
|
||||
" If option --id specified, will retrieve by regexp id, not content.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>] [--id] <expression régulière>\n"
|
||||
"\n"
|
||||
"Recherche la valeur de l'<expression régulière> de la base de données des déclencheurs. Si l'option --id est spécifiée, l'id de l'<expression régulière> sera récupéré, et non le contenu."
|
||||
|
||||
#: plugin.py:332
|
||||
msgid ""
|
||||
"[<channel>] [--id] <regexp>\n"
|
||||
"\n"
|
||||
" Display information about <regexp> in the triggers database.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel \n"
|
||||
" itself.\n"
|
||||
" If option --id specified, will retrieve by regexp id, not content.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>] [--id] <expression régulière>\n"
|
||||
"\n"
|
||||
"Affiche des informations à propos de l'<expression régulière> de la base de données des déclencheurs. Si l'option --id est spécifiée, l'id de l'<expression régulière> sera récupéré, et non le contenu."
|
||||
|
||||
#: plugin.py:355
|
||||
msgid "The regexp id is %d, regexp is \"%s\", and action is \"%s\". It was added by user %s on %s, has been triggered %d times, and is %s."
|
||||
msgstr "L'id de l'expression régulière est %d, l'expression régulière est \"%s\", et l'action est \"%s\". Elle a été ajoutée par l'utilisateur %s le %s, et a été utilisée %d fois, et est %s"
|
||||
|
||||
#: plugin.py:364
|
||||
msgid "locked"
|
||||
msgstr "verouillée"
|
||||
|
||||
#: plugin.py:364
|
||||
msgid "not locked"
|
||||
msgstr "non verrouillée"
|
||||
|
||||
#: plugin.py:371
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" Lists regexps present in the triggers database.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel \n"
|
||||
" itself. Regexp ID listed in paretheses.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>]\n"
|
||||
"\n"
|
||||
"Liste les expressions régulières présentes dans la base de données. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:384
|
||||
#: plugin.py:410
|
||||
msgid "There are no regexp triggers in the database."
|
||||
msgstr "Il n'y a pas d'expression régulière dans ma base de données."
|
||||
|
||||
#: plugin.py:394
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
" \n"
|
||||
" Returns a list of top-ranked regexps, sorted by usage count \n"
|
||||
" (rank). The number of regexps returned is set by the \n"
|
||||
" rankListLength registry value. <channel> is only necessary if the \n"
|
||||
" message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>]\n"
|
||||
"\n"
|
||||
"Retourne une liste des expressions régulières les plus utilisées. Le nombre d'expressions régulières est définie par la variable de registre supybot.plugins.MessageParser.rankListLength. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:418
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
" \n"
|
||||
" Vacuums the database for <channel>.\n"
|
||||
" See SQLite vacuum doc here: http://www.sqlite.org/lang_vacuum.html\n"
|
||||
" <channel> is only necessary if the message isn't sent in \n"
|
||||
" the channel itself.\n"
|
||||
" First check if user has the required capability specified in plugin \n"
|
||||
" config requireVacuumCapability.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>]\n"
|
||||
"\n"
|
||||
"Fait un vacuum de la base de données pour le <canal>.Lisez la documentation de SQLite sur cette fonctionnalité : http://www.sqlite.org/lang_vacuum.htmlVérifie d'abord si l'utilisateur a bien la permission spécifiée dans la variable de configuration supybot.plugins.requireVacuumCapability<canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2011-02-26 11:47+CET\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\n"
|
||||
" message parser is enabled. If enabled, will trigger on regexps\n"
|
||||
" added to the regexp db."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:53
|
||||
msgid ""
|
||||
"Determines whether we keep updating the usage\n"
|
||||
" count for each regexp, for popularity ranking."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:56
|
||||
msgid ""
|
||||
"Determines the number of regexps returned\n"
|
||||
" by the triggerrank command."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:59
|
||||
msgid ""
|
||||
"Determines the capability required (if any) to\n"
|
||||
" vacuum the database."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:62
|
||||
msgid ""
|
||||
"Determines the\n"
|
||||
" capabilities required (if any) to manage the regexp database,\n"
|
||||
" including add, remove, lock, unlock. Use 'channel,capab' for\n"
|
||||
" channel-level capabilities.\n"
|
||||
" Note that absence of an explicit anticapability means user has\n"
|
||||
" capability."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:69
|
||||
msgid ""
|
||||
"Determines the separator used between rexeps when\n"
|
||||
" shown by the list command."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:75
|
||||
#, docstring
|
||||
msgid ""
|
||||
"This plugin can set regexp triggers to activate the bot.\n"
|
||||
" Use 'add' command to add regexp trigger, 'remove' to remove."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:83
|
||||
#, docstring
|
||||
msgid "Create the database and connect to it."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:106
|
||||
#, docstring
|
||||
msgid "Use this to get a database for a specific channel."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:129
|
||||
#, docstring
|
||||
msgid "Run a command from message, as if command was sent over IRC."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:137
|
||||
#, docstring
|
||||
msgid ""
|
||||
"Check if the user has any of the required capabilities to manage\n"
|
||||
" the regexp database."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:179
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <regexp> <action>\n"
|
||||
"\n"
|
||||
" Associates <regexp> with <action>. <channel> is only\n"
|
||||
" necessary if the message isn't sent on the channel\n"
|
||||
" itself. Action is echoed upon regexp match, with variables $1, $2, \n"
|
||||
" etc. being interpolated from the regexp match groups."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:201
|
||||
msgid "Invalid python regexp: %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:213
|
||||
msgid "That trigger is locked."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:219
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] [--id] <regexp>]\n"
|
||||
"\n"
|
||||
" Removes the trigger for <regexp> from the triggers database. \n"
|
||||
" <channel> is only necessary if\n"
|
||||
" the message isn't sent in the channel itself.\n"
|
||||
" If option --id specified, will retrieve by regexp id, not content.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:241 plugin.py:271 plugin.py:294 plugin.py:322 plugin.py:352
|
||||
msgid "There is no such regexp trigger."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:245
|
||||
msgid "This regexp trigger is locked."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:257
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <regexp>\n"
|
||||
"\n"
|
||||
" Locks the <regexp> so that it cannot be\n"
|
||||
" removed or overwritten to. <channel> is only necessary if the message isn't\n"
|
||||
" sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:280
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <regexp>\n"
|
||||
"\n"
|
||||
" Unlocks the entry associated with <regexp> so that it can be\n"
|
||||
" removed or overwritten. <channel> is only necessary if the message isn't\n"
|
||||
" sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:303
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] [--id] <regexp>\n"
|
||||
"\n"
|
||||
" Looks up the value of <regexp> in the triggers database.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel \n"
|
||||
" itself.\n"
|
||||
" If option --id specified, will retrieve by regexp id, not content.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:332
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] [--id] <regexp>\n"
|
||||
"\n"
|
||||
" Display information about <regexp> in the triggers database.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel \n"
|
||||
" itself.\n"
|
||||
" If option --id specified, will retrieve by regexp id, not content.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:355
|
||||
msgid "The regexp id is %d, regexp is \"%s\", and action is \"%s\". It was added by user %s on %s, has been triggered %d times, and is %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:364
|
||||
msgid "locked"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:364
|
||||
msgid "not locked"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:371
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" Lists regexps present in the triggers database.\n"
|
||||
" <channel> is only necessary if the message isn't sent in the channel \n"
|
||||
" itself. Regexp ID listed in paretheses.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:384 plugin.py:410
|
||||
msgid "There are no regexp triggers in the database."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:394
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
" \n"
|
||||
" Returns a list of top-ranked regexps, sorted by usage count \n"
|
||||
" (rank). The number of regexps returned is set by the \n"
|
||||
" rankListLength registry value. <channel> is only necessary if the \n"
|
||||
" message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:418
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
" \n"
|
||||
" Vacuums the database for <channel>.\n"
|
||||
" See SQLite vacuum doc here: http://www.sqlite.org/lang_vacuum.html\n"
|
||||
" <channel> is only necessary if the message isn't sent in \n"
|
||||
" the channel itself.\n"
|
||||
" First check if user has the required capability specified in plugin \n"
|
||||
" config requireVacuumCapability.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,442 @@
|
|||
###
|
||||
# Copyright (c) 2010, Daniel Folkinshteyn
|
||||
# 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.
|
||||
|
||||
###
|
||||
|
||||
import supybot.utils as utils
|
||||
from supybot.commands import *
|
||||
import supybot.plugins as plugins
|
||||
import supybot.ircutils as ircutils
|
||||
import supybot.callbacks as callbacks
|
||||
|
||||
import supybot.conf as conf
|
||||
import supybot.ircdb as ircdb
|
||||
|
||||
import re
|
||||
import os
|
||||
import time
|
||||
|
||||
try:
|
||||
from supybot.i18n import PluginInternationalization
|
||||
from supybot.i18n import internationalizeDocstring
|
||||
_ = PluginInternationalization('MessageParser')
|
||||
except:
|
||||
# This are useless functions that's allow to run the plugin on a bot
|
||||
# without the i18n plugin
|
||||
_ = lambda x:x
|
||||
internationalizeDocstring = lambda x:x
|
||||
|
||||
#try:
|
||||
#import sqlite
|
||||
#except ImportError:
|
||||
#raise callbacks.Error, 'You need to have PySQLite installed to use this ' \
|
||||
#'plugin. Download it at ' \
|
||||
#'<http://code.google.com/p/pysqlite/>'
|
||||
|
||||
try:
|
||||
import sqlite3
|
||||
except ImportError:
|
||||
from pysqlite2 import dbapi2 as sqlite3 # for python2.4
|
||||
|
||||
# these are needed cuz we are overriding getdb
|
||||
import threading
|
||||
import supybot.world as world
|
||||
|
||||
|
||||
import supybot.log as log
|
||||
|
||||
|
||||
class MessageParser(callbacks.Plugin, plugins.ChannelDBHandler):
|
||||
"""This plugin can set regexp triggers to activate the bot.
|
||||
Use 'add' command to add regexp trigger, 'remove' to remove."""
|
||||
threaded = True
|
||||
def __init__(self, irc):
|
||||
callbacks.Plugin.__init__(self, irc)
|
||||
plugins.ChannelDBHandler.__init__(self)
|
||||
|
||||
def makeDb(self, filename):
|
||||
"""Create the database and connect to it."""
|
||||
if os.path.exists(filename):
|
||||
db = sqlite3.connect(filename)
|
||||
db.text_factory = str
|
||||
return db
|
||||
db = sqlite3.connect(filename)
|
||||
db.text_factory = str
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""CREATE TABLE triggers (
|
||||
id INTEGER PRIMARY KEY,
|
||||
regexp TEXT UNIQUE ON CONFLICT REPLACE,
|
||||
added_by TEXT,
|
||||
added_at TIMESTAMP,
|
||||
usage_count INTEGER,
|
||||
action TEXT,
|
||||
locked BOOLEAN
|
||||
)""")
|
||||
db.commit()
|
||||
return db
|
||||
|
||||
# override this because sqlite3 doesn't have autocommit
|
||||
# use isolation_level instead.
|
||||
def getDb(self, channel):
|
||||
"""Use this to get a database for a specific channel."""
|
||||
currentThread = threading.currentThread()
|
||||
if channel not in self.dbCache and currentThread == world.mainThread:
|
||||
self.dbCache[channel] = self.makeDb(self.makeFilename(channel))
|
||||
if currentThread != world.mainThread:
|
||||
db = self.makeDb(self.makeFilename(channel))
|
||||
else:
|
||||
db = self.dbCache[channel]
|
||||
db.isolation_level = None
|
||||
return db
|
||||
|
||||
def _updateRank(self, channel, regexp):
|
||||
if self.registryValue('keepRankInfo', channel):
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT usage_count
|
||||
FROM triggers
|
||||
WHERE regexp=?""", (regexp,))
|
||||
old_count = cursor.fetchall()[0][0]
|
||||
cursor.execute("UPDATE triggers SET usage_count=? WHERE regexp=?", (old_count + 1, regexp,))
|
||||
db.commit()
|
||||
|
||||
def _runCommandFunction(self, irc, msg, command):
|
||||
"""Run a command from message, as if command was sent over IRC."""
|
||||
tokens = callbacks.tokenize(command)
|
||||
try:
|
||||
self.Proxy(irc.irc, msg, tokens)
|
||||
except Exception, e:
|
||||
log.exception('Uncaught exception in function called by MessageParser:')
|
||||
|
||||
def _checkManageCapabilities(self, irc, msg, channel):
|
||||
"""Check if the user has any of the required capabilities to manage
|
||||
the regexp database."""
|
||||
capabilities = self.registryValue('requireManageCapability')
|
||||
if capabilities:
|
||||
for capability in re.split(r'\s*;\s*', capabilities):
|
||||
if capability.startswith('channel,'):
|
||||
capability = ircdb.makeChannelCapability(channel, capability[8:])
|
||||
if capability and ircdb.checkCapability(msg.prefix, capability):
|
||||
#print "has capability:", capability
|
||||
return True
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def doPrivmsg(self, irc, msg):
|
||||
channel = msg.args[0]
|
||||
if not irc.isChannel(channel):
|
||||
return
|
||||
if self.registryValue('enable', channel):
|
||||
if callbacks.addressed(irc.nick, msg): #message is direct command
|
||||
return
|
||||
actions = []
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("SELECT regexp, action FROM triggers")
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
return
|
||||
for (regexp, action) in results:
|
||||
for match in re.finditer(regexp, msg.args[1]):
|
||||
if match is not None:
|
||||
thisaction = action
|
||||
self._updateRank(channel, regexp)
|
||||
for (i, j) in enumerate(match.groups()):
|
||||
thisaction = re.sub(r'\$' + str(i+1), match.group(i+1), thisaction)
|
||||
actions.append(thisaction)
|
||||
|
||||
for action in actions:
|
||||
self._runCommandFunction(irc, msg, action)
|
||||
|
||||
@internationalizeDocstring
|
||||
def add(self, irc, msg, args, channel, regexp, action):
|
||||
"""[<channel>] <regexp> <action>
|
||||
|
||||
Associates <regexp> with <action>. <channel> is only
|
||||
necessary if the message isn't sent on the channel
|
||||
itself. Action is echoed upon regexp match, with variables $1, $2,
|
||||
etc. being interpolated from the regexp match groups."""
|
||||
if not self._checkManageCapabilities(irc, msg, channel):
|
||||
capabilities = self.registryValue('requireManageCapability')
|
||||
irc.errorNoCapability(capabilities, Raise=True)
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("SELECT id, usage_count, locked FROM triggers WHERE regexp=?", (regexp,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) != 0:
|
||||
(id, usage_count, locked) = map(int, results[0])
|
||||
else:
|
||||
locked = 0
|
||||
usage_count = 0
|
||||
if not locked:
|
||||
try:
|
||||
re.compile(regexp)
|
||||
except Exception, e:
|
||||
irc.error(_('Invalid python regexp: %s') % (e,))
|
||||
return
|
||||
if ircdb.users.hasUser(msg.prefix):
|
||||
name = ircdb.users.getUser(msg.prefix).name
|
||||
else:
|
||||
name = msg.nick
|
||||
cursor.execute("""INSERT INTO triggers VALUES
|
||||
(NULL, ?, ?, ?, ?, ?, ?)""",
|
||||
(regexp, name, int(time.time()), usage_count, action, locked,))
|
||||
db.commit()
|
||||
irc.replySuccess()
|
||||
else:
|
||||
irc.error(_('That trigger is locked.'))
|
||||
return
|
||||
add = wrap(add, ['channel', 'something', 'something'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def remove(self, irc, msg, args, channel, optlist, regexp):
|
||||
"""[<channel>] [--id] <regexp>]
|
||||
|
||||
Removes the trigger for <regexp> from the triggers database.
|
||||
<channel> is only necessary if
|
||||
the message isn't sent in the channel itself.
|
||||
If option --id specified, will retrieve by regexp id, not content.
|
||||
"""
|
||||
if not self._checkManageCapabilities(irc, msg, channel):
|
||||
capabilities = self.registryValue('requireManageCapability')
|
||||
irc.errorNoCapability(capabilities, Raise=True)
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
target = 'regexp'
|
||||
for (option, arg) in optlist:
|
||||
if option == 'id':
|
||||
target = 'id'
|
||||
sql = "SELECT id, locked FROM triggers WHERE %s=?" % (target,)
|
||||
cursor.execute(sql, (regexp,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) != 0:
|
||||
(id, locked) = map(int, results[0])
|
||||
else:
|
||||
irc.error(_('There is no such regexp trigger.'))
|
||||
return
|
||||
|
||||
if locked:
|
||||
irc.error(_('This regexp trigger is locked.'))
|
||||
return
|
||||
|
||||
cursor.execute("""DELETE FROM triggers WHERE id=?""", (id,))
|
||||
db.commit()
|
||||
irc.replySuccess()
|
||||
remove = wrap(remove, ['channel',
|
||||
getopts({'id': '',}),
|
||||
'something'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def lock(self, irc, msg, args, channel, regexp):
|
||||
"""[<channel>] <regexp>
|
||||
|
||||
Locks the <regexp> so that it cannot be
|
||||
removed or overwritten to. <channel> is only necessary if the message isn't
|
||||
sent in the channel itself.
|
||||
"""
|
||||
if not self._checkManageCapabilities(irc, msg, channel):
|
||||
capabilities = self.registryValue('requireManageCapability')
|
||||
irc.errorNoCapability(capabilities, Raise=True)
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("SELECT id FROM triggers WHERE regexp=?", (regexp,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
irc.error(_('There is no such regexp trigger.'))
|
||||
return
|
||||
cursor.execute("UPDATE triggers SET locked=1 WHERE regexp=?", (regexp,))
|
||||
db.commit()
|
||||
irc.replySuccess()
|
||||
lock = wrap(lock, ['channel', 'text'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def unlock(self, irc, msg, args, channel, regexp):
|
||||
"""[<channel>] <regexp>
|
||||
|
||||
Unlocks the entry associated with <regexp> so that it can be
|
||||
removed or overwritten. <channel> is only necessary if the message isn't
|
||||
sent in the channel itself.
|
||||
"""
|
||||
if not self._checkManageCapabilities(irc, msg, channel):
|
||||
capabilities = self.registryValue('requireManageCapability')
|
||||
irc.errorNoCapability(capabilities, Raise=True)
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("SELECT id FROM triggers WHERE regexp=?", (regexp,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
irc.error(_('There is no such regexp trigger.'))
|
||||
return
|
||||
cursor.execute("UPDATE triggers SET locked=0 WHERE regexp=?", (regexp,))
|
||||
db.commit()
|
||||
irc.replySuccess()
|
||||
unlock = wrap(unlock, ['channel', 'text'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def show(self, irc, msg, args, channel, optlist, regexp):
|
||||
"""[<channel>] [--id] <regexp>
|
||||
|
||||
Looks up the value of <regexp> in the triggers database.
|
||||
<channel> is only necessary if the message isn't sent in the channel
|
||||
itself.
|
||||
If option --id specified, will retrieve by regexp id, not content.
|
||||
"""
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
target = 'regexp'
|
||||
for (option, arg) in optlist:
|
||||
if option == 'id':
|
||||
target = 'id'
|
||||
sql = "SELECT regexp, action FROM triggers WHERE %s=?" % (target,)
|
||||
cursor.execute(sql, (regexp,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) != 0:
|
||||
(regexp, action) = results[0]
|
||||
else:
|
||||
irc.error(_('There is no such regexp trigger.'))
|
||||
return
|
||||
|
||||
irc.reply("The action for regexp trigger \"%s\" is \"%s\"" % (regexp, action))
|
||||
show = wrap(show, ['channel',
|
||||
getopts({'id': '',}),
|
||||
'something'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def info(self, irc, msg, args, channel, optlist, regexp):
|
||||
"""[<channel>] [--id] <regexp>
|
||||
|
||||
Display information about <regexp> in the triggers database.
|
||||
<channel> is only necessary if the message isn't sent in the channel
|
||||
itself.
|
||||
If option --id specified, will retrieve by regexp id, not content.
|
||||
"""
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
target = 'regexp'
|
||||
for (option, arg) in optlist:
|
||||
if option == 'id':
|
||||
target = 'id'
|
||||
sql = "SELECT * FROM triggers WHERE %s=?" % (target,)
|
||||
cursor.execute(sql, (regexp,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) != 0:
|
||||
(id, regexp, added_by, added_at, usage_count,
|
||||
action, locked) = results[0]
|
||||
else:
|
||||
irc.error(_('There is no such regexp trigger.'))
|
||||
return
|
||||
|
||||
irc.reply(_("The regexp id is %d, regexp is \"%s\", and action is"
|
||||
" \"%s\". It was added by user %s on %s, has been "
|
||||
"triggered %d times, and is %s.") % (id,
|
||||
regexp,
|
||||
action,
|
||||
added_by,
|
||||
time.strftime(conf.supybot.reply.format.time(),
|
||||
time.localtime(int(added_at))),
|
||||
usage_count,
|
||||
locked and _("locked") or _("not locked"),))
|
||||
info = wrap(info, ['channel',
|
||||
getopts({'id': '',}),
|
||||
'something'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def list(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
||||
Lists regexps present in the triggers database.
|
||||
<channel> is only necessary if the message isn't sent in the channel
|
||||
itself. Regexp ID listed in paretheses.
|
||||
"""
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("SELECT regexp, id FROM triggers")
|
||||
results = cursor.fetchall()
|
||||
if len(results) != 0:
|
||||
regexps = results
|
||||
else:
|
||||
irc.reply(_('There are no regexp triggers in the database.'))
|
||||
return
|
||||
|
||||
s = [ "\"%s\" (%d)" % (regexp[0], regexp[1]) for regexp in regexps ]
|
||||
separator = self.registryValue('listSeparator', channel)
|
||||
irc.reply(separator.join(s))
|
||||
list = wrap(list, ['channel'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def rank(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
||||
Returns a list of top-ranked regexps, sorted by usage count
|
||||
(rank). The number of regexps returned is set by the
|
||||
rankListLength registry value. <channel> is only necessary if the
|
||||
message isn't sent in the channel itself.
|
||||
"""
|
||||
numregexps = self.registryValue('rankListLength', channel)
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT regexp, usage_count
|
||||
FROM triggers
|
||||
ORDER BY usage_count DESC
|
||||
LIMIT ?""", (numregexps,))
|
||||
regexps = cursor.fetchall()
|
||||
if len(regexps) == 0:
|
||||
irc.reply(_('There are no regexp triggers in the database.'))
|
||||
return
|
||||
s = [ "#%d \"%s\" (%d)" % (i+1, regexp[0], regexp[1]) for i, regexp in enumerate(regexps) ]
|
||||
irc.reply(", ".join(s))
|
||||
rank = wrap(rank, ['channel'])
|
||||
|
||||
@internationalizeDocstring
|
||||
def vacuum(self, irc, msg, args, channel):
|
||||
"""[<channel>]
|
||||
|
||||
Vacuums the database for <channel>.
|
||||
See SQLite vacuum doc here: http://www.sqlite.org/lang_vacuum.html
|
||||
<channel> is only necessary if the message isn't sent in
|
||||
the channel itself.
|
||||
First check if user has the required capability specified in plugin
|
||||
config requireVacuumCapability.
|
||||
"""
|
||||
capability = self.registryValue('requireVacuumCapability')
|
||||
if capability:
|
||||
if not ircdb.checkCapability(msg.prefix, capability):
|
||||
irc.errorNoCapability(capability, Raise=True)
|
||||
db = self.getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""VACUUM""")
|
||||
db.commit()
|
||||
irc.replySuccess()
|
||||
vacuum = wrap(vacuum, ['channel'])
|
||||
MessageParser = internationalizeDocstring(MessageParser)
|
||||
|
||||
Class = MessageParser
|
||||
|
||||
|
||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
|
@ -0,0 +1,174 @@
|
|||
###
|
||||
# Copyright (c) 2010, Daniel Folkinshteyn
|
||||
# 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.
|
||||
|
||||
###
|
||||
|
||||
from supybot.test import *
|
||||
|
||||
try:
|
||||
import sqlite3
|
||||
except ImportError:
|
||||
from pysqlite2 import dbapi2 as sqlite3 # for python2.4
|
||||
|
||||
|
||||
class MessageParserTestCase(ChannelPluginTestCase):
|
||||
plugins = ('MessageParser','Utilities','User')
|
||||
#utilities for the 'echo'
|
||||
#user for register for testVacuum
|
||||
|
||||
def testAdd(self):
|
||||
self.assertError('messageparser add') #no args
|
||||
self.assertError('messageparser add "stuff"') #no action arg
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.assertRegexp('messageparser show "stuff"', '.*i saw some stuff.*')
|
||||
|
||||
self.assertError('messageparser add "[a" "echo stuff"') #invalid regexp
|
||||
self.assertError('messageparser add "(a" "echo stuff"') #invalid regexp
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw no stuff"') #overwrite existing regexp
|
||||
self.assertRegexp('messageparser show "stuff"', '.*i saw no stuff.*')
|
||||
|
||||
|
||||
try:
|
||||
world.testing = False
|
||||
origuser = self.prefix
|
||||
self.prefix = 'stuff!stuff@stuff'
|
||||
self.assertNotError('register nottester stuff', private=True)
|
||||
|
||||
self.assertError('messageparser add "aoeu" "echo vowels are nice"')
|
||||
origconf = conf.supybot.plugins.MessageParser.requireManageCapability()
|
||||
conf.supybot.plugins.MessageParser.requireManageCapability.setValue('')
|
||||
self.assertNotError('messageparser add "aoeu" "echo vowels are nice"')
|
||||
finally:
|
||||
world.testing = True
|
||||
self.prefix = origuser
|
||||
conf.supybot.plugins.MessageParser.requireManageCapability.setValue(origconf)
|
||||
|
||||
def testShow(self):
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.assertRegexp('messageparser show "nostuff"', 'there is no such regexp trigger')
|
||||
self.assertRegexp('messageparser show "stuff"', '.*i saw some stuff.*')
|
||||
self.assertRegexp('messageparser show --id 1', '.*i saw some stuff.*')
|
||||
|
||||
def testInfo(self):
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.assertRegexp('messageparser info "nostuff"', 'there is no such regexp trigger')
|
||||
self.assertRegexp('messageparser info "stuff"', '.*i saw some stuff.*')
|
||||
self.assertRegexp('messageparser info --id 1', '.*i saw some stuff.*')
|
||||
self.assertRegexp('messageparser info "stuff"', 'has been triggered 0 times')
|
||||
self.feedMsg('this message has some stuff in it')
|
||||
self.getMsg(' ')
|
||||
self.assertRegexp('messageparser info "stuff"', 'has been triggered 1 times')
|
||||
|
||||
def testTrigger(self):
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.feedMsg('this message has some stuff in it')
|
||||
m = self.getMsg(' ')
|
||||
self.failUnless(str(m).startswith('PRIVMSG #test :i saw some stuff'))
|
||||
|
||||
def testLock(self):
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.assertNotError('messageparser lock "stuff"')
|
||||
self.assertError('messageparser add "stuff" "echo some other stuff"')
|
||||
self.assertError('messageparser remove "stuff"')
|
||||
self.assertRegexp('messageparser info "stuff"', 'is locked')
|
||||
|
||||
def testUnlock(self):
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.assertNotError('messageparser lock "stuff"')
|
||||
self.assertError('messageparser remove "stuff"')
|
||||
self.assertNotError('messageparser unlock "stuff"')
|
||||
self.assertRegexp('messageparser info "stuff"', 'is not locked')
|
||||
self.assertNotError('messageparser remove "stuff"')
|
||||
|
||||
def testRank(self):
|
||||
self.assertRegexp('messageparser rank',
|
||||
'There are no regexp triggers in the database\.')
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.assertRegexp('messageparser rank', '#1 "stuff" \(0\)')
|
||||
self.assertNotError('messageparser add "aoeu" "echo vowels are nice!"')
|
||||
self.assertRegexp('messageparser rank', '#1 "stuff" \(0\), #2 "aoeu" \(0\)')
|
||||
self.feedMsg('instead of asdf, dvorak has aoeu')
|
||||
self.getMsg(' ')
|
||||
self.assertRegexp('messageparser rank', '#1 "aoeu" \(1\), #2 "stuff" \(0\)')
|
||||
|
||||
def testList(self):
|
||||
self.assertRegexp('messageparser list',
|
||||
'There are no regexp triggers in the database\.')
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.assertRegexp('messageparser list', '"stuff" \(1\)')
|
||||
self.assertNotError('messageparser add "aoeu" "echo vowels are nice!"')
|
||||
self.assertRegexp('messageparser list', '"stuff" \(1\), "aoeu" \(2\)')
|
||||
|
||||
def testRemove(self):
|
||||
self.assertError('messageparser remove "stuff"')
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.assertNotError('messageparser lock "stuff"')
|
||||
self.assertError('messageparser remove "stuff"')
|
||||
self.assertNotError('messageparser unlock "stuff"')
|
||||
self.assertNotError('messageparser remove "stuff"')
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.assertNotError('messageparser remove --id 1')
|
||||
|
||||
def testVacuum(self):
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.assertNotError('messageparser remove "stuff"')
|
||||
self.assertNotError('messageparser vacuum')
|
||||
# disable world.testing since we want new users to not
|
||||
# magically be endowed with the admin capability
|
||||
try:
|
||||
world.testing = False
|
||||
original = self.prefix
|
||||
self.prefix = 'stuff!stuff@stuff'
|
||||
self.assertNotError('register nottester stuff', private=True)
|
||||
self.assertError('messageparser vacuum')
|
||||
|
||||
orig = conf.supybot.plugins.MessageParser.requireVacuumCapability()
|
||||
conf.supybot.plugins.MessageParser.requireVacuumCapability.setValue('')
|
||||
self.assertNotError('messageparser vacuum')
|
||||
finally:
|
||||
world.testing = True
|
||||
self.prefix = original
|
||||
conf.supybot.plugins.MessageParser.requireVacuumCapability.setValue(orig)
|
||||
|
||||
def testKeepRankInfo(self):
|
||||
orig = conf.supybot.plugins.MessageParser.keepRankInfo()
|
||||
|
||||
try:
|
||||
conf.supybot.plugins.MessageParser.keepRankInfo.setValue(False)
|
||||
self.assertNotError('messageparser add "stuff" "echo i saw some stuff"')
|
||||
self.feedMsg('instead of asdf, dvorak has aoeu')
|
||||
self.getMsg(' ')
|
||||
self.assertRegexp('messageparser info "stuff"', 'has been triggered 0 times')
|
||||
finally:
|
||||
conf.supybot.plugins.MessageParser.keepRankInfo.setValue(orig)
|
||||
|
||||
self.feedMsg('this message has some stuff in it')
|
||||
self.getMsg(' ')
|
||||
self.assertRegexp('messageparser info "stuff"', 'has been triggered 1 times')
|
||||
|
||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
|
@ -199,7 +199,7 @@ msgstr ""
|
|||
|
||||
#: plugin.py:373
|
||||
msgid "I couldn't find a message matching that criteria in my history of %s messages."
|
||||
msgstr "Je ne peux trovuer de message correspondant à ce critère dans mon historique de %s messages."
|
||||
msgstr "Je ne peux trouver de message correspondant à ce critère dans mon historique de %s messages."
|
||||
|
||||
#: plugin.py:388
|
||||
msgid ""
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 15:35+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -45,15 +45,15 @@ msgid ""
|
|||
" command"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:81
|
||||
#: plugin.py:80
|
||||
msgid "You've given me %s invalid commands within the last minute; I'm now ignoring you for %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:93
|
||||
#: plugin.py:92
|
||||
msgid "The %q plugin is loaded, but there is no command named %q in it. Try \"list %s\" to see the commands in the %q plugin."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:119
|
||||
#: plugin.py:118
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--private] [<plugin>]\n"
|
||||
|
@ -64,19 +64,19 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:144
|
||||
#: plugin.py:143
|
||||
msgid "There are no private plugins."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:146
|
||||
#: plugin.py:145
|
||||
msgid "There are no public plugins."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:153
|
||||
#: plugin.py:152
|
||||
msgid "That plugin exists, but has no commands. This probably means that it has some configuration variables that can be changed in order to modify its behavior. Try \"config list supybot.plugins.%s\" to see what configuration variables it has."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:164
|
||||
#: plugin.py:163
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<string>\n"
|
||||
|
@ -86,11 +86,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:183
|
||||
#: plugin.py:182
|
||||
msgid "No appropriate commands were found."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:188
|
||||
#: plugin.py:187
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<plugin>] [<command>]\n"
|
||||
|
@ -100,15 +100,15 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:198
|
||||
#: plugin.py:197
|
||||
msgid "That command exists in the %L plugins. Please specify exactly which plugin command you want help with."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:205
|
||||
#: plugin.py:204
|
||||
msgid "There is no command %q."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:211
|
||||
#: plugin.py:210
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
|
@ -117,19 +117,19 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:217
|
||||
#: plugin.py:216
|
||||
msgid "The newest version available online is %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:221
|
||||
#: plugin.py:220
|
||||
msgid "I couldn't fetch the newest version from the Supybot website."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:223
|
||||
#: plugin.py:222
|
||||
msgid "The current (running) version of this Supybot is %s. %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:230
|
||||
#: plugin.py:229
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
|
@ -138,11 +138,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:234
|
||||
#: plugin.py:233
|
||||
msgid "My source is at http://supybot.com/"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:239
|
||||
#: plugin.py:238
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<nick>]\n"
|
||||
|
@ -154,23 +154,31 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:253
|
||||
#: plugin.py:252
|
||||
msgid "%s has no public mores."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:256
|
||||
#: plugin.py:255
|
||||
msgid "Sorry, I can't find any mores for %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:265
|
||||
#: plugin.py:262
|
||||
msgid "more message"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:264
|
||||
msgid "more messages"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:268
|
||||
msgid "You haven't asked me a command; perhaps you want to see someone else's more. To do so, call this command with that person's nick."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:269
|
||||
#: plugin.py:272
|
||||
msgid "That's all, there is no more."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:279
|
||||
#: plugin.py:282
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--{from,in,on,with,without,regexp} <value>] [--nolimit]\n"
|
||||
|
@ -185,11 +193,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:373
|
||||
#: plugin.py:376
|
||||
msgid "I couldn't find a message matching that criteria in my history of %s messages."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:388
|
||||
#: plugin.py:391
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<nick> <text>\n"
|
||||
|
@ -199,23 +207,23 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:396
|
||||
#: plugin.py:399
|
||||
msgid "Dude, just give the command. No need for the tell."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:401
|
||||
#: plugin.py:404
|
||||
msgid "You just told me, why should I tell myself?"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:406
|
||||
#: plugin.py:409
|
||||
msgid "I haven't seen %s, I'll let you do the telling."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:411
|
||||
#: plugin.py:414
|
||||
msgid "%s wants me to tell you: %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:417
|
||||
#: plugin.py:420
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
|
@ -224,7 +232,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:421
|
||||
#: plugin.py:424
|
||||
msgid "pong"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-29 12:02+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -28,38 +28,38 @@ msgid ""
|
|||
" when the 'most' command is called."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:292
|
||||
#: plugin.py:289
|
||||
#, docstring
|
||||
msgid ""
|
||||
"Add the help for \"@help MoobotFactoids\" here (assuming you don't implement a MoobotFactoids\n"
|
||||
" command). This should describe *how* to use this plugin."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:349
|
||||
#: plugin.py:346
|
||||
msgid "%s is %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:368
|
||||
#: plugin.py:365
|
||||
msgid "Factoid %q is locked."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:375
|
||||
#: plugin.py:372
|
||||
msgid "Factoid %q not found."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:385
|
||||
#: plugin.py:382
|
||||
msgid "Missing an 'is' or '_is_'."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:401
|
||||
#: plugin.py:398
|
||||
msgid "Factoid %q already exists."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:435
|
||||
#: plugin.py:432
|
||||
msgid "%s, or %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:456
|
||||
#: plugin.py:453
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <factoid key>\n"
|
||||
|
@ -70,7 +70,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:469
|
||||
#: plugin.py:466
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <factoid key>\n"
|
||||
|
@ -81,39 +81,39 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:480 plugin.py:520
|
||||
#: plugin.py:477 plugin.py:517
|
||||
msgid "No such factoid: %q"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:489
|
||||
#: plugin.py:486
|
||||
msgid "Created by %s on %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:495
|
||||
#: plugin.py:492
|
||||
msgid " Last modified by %s on %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:503
|
||||
#: plugin.py:500
|
||||
msgid " Last requested by %s on %s, requested %n."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:510
|
||||
#: plugin.py:507
|
||||
msgid " Locked by %s on %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:525
|
||||
#: plugin.py:522
|
||||
msgid "Factoid %q is already locked."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:528
|
||||
#: plugin.py:525
|
||||
msgid "Factoid %q is not locked."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:538
|
||||
#: plugin.py:535
|
||||
msgid "Cannot %s someone else's factoid unless you are an admin."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:550
|
||||
#: plugin.py:547
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <factoid key>\n"
|
||||
|
@ -124,7 +124,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:561
|
||||
#: plugin.py:558
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <factoid key>\n"
|
||||
|
@ -135,7 +135,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:572
|
||||
#: plugin.py:569
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] {popular|authored|recent}\n"
|
||||
|
@ -148,51 +148,51 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:594
|
||||
#: plugin.py:591
|
||||
msgid "author"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:596
|
||||
#: plugin.py:593
|
||||
msgid "authors"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:597
|
||||
#: plugin.py:594
|
||||
msgid "Most prolific %s: %L"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:599 plugin.py:611
|
||||
#: plugin.py:596 plugin.py:608
|
||||
msgid "There are no factoids in my database."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:606
|
||||
#: plugin.py:603
|
||||
msgid "latest factoid"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:608
|
||||
#: plugin.py:605
|
||||
msgid "latest factoids"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:609
|
||||
#: plugin.py:606
|
||||
msgid "%s: %L"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:618
|
||||
#: plugin.py:615
|
||||
msgid "requested factoid"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:620
|
||||
#: plugin.py:617
|
||||
msgid "requested factoids"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:621
|
||||
#: plugin.py:618
|
||||
msgid "Top %s: %L"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:623
|
||||
#: plugin.py:620
|
||||
msgid "No factoids have been requested from my database."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:627
|
||||
#: plugin.py:624
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <author name>\n"
|
||||
|
@ -204,15 +204,15 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:640
|
||||
#: plugin.py:637
|
||||
msgid "No factoids by %q found."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:643
|
||||
#: plugin.py:640
|
||||
msgid "Author search for %q (%i found): %L"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:650
|
||||
#: plugin.py:647
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <text>\n"
|
||||
|
@ -223,15 +223,15 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:658
|
||||
#: plugin.py:655
|
||||
msgid "No keys matching %q found."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:665
|
||||
#: plugin.py:662
|
||||
msgid "Key search for %q (%i found): %L"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:672
|
||||
#: plugin.py:669
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <text>\n"
|
||||
|
@ -242,15 +242,15 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:680
|
||||
#: plugin.py:677
|
||||
msgid "No values matching %q found."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:683
|
||||
#: plugin.py:680
|
||||
msgid "Value search for %q (%i found): %L"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:690
|
||||
#: plugin.py:687
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <factoid key>\n"
|
||||
|
@ -260,7 +260,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:703
|
||||
#: plugin.py:700
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
|
@ -271,7 +271,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:711
|
||||
#: plugin.py:708
|
||||
msgid "No factoids in the database."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -100,19 +100,21 @@ class SqliteMoobotDB(object):
|
|||
|
||||
def _getDb(self, channel):
|
||||
try:
|
||||
import sqlite
|
||||
import sqlite3
|
||||
except ImportError:
|
||||
raise callbacks.Error, \
|
||||
'You need to have PySQLite installed to use this ' \
|
||||
'plugin. Download it at ' \
|
||||
'<http://code.google.com/p/pysqlite/>'
|
||||
from pysqlite2 import dbapi2 as sqlite3 # for python2.4
|
||||
|
||||
if channel in self.dbs:
|
||||
return self.dbs[channel]
|
||||
filename = plugins.makeChannelFilename(self.filename, channel)
|
||||
|
||||
if os.path.exists(filename):
|
||||
self.dbs[channel] = sqlite.connect(filename)
|
||||
return self.dbs[channel]
|
||||
db = sqlite.connect(filename)
|
||||
db = sqlite3.connect(filename)
|
||||
db.text_factory = str
|
||||
self.dbs[channel] = db
|
||||
return db
|
||||
db = sqlite3.connect(filename)
|
||||
db.text_factory = str
|
||||
self.dbs[channel] = db
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""CREATE TABLE factoids (
|
||||
|
@ -135,11 +137,12 @@ class SqliteMoobotDB(object):
|
|||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT fact FROM factoids
|
||||
WHERE key LIKE %s""", key)
|
||||
if cursor.rowcount == 0:
|
||||
WHERE key LIKE ?""", (key,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
return None
|
||||
else:
|
||||
return cursor.fetchall()[0]
|
||||
return results[0]
|
||||
|
||||
def getFactinfo(self, channel, key):
|
||||
db = self._getDb(channel)
|
||||
|
@ -149,63 +152,65 @@ class SqliteMoobotDB(object):
|
|||
last_requested_by, last_requested_at,
|
||||
requested_count, locked_by, locked_at
|
||||
FROM factoids
|
||||
WHERE key LIKE %s""", key)
|
||||
if cursor.rowcount == 0:
|
||||
WHERE key LIKE ?""", (key,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
return None
|
||||
else:
|
||||
return cursor.fetchone()
|
||||
return results[0]
|
||||
|
||||
def randomFactoid(self, channel):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT fact, key FROM factoids
|
||||
ORDER BY random() LIMIT 1""")
|
||||
if cursor.rowcount == 0:
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
return None
|
||||
else:
|
||||
return cursor.fetchone()
|
||||
return results[0]
|
||||
|
||||
def addFactoid(self, channel, key, value, creator_id):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""INSERT INTO factoids VALUES
|
||||
(%s, %s, %s, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, %s, 0)""",
|
||||
key, creator_id, int(time.time()), value)
|
||||
(?, ?, ?, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, ?, 0)""",
|
||||
(key, creator_id, int(time.time()), value))
|
||||
db.commit()
|
||||
|
||||
def updateFactoid(self, channel, key, newvalue, modifier_id):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""UPDATE factoids
|
||||
SET fact=%s, modified_by=%s,
|
||||
modified_at=%s WHERE key LIKE %s""",
|
||||
newvalue, modifier_id, int(time.time()), key)
|
||||
SET fact=?, modified_by=?,
|
||||
modified_at=? WHERE key LIKE ?""",
|
||||
(newvalue, modifier_id, int(time.time()), key))
|
||||
db.commit()
|
||||
|
||||
def updateRequest(self, channel, key, hostmask):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""UPDATE factoids SET
|
||||
last_requested_by = %s,
|
||||
last_requested_at = %s,
|
||||
last_requested_by = ?,
|
||||
last_requested_at = ?,
|
||||
requested_count = requested_count + 1
|
||||
WHERE key = %s""",
|
||||
hostmask, int(time.time()), key)
|
||||
WHERE key = ?""",
|
||||
(hostmask, int(time.time()), key))
|
||||
db.commit()
|
||||
|
||||
def removeFactoid(self, channel, key):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""DELETE FROM factoids WHERE key LIKE %s""",
|
||||
key)
|
||||
cursor.execute("""DELETE FROM factoids WHERE key LIKE ?""",
|
||||
(key,))
|
||||
db.commit()
|
||||
|
||||
def locked(self, channel, key):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute ("""SELECT locked_by FROM factoids
|
||||
WHERE key LIKE %s""", key)
|
||||
WHERE key LIKE ?""", (key,))
|
||||
if cursor.fetchone()[0] is None:
|
||||
return False
|
||||
else:
|
||||
|
@ -215,17 +220,17 @@ class SqliteMoobotDB(object):
|
|||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""UPDATE factoids
|
||||
SET locked_by=%s, locked_at=%s
|
||||
WHERE key LIKE %s""",
|
||||
locker_id, int(time.time()), key)
|
||||
SET locked_by=?, locked_at=?
|
||||
WHERE key LIKE ?""",
|
||||
(locker_id, int(time.time()), key))
|
||||
db.commit()
|
||||
|
||||
def unlock(self, channel, key):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""UPDATE factoids
|
||||
SET locked_by=%s, locked_at=%s
|
||||
WHERE key LIKE %s""", None, None, key)
|
||||
SET locked_by=?, locked_at=?
|
||||
WHERE key LIKE ?""", (None, None, key))
|
||||
db.commit()
|
||||
|
||||
def mostAuthored(self, channel, limit):
|
||||
|
@ -233,14 +238,14 @@ class SqliteMoobotDB(object):
|
|||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT created_by, count(key) FROM factoids
|
||||
GROUP BY created_by
|
||||
ORDER BY count(key) DESC LIMIT %s""", limit)
|
||||
ORDER BY count(key) DESC LIMIT ?""", (limit,))
|
||||
return cursor.fetchall()
|
||||
|
||||
def mostRecent(self, channel, limit):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT key FROM factoids
|
||||
ORDER BY created_at DESC LIMIT %s""", limit)
|
||||
ORDER BY created_at DESC LIMIT ?""", (limit,))
|
||||
return cursor.fetchall()
|
||||
|
||||
def mostPopular(self, channel, limit):
|
||||
|
@ -248,43 +253,35 @@ class SqliteMoobotDB(object):
|
|||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT key, requested_count FROM factoids
|
||||
WHERE requested_count > 0
|
||||
ORDER BY requested_count DESC LIMIT %s""", limit)
|
||||
if cursor.rowcount == 0:
|
||||
return []
|
||||
else:
|
||||
return cursor.fetchall()
|
||||
ORDER BY requested_count DESC LIMIT ?""", (limit,))
|
||||
results = cursor.fetchall()
|
||||
return results
|
||||
|
||||
def getKeysByAuthor(self, channel, authorId):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT key FROM factoids WHERE created_by=%s
|
||||
ORDER BY key""", authorId)
|
||||
if cursor.rowcount == 0:
|
||||
return []
|
||||
else:
|
||||
return cursor.fetchall()
|
||||
cursor.execute("""SELECT key FROM factoids WHERE created_by=?
|
||||
ORDER BY key""", (authorId,))
|
||||
results = cursor.fetchall()
|
||||
return results
|
||||
|
||||
def getKeysByGlob(self, channel, glob):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
glob = '%%%s%%' % glob
|
||||
cursor.execute("""SELECT key FROM factoids WHERE key LIKE %s
|
||||
ORDER BY key""", glob)
|
||||
if cursor.rowcount == 0:
|
||||
return []
|
||||
else:
|
||||
return cursor.fetchall()
|
||||
cursor.execute("""SELECT key FROM factoids WHERE key LIKE ?
|
||||
ORDER BY key""", (glob,))
|
||||
results = cursor.fetchall()
|
||||
return results
|
||||
|
||||
def getKeysByValueGlob(self, channel, glob):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
glob = '%%%s%%' % glob
|
||||
cursor.execute("""SELECT key FROM factoids WHERE fact LIKE %s
|
||||
ORDER BY key""", glob)
|
||||
if cursor.rowcount == 0:
|
||||
return []
|
||||
else:
|
||||
return cursor.fetchall()
|
||||
cursor.execute("""SELECT key FROM factoids WHERE fact LIKE ?
|
||||
ORDER BY key""", (glob,))
|
||||
results = cursor.fetchall()
|
||||
return results
|
||||
|
||||
MoobotDB = plugins.DB('MoobotFactoids', {'sqlite': SqliteMoobotDB})
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-16 12:52+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 16:53+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 16:58+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -27,7 +27,7 @@ msgid ""
|
|||
" will check whether its nick ISON."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:41
|
||||
#: plugin.py:40
|
||||
#, docstring
|
||||
msgid ""
|
||||
"This module constantly tries to take whatever nick is configured as\n"
|
||||
|
@ -35,7 +35,7 @@ msgid ""
|
|||
" will do the rest."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:90
|
||||
#: plugin.py:89
|
||||
#, docstring
|
||||
msgid "This is returned by the ISON command."
|
||||
msgstr ""
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 18:28+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-29 13:54+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -15,7 +15,7 @@ msgstr ""
|
|||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: plugin.py:179
|
||||
#: plugin.py:181
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<recipient>,[<recipient>,[...]] <text>\n"
|
||||
|
@ -25,7 +25,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:195
|
||||
#: plugin.py:197
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<id> <text>\n"
|
||||
|
@ -34,7 +34,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:219
|
||||
#: plugin.py:221
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<id>\n"
|
||||
|
@ -44,7 +44,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:251
|
||||
#: plugin.py:253
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<id>\n"
|
||||
|
@ -54,7 +54,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:281
|
||||
#: plugin.py:283
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--{regexp} <value>] [--sent] [<glob>]\n"
|
||||
|
@ -65,7 +65,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:320
|
||||
#: plugin.py:322
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--{old,sent}] [--{from,to} <user>]\n"
|
||||
|
@ -77,7 +77,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:361
|
||||
#: plugin.py:363
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-29 14:47+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -15,7 +15,7 @@ msgstr ""
|
|||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: plugin.py:270
|
||||
#: plugin.py:273
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -25,7 +25,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:280
|
||||
#: plugin.py:283
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<text>\n"
|
||||
|
@ -35,7 +35,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:295
|
||||
#: plugin.py:298
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--remove] <command> [<plugin>]\n"
|
||||
|
@ -47,7 +47,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:333
|
||||
#: plugin.py:336
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<string to be sent to the server>\n"
|
||||
|
@ -56,7 +56,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:347
|
||||
#: plugin.py:350
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<text>]\n"
|
||||
|
@ -67,7 +67,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:363
|
||||
#: plugin.py:366
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
|
@ -77,7 +77,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:373
|
||||
#: plugin.py:376
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<level>]\n"
|
||||
|
@ -89,7 +89,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:412
|
||||
#: plugin.py:415
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[--deprecated] <plugin>\n"
|
||||
|
@ -101,7 +101,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:447
|
||||
#: plugin.py:450
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<plugin>\n"
|
||||
|
@ -111,7 +111,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:476
|
||||
#: plugin.py:479
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<plugin>\n"
|
||||
|
@ -122,7 +122,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:500
|
||||
#: plugin.py:503
|
||||
#, docstring
|
||||
msgid ""
|
||||
"{add|remove} <capability>\n"
|
||||
|
@ -133,7 +133,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:525
|
||||
#: plugin.py:528
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<plugin>] <command>\n"
|
||||
|
@ -146,7 +146,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:552
|
||||
#: plugin.py:555
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<plugin>] <command>\n"
|
||||
|
@ -157,7 +157,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:571
|
||||
#: plugin.py:574
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<plugin> <command> <new name>\n"
|
||||
|
@ -166,7 +166,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:588
|
||||
#: plugin.py:591
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<plugin>\n"
|
||||
|
@ -176,3 +176,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:604
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no argument\n"
|
||||
"\n"
|
||||
" Reloads the locale of the bot."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -435,7 +435,7 @@ class Owner(callbacks.Plugin):
|
|||
'to force it to load.' % name.capitalize())
|
||||
return
|
||||
except ImportError, e:
|
||||
if name in str(e):
|
||||
if str(e).endswith(' ' + name):
|
||||
irc.error('No plugin named %s exists.' % utils.str.dqrepr(name))
|
||||
else:
|
||||
irc.error(str(e))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot-fr\n"
|
||||
"POT-Creation-Date: 2010-10-16 13:50+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
|
@ -13,7 +13,7 @@ msgstr ""
|
|||
"X-Poedit-Country: France\n"
|
||||
"X-Poedit-SourceCharset: ASCII\n"
|
||||
|
||||
#: plugin.py:43
|
||||
#: plugin.py:42
|
||||
msgid ""
|
||||
"This plugin exists to help users manage their plugins. Use 'plugin\n"
|
||||
" list' to list the loaded plugins; use 'plugin help' to get the description\n"
|
||||
|
@ -21,7 +21,7 @@ msgid ""
|
|||
" command exists in."
|
||||
msgstr "Ce plugin existe pour aider les utilisateurs à gérer leurs plugins. Utilisez 'list' pour liser les plugins chargés ; utilisez 'help' pour avoir de l'aide quant à d'autres plugins ; utilisez la commande 'plugin' elle-même pour déterminer dans quel plugin une commande existe."
|
||||
|
||||
#: plugin.py:49
|
||||
#: plugin.py:48
|
||||
msgid ""
|
||||
"<plugin>\n"
|
||||
"\n"
|
||||
|
@ -33,11 +33,11 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne une description utile de comment utiliser le <plugin>, si le plugin en a une."
|
||||
|
||||
#: plugin.py:58
|
||||
#: plugin.py:57
|
||||
msgid "That plugin is loaded, but has no plugin help."
|
||||
msgstr "Ce plugin est chargé mais n'a pas d'aide."
|
||||
|
||||
#: plugin.py:63
|
||||
#: plugin.py:62
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
"\n"
|
||||
|
@ -48,34 +48,48 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne une liste des plugins actuellement chargés."
|
||||
|
||||
#: plugin.py:74
|
||||
#: plugin.py:73
|
||||
msgid ""
|
||||
"<command>\n"
|
||||
"\n"
|
||||
" Returns the plugin(s) that <command> is in.\n"
|
||||
" Returns the name of the plugin that would be used to call <command>.\n"
|
||||
" \n"
|
||||
" If it is not uniquely determined, returns list of all plugins that\n"
|
||||
" contain <command>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<commande>\n"
|
||||
"\n"
|
||||
"Retourne le(s) plugin(s) ayant la <commande>."
|
||||
"Retourne le nom du plugin qui serait utilisé pour appeller la <commande>.Si il ne peut être déterminé (c'est à dire s'il y a un conflit, sans plugin par défaut), la liste de tous les plugins contenant cette commande sera renvoyée."
|
||||
|
||||
#: plugin.py:89
|
||||
#: plugin.py:91
|
||||
msgid "plugins"
|
||||
msgstr "plugins"
|
||||
|
||||
#: plugin.py:91
|
||||
#: plugin.py:93
|
||||
msgid "plugin"
|
||||
msgstr "plugin"
|
||||
|
||||
#: plugin.py:92
|
||||
#: plugin.py:94
|
||||
msgid "The %q command is available in the %L %s."
|
||||
msgstr "La commande %q est disponibles dans le(s) plugin(s) %L%v."
|
||||
|
||||
#: plugin.py:95
|
||||
#: plugin.py:97
|
||||
msgid "There is no command %q."
|
||||
msgstr "Il n'y a pas de commande %q."
|
||||
|
||||
#: plugin.py:100
|
||||
#: plugin.py:113
|
||||
msgid ""
|
||||
"<command>\n"
|
||||
"\n"
|
||||
" Returns the names of all plugins that contain <command>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<commande>\n"
|
||||
"\n"
|
||||
"Retourne les noms de tous les plugins contenant la <commande>."
|
||||
|
||||
#: plugin.py:135
|
||||
msgid ""
|
||||
"<plugin>\n"
|
||||
"\n"
|
||||
|
@ -87,15 +101,15 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne l'auteur du <plugin>. C'est la personne à qui vous devriez parler si vous avez des idées, suggestions, ou d'autres commentaires à propos d'un plugin donné."
|
||||
|
||||
#: plugin.py:106
|
||||
#: plugin.py:141
|
||||
msgid "That plugin does not seem to be loaded."
|
||||
msgstr "Ce plugin ne semble pas être chargé."
|
||||
|
||||
#: plugin.py:112
|
||||
#: plugin.py:147
|
||||
msgid "That plugin doesn't have an author that claims it."
|
||||
msgstr "Ce plugin n'a pas d'auteur."
|
||||
|
||||
#: plugin.py:117
|
||||
#: plugin.py:152
|
||||
msgid ""
|
||||
"<plugin> [<nick>]\n"
|
||||
"\n"
|
||||
|
@ -109,7 +123,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Renvoie une liste des personnes ayant contribué à un plugin donné. Si le <nick> est spécifié, les contributions de cette personne seront lisées. Note : <nick> est la partie entre parenthèses lors du listing des personnes."
|
||||
|
||||
#: plugin.py:125
|
||||
#: plugin.py:160
|
||||
msgid ""
|
||||
"\n"
|
||||
" Take an Authors object, and return only the name and nick values\n"
|
||||
|
@ -117,7 +131,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:131
|
||||
#: plugin.py:166
|
||||
msgid ""
|
||||
"\n"
|
||||
" Take a list of long names and turn it into :\n"
|
||||
|
@ -125,7 +139,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:138
|
||||
#: plugin.py:173
|
||||
msgid ""
|
||||
"\n"
|
||||
" Sort the list of 'long names' based on the number of contributions\n"
|
||||
|
@ -133,7 +147,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:148
|
||||
#: plugin.py:183
|
||||
msgid ""
|
||||
"\n"
|
||||
" Build the list of author + contributors (if any) for the requested\n"
|
||||
|
@ -141,39 +155,39 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:152
|
||||
#: plugin.py:187
|
||||
msgid "The %s plugin"
|
||||
msgstr "Le plugin s"
|
||||
|
||||
#: plugin.py:153
|
||||
#: plugin.py:188
|
||||
msgid "has not been claimed by an author"
|
||||
msgstr "n'a aucun auteur"
|
||||
|
||||
#: plugin.py:154
|
||||
#: plugin.py:189
|
||||
msgid "and"
|
||||
msgstr "et"
|
||||
|
||||
#: plugin.py:155
|
||||
#: plugin.py:190
|
||||
msgid "has no contributors listed."
|
||||
msgstr "n'a pas de contributeur listé."
|
||||
|
||||
#: plugin.py:160
|
||||
#: plugin.py:195
|
||||
msgid "was written by %s"
|
||||
msgstr "a été écrit par %s"
|
||||
|
||||
#: plugin.py:171
|
||||
#: plugin.py:206
|
||||
msgid "%s %h contributed to it."
|
||||
msgstr "%s y %h contribué."
|
||||
|
||||
#: plugin.py:176
|
||||
#: plugin.py:211
|
||||
msgid "has no additional contributors listed."
|
||||
msgstr "n'a pas d'autre contributeur listé."
|
||||
|
||||
#: plugin.py:178
|
||||
#: plugin.py:213
|
||||
msgid "but"
|
||||
msgstr "mais"
|
||||
|
||||
#: plugin.py:181
|
||||
#: plugin.py:216
|
||||
msgid ""
|
||||
"\n"
|
||||
" Build the list of contributions (if any) for the requested person\n"
|
||||
|
@ -181,39 +195,39 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:195
|
||||
#: plugin.py:230
|
||||
msgid "The nick specified (%s) is not a registered contributor."
|
||||
msgstr "Le nick spécifié(%s) n'est pas un contributeur enregistré."
|
||||
|
||||
#: plugin.py:201
|
||||
#: plugin.py:236
|
||||
msgid "The %s plugin does not have '%s' listed as a contributor."
|
||||
msgstr "Le plugin %s n'a pas '%s' listé comme contributeur."
|
||||
|
||||
#: plugin.py:209
|
||||
#: plugin.py:244
|
||||
msgid "command"
|
||||
msgstr "commande"
|
||||
|
||||
#: plugin.py:212
|
||||
#: plugin.py:247
|
||||
msgid "the %L %s"
|
||||
msgstr "La/les commande(s) %L%v"
|
||||
|
||||
#: plugin.py:214
|
||||
#: plugin.py:249
|
||||
msgid "the %L"
|
||||
msgstr "La/les %L"
|
||||
|
||||
#: plugin.py:217
|
||||
#: plugin.py:252
|
||||
msgid "%s wrote the %s plugin and also contributed %L."
|
||||
msgstr "%s a écrit le plugin %s et a aussi contribué à %L"
|
||||
|
||||
#: plugin.py:220
|
||||
#: plugin.py:255
|
||||
msgid "%s contributed %L to the %s plugin."
|
||||
msgstr "%s a contribué à %L et au plugin %s"
|
||||
|
||||
#: plugin.py:223
|
||||
#: plugin.py:258
|
||||
msgid "%s wrote the %s plugin"
|
||||
msgstr "%s a écrit le plugin %s"
|
||||
|
||||
#: plugin.py:226
|
||||
#: plugin.py:261
|
||||
msgid "%s has no listed contributions for the %s plugin."
|
||||
msgstr "%s n'a pas de contribution listée pour le plugin %s."
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-16 13:50+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -15,7 +15,7 @@ msgstr ""
|
|||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: plugin.py:43
|
||||
#: plugin.py:42
|
||||
#, docstring
|
||||
msgid ""
|
||||
"This plugin exists to help users manage their plugins. Use 'plugin\n"
|
||||
|
@ -24,7 +24,7 @@ msgid ""
|
|||
" command exists in."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:49
|
||||
#: plugin.py:48
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<plugin>\n"
|
||||
|
@ -34,11 +34,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:58
|
||||
#: plugin.py:57
|
||||
msgid "That plugin is loaded, but has no plugin help."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:63
|
||||
#: plugin.py:62
|
||||
#, docstring
|
||||
msgid ""
|
||||
"takes no arguments\n"
|
||||
|
@ -47,32 +47,44 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:74
|
||||
#: plugin.py:73
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<command>\n"
|
||||
"\n"
|
||||
" Returns the plugin(s) that <command> is in.\n"
|
||||
" Returns the name of the plugin that would be used to call <command>.\n"
|
||||
" \n"
|
||||
" If it is not uniquely determined, returns list of all plugins that\n"
|
||||
" contain <command>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:89
|
||||
#: plugin.py:91
|
||||
msgid "plugins"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:91
|
||||
#: plugin.py:93
|
||||
msgid "plugin"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:92
|
||||
#: plugin.py:94
|
||||
msgid "The %q command is available in the %L %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:95
|
||||
#: plugin.py:97
|
||||
msgid "There is no command %q."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:100
|
||||
#: plugin.py:113
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<command>\n"
|
||||
"\n"
|
||||
" Returns the names of all plugins that contain <command>.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:135
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<plugin>\n"
|
||||
|
@ -82,15 +94,15 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:106
|
||||
#: plugin.py:141
|
||||
msgid "That plugin does not seem to be loaded."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:112
|
||||
#: plugin.py:147
|
||||
msgid "That plugin doesn't have an author that claims it."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:117
|
||||
#: plugin.py:152
|
||||
#, docstring
|
||||
msgid ""
|
||||
"<plugin> [<nick>]\n"
|
||||
|
@ -102,7 +114,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:125
|
||||
#: plugin.py:160
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
|
@ -111,7 +123,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:131
|
||||
#: plugin.py:166
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
|
@ -120,7 +132,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:138
|
||||
#: plugin.py:173
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
|
@ -129,7 +141,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:148
|
||||
#: plugin.py:183
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
|
@ -138,39 +150,39 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:152
|
||||
#: plugin.py:187
|
||||
msgid "The %s plugin"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:153
|
||||
#: plugin.py:188
|
||||
msgid "has not been claimed by an author"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:154
|
||||
#: plugin.py:189
|
||||
msgid "and"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:155
|
||||
#: plugin.py:190
|
||||
msgid "has no contributors listed."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:160
|
||||
#: plugin.py:195
|
||||
msgid "was written by %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:171
|
||||
#: plugin.py:206
|
||||
msgid "%s %h contributed to it."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:176
|
||||
#: plugin.py:211
|
||||
msgid "has no additional contributors listed."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:178
|
||||
#: plugin.py:213
|
||||
msgid "but"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:181
|
||||
#: plugin.py:216
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
|
@ -179,39 +191,39 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:195
|
||||
#: plugin.py:230
|
||||
msgid "The nick specified (%s) is not a registered contributor."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:201
|
||||
#: plugin.py:236
|
||||
msgid "The %s plugin does not have '%s' listed as a contributor."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:209
|
||||
#: plugin.py:244
|
||||
msgid "command"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:212
|
||||
#: plugin.py:247
|
||||
msgid "the %L %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:214
|
||||
#: plugin.py:249
|
||||
msgid "the %L"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:217
|
||||
#: plugin.py:252
|
||||
msgid "%s wrote the %s plugin and also contributed %L."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:220
|
||||
#: plugin.py:255
|
||||
msgid "%s contributed %L to the %s plugin."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:223
|
||||
#: plugin.py:258
|
||||
msgid "%s wrote the %s plugin"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:226
|
||||
#: plugin.py:261
|
||||
msgid "%s has no listed contributions for the %s plugin."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -72,7 +72,10 @@ class Plugin(callbacks.Plugin):
|
|||
def plugin(self, irc, msg, args, command):
|
||||
"""<command>
|
||||
|
||||
Returns the plugin(s) that <command> is in.
|
||||
Returns the name of the plugin that would be used to call <command>.
|
||||
|
||||
If it is not uniquely determined, returns list of all plugins that
|
||||
contain <command>.
|
||||
"""
|
||||
(maxL, cbs) = irc.findCallbacksForArgs(command)
|
||||
L = []
|
||||
|
@ -94,7 +97,39 @@ class Plugin(callbacks.Plugin):
|
|||
irc.error(format(_('There is no command %q.'), command))
|
||||
plugin = wrap(plugin, [many('something')])
|
||||
|
||||
def _findCallbacks(self, irc, command):
|
||||
command = map(callbacks.canonicalName, command)
|
||||
plugin_list = []
|
||||
for cb in irc.callbacks:
|
||||
if not hasattr(cb, 'getCommand'):
|
||||
continue
|
||||
commandlist = cb.getCommand(command)
|
||||
if commandlist:
|
||||
plugin_list.append(cb.name())
|
||||
return plugin_list
|
||||
|
||||
@internationalizeDocstring
|
||||
def plugins(self, irc, msg, args, command):
|
||||
"""<command>
|
||||
|
||||
Returns the names of all plugins that contain <command>.
|
||||
"""
|
||||
L = self._findCallbacks(irc, command)
|
||||
command = callbacks.formatCommand(command)
|
||||
if L:
|
||||
if irc.nested:
|
||||
irc.reply(format('%L', L))
|
||||
else:
|
||||
if len(L) > 1:
|
||||
plugin = 'plugins'
|
||||
else:
|
||||
plugin = 'plugin'
|
||||
irc.reply(format('The %q command is available in the %L %s.',
|
||||
command, L, plugin))
|
||||
else:
|
||||
irc.error(format('There is no command %q.', command))
|
||||
plugins = wrap(plugins, [many('something')])
|
||||
|
||||
def author(self, irc, msg, args, cb):
|
||||
"""<plugin>
|
||||
|
||||
|
|
|
@ -30,11 +30,15 @@
|
|||
from supybot.test import *
|
||||
|
||||
class PluginTestCase(PluginTestCase):
|
||||
plugins = ('Plugin', 'Utilities')
|
||||
plugins = ('Plugin', 'Utilities', 'Admin', 'Format')
|
||||
def testPlugin(self):
|
||||
self.assertRegexp('plugin plugin', 'available.*Plugin plugin')
|
||||
self.assertResponse('echo [plugin plugin]', 'Plugin')
|
||||
|
||||
def testPlugins(self):
|
||||
self.assertRegexp('plugins join', '(Format.*Admin|Admin.*Format)')
|
||||
self.assertRegexp('plugins plugin', 'Plugin')
|
||||
|
||||
def testList(self):
|
||||
self.assertRegexp('plugin list', 'Plugin.*Utilities')
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 18:33+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -21,7 +21,7 @@ msgid ""
|
|||
" a praise when the praise is given."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:40
|
||||
#: plugin.py:39
|
||||
#, docstring
|
||||
msgid ""
|
||||
"Praise is a plugin for ... well, praising things. Feel free to add\n"
|
||||
|
@ -31,11 +31,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:54
|
||||
#: plugin.py:53
|
||||
msgid "Praises must contain $who."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:58
|
||||
#: plugin.py:57
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] [<id>] <who|what> [for <reason>]\n"
|
||||
|
@ -46,15 +46,15 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:74
|
||||
#: plugin.py:73
|
||||
msgid "There is no praise with id #%i."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:79
|
||||
#: plugin.py:78
|
||||
msgid "There are no praises in my database for %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:87
|
||||
#: plugin.py:86
|
||||
msgid " for "
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 18:34+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 18:34+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2010-10-17 18:36+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\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"
|
||||
|
@ -44,16 +44,16 @@ msgid ""
|
|||
" random grabbing."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:57
|
||||
#: plugin.py:66
|
||||
msgid "%s (Said by: %s; grabbed by %s at %t)"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:210
|
||||
#: plugin.py:226
|
||||
#, docstring
|
||||
msgid "Add the help for \"@help QuoteGrabs\" here."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:249
|
||||
#: plugin.py:265
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <nick>\n"
|
||||
|
@ -64,15 +64,15 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:262
|
||||
#: plugin.py:278
|
||||
msgid "You can't quote grab yourself."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:269
|
||||
#: plugin.py:285
|
||||
msgid "I couldn't find a proper message to grab."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:274
|
||||
#: plugin.py:290
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <number>\n"
|
||||
|
@ -83,15 +83,15 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:285
|
||||
#: plugin.py:301
|
||||
msgid "Nothing to ungrab."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:287
|
||||
#: plugin.py:303
|
||||
msgid "Invalid grab number."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:292
|
||||
#: plugin.py:308
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <nick>\n"
|
||||
|
@ -101,11 +101,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:300
|
||||
#: plugin.py:316
|
||||
msgid "I couldn't find a matching quotegrab for %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:306
|
||||
#: plugin.py:322
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <nick>\n"
|
||||
|
@ -117,11 +117,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:323
|
||||
#: plugin.py:339
|
||||
msgid "I couldn't find any quotegrabs for %s."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:329
|
||||
#: plugin.py:345
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] [<nick>]\n"
|
||||
|
@ -132,15 +132,15 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:339
|
||||
#: plugin.py:355
|
||||
msgid "Couldn't get a random quote for that nick."
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:341
|
||||
#: plugin.py:357
|
||||
msgid "Couldn't get a random quote. Are there any grabbed quotes in the database?"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:347
|
||||
#: plugin.py:363
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <id>\n"
|
||||
|
@ -150,11 +150,11 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:355
|
||||
#: plugin.py:371
|
||||
msgid "No quotegrab for id %s"
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:361
|
||||
#: plugin.py:377
|
||||
#, docstring
|
||||
msgid ""
|
||||
"[<channel>] <text>\n"
|
||||
|
@ -164,7 +164,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
|
||||
#: plugin.py:376
|
||||
#: plugin.py:392
|
||||
msgid "No quotegrabs matching %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -43,6 +43,15 @@ import supybot.callbacks as callbacks
|
|||
from supybot.i18n import PluginInternationalization, internationalizeDocstring
|
||||
_ = PluginInternationalization('QuoteGrabs')
|
||||
|
||||
try:
|
||||
import sqlite3
|
||||
except ImportError:
|
||||
from pysqlite2 import dbapi2 as sqlite3 # for python2.4
|
||||
|
||||
import traceback
|
||||
|
||||
#sqlite3.register_converter('bool', bool)
|
||||
|
||||
class QuoteGrabsRecord(dbi.Record):
|
||||
__fields__ = [
|
||||
'by',
|
||||
|
@ -67,29 +76,27 @@ class SqliteQuoteGrabsDB(object):
|
|||
db.close()
|
||||
|
||||
def _getDb(self, channel):
|
||||
try:
|
||||
import sqlite
|
||||
except ImportError:
|
||||
raise callbacks.Error, 'You need to have PySQLite installed to ' \
|
||||
'use QuoteGrabs. Download it at ' \
|
||||
'<http://code.google.com/p/pysqlite/>'
|
||||
filename = plugins.makeChannelFilename(self.filename, channel)
|
||||
def p(s1, s2):
|
||||
return int(ircutils.nickEqual(s1, s2))
|
||||
# text_factory seems to only apply as an output adapter,
|
||||
# so doesn't apply to created functions; so we use str()
|
||||
return ircutils.nickEqual(str(s1), str(s2))
|
||||
if filename in self.dbs:
|
||||
return self.dbs[filename]
|
||||
if os.path.exists(filename):
|
||||
self.dbs[filename] = sqlite.connect(filename,
|
||||
converters={'bool': bool})
|
||||
self.dbs[filename].create_function('nickeq', 2, p)
|
||||
return self.dbs[filename]
|
||||
db = sqlite.connect(filename, converters={'bool': bool})
|
||||
db = sqlite3.connect(filename)
|
||||
db.text_factory = str
|
||||
db.create_function('nickeq', 2, p)
|
||||
self.dbs[filename] = db
|
||||
return db
|
||||
db = sqlite3.connect(filename)
|
||||
db.text_factory = str
|
||||
db.create_function('nickeq', 2, p)
|
||||
self.dbs[filename] = db
|
||||
self.dbs[filename].create_function('nickeq', 2, p)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""CREATE TABLE quotegrabs (
|
||||
id INTEGER PRIMARY KEY,
|
||||
nick TEXT,
|
||||
nick BLOB,
|
||||
hostmask TEXT,
|
||||
added_by TEXT,
|
||||
added_at TIMESTAMP,
|
||||
|
@ -102,10 +109,11 @@ class SqliteQuoteGrabsDB(object):
|
|||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT id, nick, quote, hostmask, added_at, added_by
|
||||
FROM quotegrabs WHERE id = %s""", id)
|
||||
if cursor.rowcount == 0:
|
||||
FROM quotegrabs WHERE id = ?""", (id,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
raise dbi.NoRecordError
|
||||
(id, by, quote, hostmask, at, grabber) = cursor.fetchone()
|
||||
(id, by, quote, hostmask, at, grabber) = results[0]
|
||||
return QuoteGrabsRecord(id, by=by, text=quote, hostmask=hostmask,
|
||||
at=int(at), grabber=grabber)
|
||||
|
||||
|
@ -114,46 +122,50 @@ class SqliteQuoteGrabsDB(object):
|
|||
cursor = db.cursor()
|
||||
if nick:
|
||||
cursor.execute("""SELECT quote FROM quotegrabs
|
||||
WHERE nickeq(nick, %s)
|
||||
WHERE nickeq(nick, ?)
|
||||
ORDER BY random() LIMIT 1""",
|
||||
nick)
|
||||
(nick,))
|
||||
else:
|
||||
cursor.execute("""SELECT quote FROM quotegrabs
|
||||
ORDER BY random() LIMIT 1""")
|
||||
if cursor.rowcount == 0:
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
raise dbi.NoRecordError
|
||||
return cursor.fetchone()[0]
|
||||
return results[0][0]
|
||||
|
||||
def list(self, channel, nick):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT id, quote FROM quotegrabs
|
||||
WHERE nickeq(nick, %s)
|
||||
ORDER BY id DESC""", nick)
|
||||
if cursor.rowcount == 0:
|
||||
WHERE nickeq(nick, ?)
|
||||
ORDER BY id DESC""", (nick,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
raise dbi.NoRecordError
|
||||
return [QuoteGrabsRecord(id, text=quote)
|
||||
for (id, quote) in cursor.fetchall()]
|
||||
for (id, quote) in results]
|
||||
|
||||
def getQuote(self, channel, nick):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT quote FROM quotegrabs
|
||||
WHERE nickeq(nick, %s)
|
||||
ORDER BY id DESC LIMIT 1""", nick)
|
||||
if cursor.rowcount == 0:
|
||||
WHERE nickeq(nick, ?)
|
||||
ORDER BY id DESC LIMIT 1""", (nick,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
raise dbi.NoRecordError
|
||||
return cursor.fetchone()[0]
|
||||
return results[0][0]
|
||||
|
||||
def select(self, channel, nick):
|
||||
db = self._getDb(channel)
|
||||
cursor = db.cursor()
|
||||
cursor.execute("""SELECT added_at FROM quotegrabs
|
||||
WHERE nickeq(nick, %s)
|
||||
ORDER BY id DESC LIMIT 1""", nick)
|
||||
if cursor.rowcount == 0:
|
||||
WHERE nickeq(nick, ?)
|
||||
ORDER BY id DESC LIMIT 1""", (nick,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
raise dbi.NoRecordError
|
||||
return cursor.fetchone()[0]
|
||||
return results[0][0]
|
||||
|
||||
def add(self, channel, msg, by):
|
||||
db = self._getDb(channel)
|
||||
|
@ -161,14 +173,15 @@ class SqliteQuoteGrabsDB(object):
|
|||
text = ircmsgs.prettyPrint(msg)
|
||||
# Check to see if the latest quotegrab is identical
|
||||
cursor.execute("""SELECT quote FROM quotegrabs
|
||||
WHERE nick=%s
|
||||
ORDER BY id DESC LIMIT 1""", msg.nick)
|
||||
if cursor.rowcount != 0:
|
||||
if text == cursor.fetchone()[0]:
|
||||
WHERE nick=?
|
||||
ORDER BY id DESC LIMIT 1""", (msg.nick,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) != 0:
|
||||
if text == results[0][0]:
|
||||
return
|
||||
cursor.execute("""INSERT INTO quotegrabs
|
||||
VALUES (NULL, %s, %s, %s, %s, %s)""",
|
||||
msg.nick, msg.prefix, by, int(time.time()), text)
|
||||
VALUES (NULL, ?, ?, ?, ?, ?)""",
|
||||
(msg.nick, msg.prefix, by, int(time.time()), text,))
|
||||
db.commit()
|
||||
|
||||
def remove(self, channel, grab=None):
|
||||
|
@ -179,14 +192,16 @@ class SqliteQuoteGrabsDB(object):
|
|||
# strictly unnecessary -- the DELETE operation would "succeed"
|
||||
# anyway, but it's silly to just keep saying 'OK' no matter what,
|
||||
# so...
|
||||
cursor.execute("""SELECT * FROM quotegrabs WHERE id = %s""", grab)
|
||||
if cursor.rowcount == 0:
|
||||
cursor.execute("""SELECT * FROM quotegrabs WHERE id = ?""", (grab,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
raise dbi.NoRecordError
|
||||
cursor.execute("""DELETE FROM quotegrabs WHERE id = %s""", grab)
|
||||
cursor.execute("""DELETE FROM quotegrabs WHERE id = ?""", (grab,))
|
||||
else:
|
||||
cursor.execute("""SELECT * FROM quotegrabs WHERE id = (SELECT MAX(id)
|
||||
FROM quotegrabs)""")
|
||||
if cursor.rowcount == 0:
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
raise dbi.NoRecordError
|
||||
cursor.execute("""DELETE FROM quotegrabs WHERE id = (SELECT MAX(id)
|
||||
FROM quotegrabs)""")
|
||||
|
@ -197,14 +212,15 @@ class SqliteQuoteGrabsDB(object):
|
|||
cursor = db.cursor()
|
||||
text = '%' + text + '%'
|
||||
cursor.execute("""SELECT id, nick, quote FROM quotegrabs
|
||||
WHERE quote LIKE %s
|
||||
ORDER BY id DESC""", text)
|
||||
if cursor.rowcount == 0:
|
||||
WHERE quote LIKE ?
|
||||
ORDER BY id DESC""", (text,))
|
||||
results = cursor.fetchall()
|
||||
if len(results) == 0:
|
||||
raise dbi.NoRecordError
|
||||
return [QuoteGrabsRecord(id, text=quote, by=nick)
|
||||
for (id, nick, quote) in cursor.fetchall()]
|
||||
for (id, nick, quote) in results]
|
||||
|
||||
QuoteGrabsDB = plugins.DB('QuoteGrabs', {'sqlite': SqliteQuoteGrabsDB})
|
||||
QuoteGrabsDB = plugins.DB('QuoteGrabs', {'sqlite3': SqliteQuoteGrabsDB})
|
||||
|
||||
class QuoteGrabs(callbacks.Plugin):
|
||||
"""Add the help for "@help QuoteGrabs" here."""
|
||||
|
|
|
@ -72,6 +72,12 @@ conf.registerChannelValue(RSS, 'showLinks',
|
|||
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.""")))
|
||||
conf.registerGlobalValue(RSS, 'defaultNumberOfHeadlines',
|
||||
registry.PositiveInteger(1, """Indicates how many headlines an rss feed
|
||||
will output by default, if no number is provided."""))
|
||||
conf.registerChannelValue(RSS, 'initialAnnounceHeadlines',
|
||||
registry.PositiveInteger(5, """Indicates how many headlines an rss feed
|
||||
will output when it is first added to announce for a channel."""))
|
||||
|
||||
conf.registerGroup(RSS, 'announce')
|
||||
conf.registerChannelValue(RSS.announce, 'showLinks',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Supybot-fr\n"
|
||||
"POT-Creation-Date: 2010-10-19 19:27+CEST\n"
|
||||
"POT-Creation-Date: 2011-02-26 09:49+CET\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||
|
@ -15,20 +15,20 @@ msgstr ""
|
|||
|
||||
#: config.py:50
|
||||
msgid ""
|
||||
"Determines whether the bot will bold the title of the feed when it\n"
|
||||
" announces new news."
|
||||
"Determines whether the bot will bold the title of the feed when\n"
|
||||
" it announces new news."
|
||||
msgstr "Détermine si le bot mettera en gras le titre des flux lorsqu'il annoncera des news."
|
||||
|
||||
#: config.py:53
|
||||
msgid ""
|
||||
"Determines what string is used\n"
|
||||
" to separate headlines in new feeds."
|
||||
"Determines what string is\n"
|
||||
" used to separate headlines in new feeds."
|
||||
msgstr "Détermine quelle chaîne est utilisé pour séparer les titres dans les nouveaux flux."
|
||||
|
||||
#: config.py:56
|
||||
msgid ""
|
||||
"Determines what prefix\n"
|
||||
" is prepended (if any) to the new news item announcements made in the\n"
|
||||
"Determines what\n"
|
||||
" prefix is prepended (if any) to the new news item announcements made in the\n"
|
||||
" channel."
|
||||
msgstr "Détermine quel préfixe (s'il y en a un) est utilisé pour annoncer les news sur le canal."
|
||||
|
||||
|
@ -60,14 +60,14 @@ msgid ""
|
|||
" listed when a feed is automatically announced."
|
||||
msgstr "Détermine si le bot listera le lien de chaque flus avec son titre, lorsque la commande rss est appelée. supybot.plugins.RSS.announce.showLinks affecte si les liens sont affichés lorsqu'un flux est annoncé automatiquement."
|
||||
|
||||
#: config.py:78
|
||||
#: config.py:84
|
||||
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 "Détermine si le bot listera le lien de chaque flux avec le titre lorsqu'un flux est automatiquement annoncé."
|
||||
|
||||
#: plugin.py:63
|
||||
#: plugin.py:62
|
||||
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"
|
||||
|
@ -75,7 +75,7 @@ msgid ""
|
|||
" command to determine what feeds should be announced in a given channel."
|
||||
msgstr "Ce plugin est utile pour annoncer des flux RSS sur un canal, et pour récupérer les en-tête des flux RSS via une commande. Utilisez la commande \"add\" pour ajouter des flux au plugin, et utilisez la commande \"annonce\" pour détermine quels flux pourront être annoncés sur un canal donné."
|
||||
|
||||
#: plugin.py:311
|
||||
#: plugin.py:316
|
||||
msgid ""
|
||||
"<name> <url>\n"
|
||||
"\n"
|
||||
|
@ -87,7 +87,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Ajoute un commande à ce plugin qui permet de regarder le flux situé à l'<url>."
|
||||
|
||||
#: plugin.py:322
|
||||
#: plugin.py:327
|
||||
msgid ""
|
||||
"<name>\n"
|
||||
"\n"
|
||||
|
@ -99,15 +99,27 @@ msgstr ""
|
|||
"\n"
|
||||
"Supprime le flux des flux qui peuvent être lus grâce à une commande."
|
||||
|
||||
#: plugin.py:328
|
||||
#: plugin.py:333
|
||||
msgid "That's not a valid RSS feed command name."
|
||||
msgstr "Ce n'est pas une commande de flux RSS valide"
|
||||
|
||||
#: plugin.py:346
|
||||
#: plugin.py:344
|
||||
msgid ""
|
||||
"[<channel>]\n"
|
||||
"\n"
|
||||
" Returns the list of feeds announced in <channel>. <channel> is\n"
|
||||
" only necessary if the message isn't sent in the channel itself.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"[<canal>]\n"
|
||||
"\n"
|
||||
"Retourne la liste des flux annoncés sur le <canal>. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:351
|
||||
msgid "I am currently not announcing any feeds."
|
||||
msgstr "Je n'annonce actuellement aucun flux."
|
||||
|
||||
#: plugin.py:351
|
||||
#: plugin.py:356
|
||||
msgid ""
|
||||
"[<channel>] <name|url> [<name|url> ...]\n"
|
||||
"\n"
|
||||
|
@ -121,7 +133,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Ajoute la liste de flux à la liste actuelle des flux annoncés sur le <canal>. Vous devez indiquer le <nom> du flux si il est déjà enregistré, ou l'<url> dans le cas contraire. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:369
|
||||
#: plugin.py:374
|
||||
msgid ""
|
||||
"[<channel>] <name|url> [<name|url> ...]\n"
|
||||
"\n"
|
||||
|
@ -135,7 +147,7 @@ msgstr ""
|
|||
"\n"
|
||||
"Supprime la liste de flux de la liste actuelle des flux annoncés sur le <canal>. Vous devez indiquer le <nom> du flux si il est déjà enregistré, ou l'<url> dans le cas contraire. <canal> n'est nécessaire que si le message n'est pas envoyé sur le canal lui-même."
|
||||
|
||||
#: plugin.py:387
|
||||
#: plugin.py:392
|
||||
msgid ""
|
||||
"<url> [<number of headlines>]\n"
|
||||
"\n"
|
||||
|
@ -147,11 +159,11 @@ msgstr ""
|
|||
"\n"
|
||||
"Récupère le titre des éléments du flux RSS donné. si le <nombre de lignes> est donné, ne retourne que ce nombre de lignes d'en-tête."
|
||||
|
||||
#: plugin.py:400
|
||||
#: plugin.py:405
|
||||
msgid "Couldn't get RSS feed."
|
||||
msgstr "Ne peut récupérer le flux RSS."
|
||||
|
||||
#: plugin.py:413
|
||||
#: plugin.py:420
|
||||
msgid ""
|
||||
"<url|feed>\n"
|
||||
"\n"
|
||||
|
@ -163,11 +175,11 @@ msgstr ""
|
|||
"\n"
|
||||
"Retourne des informations sur le flux RSS donné : le titre, l'URL, la description, et la dernière mise à jour."
|
||||
|
||||
#: plugin.py:426
|
||||
#: plugin.py:433
|
||||
msgid "I couldn't retrieve that RSS feed."
|
||||
msgstr "Je ne peux récupérer ce flux RSS."
|
||||
|
||||
#: plugin.py:439
|
||||
#: plugin.py:446
|
||||
msgid "Title: %s; URL: %u; Description: %s; Last updated: %s."
|
||||
msgstr "Titre : %s , URL : %u ; description : %s ; dernière mise à jour : %s."
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue