]> gitweb.pimeys.fr Git - bots/basile.git/commitdiff
PEP8
authorVincent Le Gallic <legallic@crans.org>
Sat, 1 Jun 2013 04:36:46 +0000 (06:36 +0200)
committerVincent Le Gallic <legallic@crans.org>
Sat, 1 Jun 2013 04:36:46 +0000 (06:36 +0200)
basile.py
config.py
identities.pickle [deleted file]
nk.py

index 96641c120badf7e01959faa6d3351b017c898ebe..797717a905bfd733a0083356d39b6a00226ae9fe 100755 (executable)
--- a/basile.py
+++ b/basile.py
@@ -9,7 +9,6 @@ import threading
 import random
 import time
 import json
-import pickle
 import re
 import os
 import signal
@@ -30,789 +29,820 @@ import nk
 # la partie qui réfère au fichier lui-même est mieux ici
 # sinon on réfère la config et pas le fichier lui-même
 import os
-config.thisfile= os.path.realpath( __file__ )
+config.thisfile = os.path.realpath(__file__)
 
 def get_config_logfile(serveur):
-    serveurs={"acoeur.crans.org":"acoeur","irc.crans.org":"crans"}
-    return config.logfile_template%(serveurs[serveur])
+    """Renvoie le nom du fichier de log en fonction du ``serveur`` et de la config."""
+    serveurs = {"acoeur.crans.org" : "acoeur",
+                "irc.crans.org" : "crans"}
+    return config.logfile_template % (serveurs[serveur],)
 
 def get_filesize():
-    return ex("ls -s %s"%(config.thisfile))[1].split()[0]
+    """Récupère la taille de ce fichier."""
+    return ex("ls -s %s" % (config.thisfile))[1].split()[0]
 
-def log(serveur,channel,auteur=None,message=None):
-    f=open(get_config_logfile(serveur),"a")
-    if auteur==message==None:
+def log(serveur, channel, auteur=None, message=None):
+    """Enregistre une ligne de log."""
+    if auteur == message == None:
         # alors c'est que c'est pas un channel mais juste une ligne de log
-        chain="%s %s"%(time.strftime("%F %T"),channel)
+        chain = u"%s %s" % (time.strftime("%F %T"), channel)
     else:
-        chain="%s [%s:%s] %s"%(time.strftime("%F %T"),channel,auteur,message)
-    f.write(chain+"\n")
+        chain = u"%s [%s:%s] %s" % (time.strftime("%F %T"), channel, auteur, message)
+    f = open(get_config_logfile(serveur), "a")
+    f.write((chain + u"\n").encode("utf-8"))
+    f.close()
     if config.debug_stdout:
         print chain
-    f.close()
 
-def is_something(chain,matches,avant=u".*(?:^| )",apres=u"(?:$|\.| |,|;).*",case_sensitive=False,debug=False):
+def regex_join(liste, avant=u".*(?:^| )", apres=u"(?:$|\.| |,|;).*"):
+    """Fabrique une regexp à partir d'une liste d'éléments à matcher."""
+    return avant + u"(" + u"|".join(liste) + u")" + apres
+
+def is_something(chain, regexp=None, matches=[], avant=u".*(?:^| )", apres=u"(?:$|\.| |,|;).*",
+                 case_sensitive=False):
+    """Vérifie si chain contient un des éléments de ``matches``.
+       Si ``regexp`` est fournie, c'est simplement elle qui est testée"""
     if case_sensitive:
-        chain=unicode(chain,"utf8")
-    else:
-        chain=unicode(chain,"utf8").lower()
-    allmatches="("+"|".join(matches)+")"
-    reg=(avant+allmatches+apres).lower()
-    o=re.match(reg,chain)
+        chain = chain.lower()
+    if regexp == None:
+        regexp = regex_join(matches, avant, apres)
+        regexp = re.compile(regexp)
+    o = regexp.match(chain)
     return o
 
-def is_insult(chain,debug=True):
-    return is_something(chain,config.insultes,avant=".*(?:^| |')")
+def regexp_compile():
+    """Compilation des regexp à partir de la conf.
+       Place les résultats dans le namespace de ``config``"""
+    config.insult_regexp = regex_join(config.insultes, avant=u".*(?:^| |')")
+    config.insult_regexp_compiled = re.compile(config.insult_regexp)
+    
+    config.not_insult_regexp = u".*pas %s%s" % (config.amplifier_regexp, config.insult_regexp)
+    config.not_insult_regexp_compiled = re.compile(config.not_insult_regexp)
+    
+    config.compliment_regexp = regex_join(config.compliment_triggers, avant=u".*(?:^| |')")
+    config.compliment_regexp_compiled = re.compile(config.compliment_regexp)
+    
+    config.perdu_regexp = regex_join(config.perdu)
+    config.perdu_regexp_compiled = re.compile(config.perdu_regexp)
+    
+    config.tag_regexp = regex_join(config.tag_triggers)
+    config.tag_regexp_compiled = re.compile(config.tag_regexp)
+    
+    config.gros_regexp = regex_join(config.gros)
+    config.gros_regexp_compiled = re.compile(config.gros_regexp)
+    
+    config.tesla_regexp = regex_join(config.tesla_triggers, avant=u"^", apres="$")
+    config.tesla_regexp_compiled = re.compile(config.tesla_regexp)
+    
+    config.merci_regexp = regex_join(config.merci_triggers)
+    config.merci_regexp_compiled = re.compile(config.merci_regexp)
+    
+    config.tamere_regexp = regex_join(config.tamere_triggers)
+    config.tamere_regexp_compiled = re.compile(config.tamere_regexp)
+    
+    config.bonjour_regexp = regex_join(config.bonjour_triggers, avant=u"^")
+    config.bonjour_regexp_compiled = re.compile(config.bonjour_regexp)
+    
+    config.bonne_nuit_regexp = regex_join(config.bonne_nuit_triggers, avant=u"^")
+    config.bonne_nuit_regexp_compiled = re.compile(config.bonne_nuit_regexp)
+    
+    config.pan_regexp = regex_join(config.pan_triggers, avant=".*", apres=".*")
+    config.pan_regexp_compiled = re.compile(config.pan_regexp)
+    
+    
+regexp_compile()
+def is_insult(chain, debug=True):
+    """Vérifie si ``chain`` contient une insulte."""
+    return is_something(chain, config.insult_regexp_compiled)
 def is_not_insult(chain):
-    chain=unicode(chain,"utf8")
-    insult_regexp=u"("+u"|".join(config.insultes)+u")"
-    middle_regexp=u"(une? (?:(?:putain|enfoiré) d(?:e |'))*|)(?:| super )(?: (?:gros|petit|grand|énorme) |)"
-    reg=".*pas %s%s.*"%(middle_regexp,insult_regexp)
-    if re.match(reg,chain):
-        return True
-    else:
-        return False
-def is_compliment(chain,debug=True):
-    return is_something(chain,config.compliment_triggers,avant=".*(?:^| |')")
+    """Vérifie si ``chain`` contient une insulte à la forme négative."""
+    return is_something(chain, config.not_insult_regexp_compiled)
+def is_compliment(chain, debug=True):
+    """Vérifie si ``chain`` contient un compliment."""
+    return is_something(chain, config.compliment_regexp_compiled)
 def is_perdu(chain):
-    return is_something(chain,config.perdu)
+    """Vérifie si ``chain`` contient une raison de perdre."""
+    return is_something(chain, config.perdu_regexp_compiled)
 def is_tag(chain):
-    return is_something(chain,config.tag_triggers)
+    """Vérifie si ``chain`` demande de fermer sa gueule."""
+    return is_something(chain, config.tag_regexp_compiled)
 def is_gros(chain):
-    return is_something(chain,config.gros)
+    """Vérifie si ``chain`` traite de gros."""
+    return is_something(chain, config.gros_regexp_compiled)
 def is_tesla(chain):
-    return is_something(chain,config.tesla_triggers,avant=u"^",apres=u"$",debug=True)
+    """Vérifie si ``chain`` est un ping."""
+    return is_something(chain, config.tesla_regexp_compiled)
 def is_merci(chain):
-    return is_something(chain,config.merci_triggers)
+    """Vérifie si ``chain`` contient un remerciement."""
+    return is_something(chain, config.merci_regexp_compiled)
 def is_tamere(chain):
-    return is_something(chain,config.tamere_triggers)
+    """Vérifie si ``chain`` traite ma mère."""
+    return is_something(chain, config.tamere_regexp_compiled)
 def is_bad_action_trigger(chain,pseudo):
-    return is_something(chain,config.bad_action_triggers,avant=u"^",
-                            apres="(?: [a-z]*ment)? %s($|\.| |,|;).*"%(pseudo))
+    """Vérifie si ``chain`` est une action méchante.
+       On a besoin d'une regexp dynamique à cause du pseudo qui peut changer."""
+    return is_something(chain, matches=config.bad_action_triggers, avant=u"^",
+                            apres="(?: [a-z]*ment)? %s($|\.| |,|;).*" % (pseudo))
 def is_good_action_trigger(chain,pseudo):
-    return is_something(chain,config.good_action_triggers,avant=u"^",
-                            apres="(?: [a-z]*ment)? %s($|\.| |,|;).*"%(pseudo))
+    """Vérifie si ``chain`` est une action gentille.
+       On a besoin d'une regexp dynamique à cause du pseudo qui peut changer."""
+    return is_something(chain, matches=config.good_action_triggers, avant=u"^",
+                            apres="(?: [a-z]*ment)? %s($|\.| |,|;).*" % (pseudo))
 def is_bonjour(chain):
-    return is_something(chain,config.bonjour_triggers,avant=u"^")
+    """Vérifie si ``chain`` contient un bonjour."""
+    return is_something(chain, config.bonjour_regexp_compiled)
 def is_bonne_nuit(chain):
-    return is_something(chain,config.bonne_nuit_triggers,avant=u"^")
+    """Vérifie si ``chain`` contient un bonne nuit."""
+    return is_something(chain, config.bonne_nuit_regexp_compiled)
 def is_pan(chain):
-    return re.match(u"^(pan|bim|bang)( .*)?$",unicode(chain,"utf8").lower().strip())
+    """Vérifie si ``chain`` contient un pan."""
+    return is_something(chain, config.pan_regexp_compiled)
 
 def is_time(conf):
-    _,_,_,h,m,s,_,_,_=time.localtime()
-    return (conf[0],0,0)<(h,m,s)<(conf[1],0,0)
+    """Vérifie si l'heure actuelle est entre les deux heures ``conf[0]`` et ``conf[1]``"""
+    _, _, _, h, m, s, _, _, _ = time.localtime()
+    return (conf[0], 0, 0) < (h, m, s) < (conf[1], 0, 0)
 def is_day():
+    """Vérifie si on est le jour."""
     return is_time(config.daytime)
 def is_night():
+    """Vérifie si on est la nuit."""
     return is_time(config.nighttime)
 
       
 class UnicodeBotError(Exception):
+    """Erreur levée si quelqu'un fait du caca avec son encodage."""
     pass
 
 class CrashError(Exception):
-    """Pour pouvoir faire crasher Basile, parce que ça a l'air drôle"""
-    def __init__(self, msg=u""):
+    """Pour pouvoir faire crasher Basile, parce que ça a l'air drôle."""
+    def __init__(self, msg=""):
         Exception.__init__(self, msg)
 
 def bot_unicode(chain):
+    """Essaye de décoder ``chain`` en UTF-8.
+       Lève une py:class:`UnicodeBotError` en cas d'échec."""
     try:
-        unicode(chain,"utf8")
+        return chain.decode("utf8")
     except UnicodeDecodeError as exc:
         raise UnicodeBotError
 
 
 class Basile(ircbot.SingleServerIRCBot):
-    def __init__(self,serveur,debug=False):
-        temporary_pseudo=config.irc_pseudo+str(random.randrange(10000,100000))
+    """Classe principale : définition du bot Basile."""
+    def __init__(self, serveur, debug=False):
+        temporary_pseudo = config.irc_pseudo + str(random.randrange(10000,100000))
         ircbot.SingleServerIRCBot.__init__(self, [(serveur, 6667)],
-                              temporary_pseudo,"Basile, le bot irc.[Codé par 20-100, fouettez-le]", 10)
-        self.debug=debug
-        self.serveur=serveur
-        self.overops=config.overops
-        self.ops=self.overops+config.ops
-        self.report_bugs_to=config.report_bugs_to
-        self.chanlist=config.chanlist
-        self.identities=pickle.load(open("identities.pickle","r"))
-        self.stay_channels=config.stay_channels
-        self.quiet_channels=config.quiet_channels
-        self.last_perdu=0
-
-
-    def new_connection_NK(self,serv,username,password,typ="bdd"):
+                              temporary_pseudo, "Basile, le bot irc. [Codé par 20-100]", 10)
+        self.debug = debug
+        self.serveur = serveur
+        self.overops = config.overops
+        self.ops = self.overops + config.ops
+        self.report_bugs_to = config.report_bugs_to
+        self.chanlist = config.chanlist
+        self.identities = json.load(open(config.identities_file, "r"))
+        self.stay_channels = config.stay_channels
+        self.quiet_channels = config.quiet_channels
+        self.last_perdu = 0
+    
+    def new_connection_NK(self, serv, username, password, typ="bdd"):
         """Renvoie (``True``, <une socket ouverte et authentifiée sur la NoteKfet2015>)
            ou bien (``False``, None)"""
         try:
-            login_result,sock=nk.login(username,password,typ)
-            droits,retcode,errmsg=login_result["msg"],login_result["retcode"],login_result["errmsg"]
+            login_result, sock = nk.login(username, password, typ)
+            droits, retcode, errmsg = login_result["msg"], login_result["retcode"], login_result["errmsg"]
         except nk.NKRefused as exc:
             for report in self.report_bugs_to:
-                serv.privmsg(report,"Le Serveur NK2015 est down.")
-            return (False,None)
+                serv.privmsg(report, "Le Serveur NK2015 est down.")
+            return (False, None)
         except nk.NKHelloFailed as exc:
             for report in self.report_bugs_to:
                 serv.privmsg(report,
-                             "La version du site utilisée n'est pas supportée par le serveur NK2015.")
-            return (False,None)
+                             "La version du protocole utilisée n'est pas supportée par le serveur NK2015.")
+            return (False, None)
         except nk.NKUnknownError as exc:
-            erreurs=["Une fucking erreur inconnue s'est produite"]
-            erreurs+=str(exc).split("\n")
+            erreurs = ["Une fucking erreur inconnue s'est produite"]
+            erreurs += str(exc).split("\n")
             for report in self.report_bugs_to:
                 for err in erreurs:
-                    serv.privmsg(report,err)
-            return (False,None)
+                    serv.privmsg(report, err)
+            return (False, None)
         except Exception as exc:
             # Exception qui ne vient pas de la communication avec le serveur NK2015
-            log(self.serveur,"Erreur dans new_connection_NK\n"+str(exc))
-            return (False,None)
-        if retcode==0:
-            return (True,sock)
+            log(self.serveur, "Erreur dans new_connection_NK\n" + str(exc))
+            return (False, None)
+        if retcode == 0:
+            return (True, sock)
         else:
-            return (False,None)
+            return (False, None)
 
-    def give_me_my_pseudo(self,serv):
+    def give_me_my_pseudo(self, serv):
         """Récupère le pseudo auprès de NickServ."""
-        serv.privmsg("NickServ","RECOVER %s %s"%(config.irc_pseudo,config.irc_password))
-        serv.privmsg("NickServ","RELEASE %s %s"%(config.irc_pseudo,config.irc_password))
+        serv.privmsg("NickServ", "RECOVER %s %s" % (config.irc_pseudo, config.irc_password))
+        serv.privmsg("NickServ", "RELEASE %s %s" % (config.irc_pseudo, config.irc_password))
         time.sleep(0.3)
         serv.nick(config.irc_pseudo)
     
     def on_welcome(self, serv, ev):
-        self.serv=serv # ça serv ira :)
+        """À l'arrivée sur le serveur."""
+        self.serv = serv # ça serv ira :)
         self.give_me_my_pseudo(serv)
-        serv.privmsg("NickServ","identify %s"%(config.irc_password))
-        log(self.serveur,"Connected")
+        serv.privmsg("NickServ", "IDENTIFY %s" % (config.irc_password))
+        log(self.serveur, "Connected")
         if self.debug:
-            self.chanlist=["#bot"]
+            self.chanlist = ["#bot"]
         for c in self.chanlist:
-            log(self.serveur,"JOIN %s"%(c))
+            log(self.serveur, "JOIN %s" % (c))
             serv.join(c)
         # on ouvre la connexion note de Basile, special user
-        self.nk=self.new_connection_NK(serv,config.note_pseudo,config.note_password,"special")[1]
-        if self.nk==None:
+        self.nk = self.new_connection_NK(serv, config.note_pseudo, config.note_password, "special")[1]
+        if self.nk == None:
             for report in self.report_bugs_to:
-                serv.privmsg(report,"Connection to NK2015 failed, invalid password ?")
+                serv.privmsg(report, "Connection to NK2015 failed, invalid password ?")
 
-    def lost(self,serv,channel,forced=False):
-        if self.last_perdu+config.time_between_perdu<time.time() or forced:
+    def lost(self, serv, channel, forced=False):
+        """Réaction à un trigger de perdu.
+           Annonce "J'ai perdu" sur le channel si on n'a pas perdu depuis un certain temps."""
+        if self.last_perdu + config.time_between_perdu < time.time() or forced:
             if not channel in self.quiet_channels or forced:
-                serv.privmsg(channel,"J'ai perdu !")
+                serv.privmsg(channel, "J'ai perdu !")
             self.last_perdu=time.time()
             delay=config.time_between_perdu_trigger
             delta=config.time_between_perdu_trigger_delta
             serv.execute_delayed(random.randrange(delay-delta,delay+delta),self.lost,(serv,channel))
     
     def pourmoi(self, serv, message):
-        """renvoie (False,lemessage) ou (True, le message amputé de "pseudo: ")"""
-        pseudo=self.nick
-        size=len(pseudo)
-        if message[:size]==pseudo and len(message)>size and message[size]==":":
-            return (True,message[size+1:].lstrip(" "))
+        """Renvoie (False, lemessage) ou (True, le message amputé de "pseudo: ")"""
+        pseudo = self.nick
+        pseudo = pseudo.decode("utf-8")
+        size = len(pseudo)
+        if message[:size] == pseudo and len(message) > size and message[size] == ":":
+            return (True, message[size+1:].lstrip(" "))
         else:
-            return (False,message)
+            return (False, message)
 
     def on_privmsg(self, serv, ev):
-        message=ev.arguments()[0]
+        """À la réception d'un message en privé."""
+        message = ev.arguments()[0]
         auteur = irclib.nm_to_n(ev.source())
         try:
-            test=bot_unicode(message)
+            message = bot_unicode(message)
         except UnicodeBotError:
             if config.utf8_trigger:
                 serv.privmsg(auteur, random.choice(config.utf8_fail_answers).encode("utf8"))
             return
-        message=message.split()
-        cmd=message[0].lower()
-        notunderstood=False
-        if cmd=="help":
-            helpdico={"help":["""HELP <commande>
- Affiche de l'aide sur la commande""",None,None],
-"identify": ["""IDENTIFY <username> <password>
- Vérifie le mot de passe et me permet de savoir à l'avenir quel est votre pseudo note kfet.
- Sans paramètre, je vous précise sous quel pseudo je vous connais.""",None,None],
-"drop":["""DROP <password>
- Vérifie le mot de passe et me fait d'oublier votre pseudo note kfet.""",None,None],
-"solde": ["""SOLDE
- Affiche votre solde, si je connais votre pseudo note kfet.""",
- """SOLDE <pseudo>
- Affiche le solde de la personne désignée (par son pseudo note).""",None],
- "join": [None, """JOIN <channel>
- Me fait rejoindre le channel""",None],
- "leave": [None,"""LEAVE <channel>
- Me fait quitter le channel (sauf s'il est dans ma stay_list).""",None],
- "quiet": [None,"""QUIET <channel>
- Me rend silencieux sur le channel.""",None],
- "noquiet": [None,"""NOQUIET <channel>
- Me rend la parole sur le channel.""",None],
- "lost": [None,"""LOST <channel>
- Me fait perdre sur le channel.""",None],
- "reconnect": [None,"""RECONNECT
- Établit à nouveau la connexion avec le serveur NK2015""",None],
- "reload": [None,"""RELOAD
- Recharge la configuration.""",None],
- "say": [None,None,"""SAY <channel> <message>
- Me fait parler sur le channel."""],
- "do": [None,None,"""DO <channel> <action>
- Me fait faitre une action (/me) sur le channel."""],
- "stay": [None,None,"""STAY <channel>
- Ajoute le channel à ma stay_list."""],
- "nostay": [None,None,"""NOSTAY <channel>
- Retire le channel de ma stay_list."""],
- "ops": [None,None,"""OPS
- Affiche la liste des ops."""],
- "overops": [None,None,"""OVEROPS
- Affiche la liste des overops."""],
- "kick": [None,None,"""KICK <channel> <pseudo> [<raison>]
- Kicke <pseudo> du channel (Il faut bien entendu que j'y sois op)."""],
- "die": [None,None,"""DIE
- Me déconnecte du serveur IRC."""],
- "crash": [None,None,"""CRASH
- Me fait crasher"""]
- }
-            helpmsg_default="Liste des commandes disponibles :\nHELP IDENTIFY DROP SOLDE"
-            helpmsg_ops=" JOIN LEAVE QUIET NOQUIET LOST RECONNECT RELOAD"
-            helpmsg_overops=" SAY DO STAY NOSTAY OPS OVEROPS KICK DIE CRASH"
+        message = message.split()
+        cmd = message[0].lower()
+        notunderstood = False
+        if cmd == u"help":
             op,overop=auteur in self.ops, auteur in self.overops
             if len(message)==1:
-                helpmsg=helpmsg_default
+                helpmsg = config.helpmsg_default
                 if op:
-                    helpmsg+=helpmsg_ops
+                    helpmsg += config.helpmsg_ops
                 if overop:
-                    helpmsg+=helpmsg_overops
+                    helpmsg += config.helpmsg_overops
             else:
-                helpmsgs=helpdico.get(message[1].lower(),["Commande inconnue.",None,None])
-                helpmsg=helpmsgs[0]
+                helpmsgs = config.helpdico.get(message[1].lower(), ["Commande inconnue.", None, None])
+                helpmsg = helpmsgs[0]
                 if op and helpmsgs[1]:
                     if helpmsg:
-                        helpmsg+="\n"+helpmsgs[1]
+                        helpmsg += "\n" + helpmsgs[1]
                     else:
-                        helpmsg=helpmsgs[1]
+                        helpmsg = helpmsgs[1]
                 if overop and helpmsgs[2]:
                     if helpmsg:
-                        helpmsg+="\n"+helpmsgs[2]
+                        helpmsg += "\n" + helpmsgs[2]
                     else:
-                        helpmsg=helpmsgs[2]
+                        helpmsg = helpmsgs[2]
             for ligne in helpmsg.split("\n"):
-                serv.privmsg(auteur,ligne)
-        elif cmd=="identify":
-            if len(message)==1:
+                serv.privmsg(auteur, ligne.encode("utf-8"))
+        elif cmd == u"identify":
+            if len(message) == 1:
                 if self.identities.has_key(auteur):
-                    serv.privmsg(auteur,"Je vous connais sous le pseudo note %s."%(
+                    serv.privmsg(auteur, "Je vous connais sous le pseudo note %s." % (
                                      self.identities[auteur].encode("utf8")))
                 else:
-                    serv.privmsg(auteur,"Je ne connais pas votre pseudo note.")
-            elif len(message)>=3:
-                username,password=message[1],unicode(" ".join(message[2:]),"utf8")
-                success,_=self.new_connection_NK(serv,username,password)
+                    serv.privmsg(auteur, "Je ne connais pas votre pseudo note.")
+            elif len(message) >= 3:
+                username, password = message[1], " ".join(message[2:])
+                success, _ = self.new_connection_NK(serv, username, password)
                 if success:
-                    log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
-                    serv.privmsg(auteur,"Identité enregistrée.")
-                    self.identities[auteur]=username
-                    pickle.dump(Xself.identities,open("identities.pickle","w"))
+                    log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
+                    serv.privmsg(auteur, "Identité enregistrée.")
+                    self.identities[auteur] = username
+                    json.dump(self.identities, open(config.identities_file,"w"))
                 else:
-                    log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
-                    serv.privmsg(auteur,"Mot de passe invalide. (ou serveur down)")
+                    log(self.serveur, "priv", auteur, " ".join(message) + "[failed]")
+                    serv.privmsg(auteur, "Mot de passe invalide. (ou serveur down)")
             else:
-                serv.privmsg(auteur,u"Syntaxe : IDENTIFY [<username> <password>]")
-        elif cmd=="drop":
-            if len(message)>1:
+                serv.privmsg(auteur, "Syntaxe : IDENTIFY [<username> <password>]")
+        elif cmd == u"drop":
+            if len(message) > 1:
                 if self.identities.has_key(auteur):
-                    password=" ".join(message[1:])
-                    success,_=self.new_connection_NK(serv,self.identities[auteur],password)
+                    password = " ".join(message[1:])
+                    success, _ = self.new_connection_NK(serv, self.identities[auteur], password)
                     if success:
                         del self.identities[auteur]
-                        log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
-                        pickle.dump(self.identities,open("identities.pickle","w"))
-                        serv.privmsg(auteur,"Identité oubliée.")
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
+                        json.dump(self.identities, open(config.identities_file, "w"))
+                        serv.privmsg(auteur, "Identité oubliée.")
                     else:
-                        log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
-                        serv.privmsg(auteur,"Mot de passe invalide. (ou serveur down)")
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[failed]")
+                        serv.privmsg(auteur, "Mot de passe invalide. (ou serveur down)")
                 else:
-                    serv.privmsg(auteur,"Je ne connais pas ton pseudo note.")
+                    serv.privmsg(auteur, "Je ne connais pas ton pseudo note.")
             else:
-                serv.privmsg(auteur,"Syntaxe : DROP <password>")
-        elif cmd=="join":
+                serv.privmsg(auteur, "Syntaxe : DROP <password>")
+        elif cmd == u"join":
             if auteur in self.ops:
-                if len(message)>1:
+                if len(message) > 1:
                     if message[1] in self.chanlist:
-                        serv.privmsg(auteur,"Je suis déjà sur %s"%(message[1]))
+                        serv.privmsg(auteur, "Je suis déjà sur %s" % (message[1]))
                     else:
                         serv.join(message[1])
                         self.chanlist.append(message[1])
-                        serv.privmsg(auteur,"Channels : "+" ".join(self.chanlist))
-                        log(self.serveur,"priv",auteur," ".join(message))
+                        serv.privmsg(auteur, "Channels : " + " ".join(self.chanlist))
+                        log(self.serveur, "priv", auteur, " ".join(message))
                 else:
-                    serv.privmsg(auteur,"Channels : "+" ".join(self.chanlist))
+                    serv.privmsg(auteur, "Channels : " + " ".join(self.chanlist))
             else:
-                notunderstood=True
-        elif cmd=="leave":
-            if auteur in self.ops and len(message)>1:
+                notunderstood = True
+        elif cmd == u"leave":
+            if auteur in self.ops and len(message) > 1:
                 if message[1] in self.chanlist:
                     if not (message[1] in self.stay_channels) or auteur in self.overops:
-                        self.quitter(message[1]," ".join(message[2:]))
+                        self.quitter(message[1], " ".join(message[2:]))
                         self.chanlist.remove(message[1])
-                        log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
                     else:
-                        serv.privmsg(auteur,"Non, je reste !")
-                        log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
+                        serv.privmsg(auteur, "Non, je reste !")
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[failed]")
                 else:
-                    serv.privmsg(auteur,"Je ne suis pas sur %s"%(message[1]))
+                    serv.privmsg(auteur, "Je ne suis pas sur %s" % (message[1]))
             else:
-                notunderstood=True
-        elif cmd=="stay":
+                notunderstood = True
+        elif cmd == u"stay":
             if auteur in self.overops:
-                if len(message)>1:
+                if len(message) > 1:
                     if message[1] in self.stay_channels:
-                        log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
-                        serv.privmsg(auteur,"Je stay déjà sur %s."%(message[1]))
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[failed]")
+                        serv.privmsg(auteur, "Je stay déjà sur %s." % (message[1]))
                     else:
-                        log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
                         self.stay_channels.append(message[1])
-                        serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
+                        serv.privmsg(auteur, "Stay channels : " + " ".join(self.stay_channels))
                 else:
-                    serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
+                    serv.privmsg(auteur, "Stay channels : " + " ".join(self.stay_channels))
             else:
-                notunderstood=True
-        elif cmd=="nostay":
+                notunderstood = True
+        elif cmd == u"nostay":
             if auteur in self.overops:
-                if len(message)>1:
+                if len(message) > 1:
                     if message[1] in self.stay_channels:
-                        log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
                         self.stay_channels.remove(message[1])
-                        serv.privmsg(auteur,"Stay channels : "+" ".join(self.stay_channels))
+                        serv.privmsg(auteur, "Stay channels : " + " ".join(self.stay_channels))
                     else:
-                        log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
-                        serv.privmsg(auteur,"Je ne stay pas sur %s."%(message[1]))
-
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[failed]")
+                        serv.privmsg(auteur, "Je ne stay pas sur %s." % (message[1]))
             else:
-                notunderstood=True
-        elif cmd=="die":
+                notunderstood = True
+        elif cmd == u"die":
             if auteur in self.overops:
-                log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
+                log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
                 self.mourir()
             else:
-                notunderstood=True
-        elif cmd=="crash":
+                notunderstood = True
+        elif cmd == u"crash":
             if auteur in self.overops:
-                log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
+                log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
                 self.crash("priv", auteur)
             else:
-                notunderstood=True
-        elif cmd=="reload":
+                notunderstood = True
+        elif cmd == u"reload":
             if auteur in self.ops:
                 self.reload(auteur)
-                log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
+                log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
             else:
-                notunderstood=True
-        elif cmd=="reconnect":
+                notunderstood = True
+        elif cmd == u"reconnect":
             if auteur in self.ops:
                 try:
-                    self.nk=self.new_connection_NK(serv,config.note_pseudo,
-                                            config.note_password,"special")[1]
+                    self.nk = self.new_connection_NK(serv, config.note_pseudo,
+                                            config.note_password, "special")[1]
                 except Exception as exc:
-                    self.nk=None
-                    log(self.serveur,"""Erreur dans on_pubmsg/"cmd in ["reconnect"]\n"""+str(exc))
-                if self.nk!=None:
-                    serv.privmsg(auteur,"%s: done"%(auteur))
-                    log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
+                    self.nk = None
+                    log(self.serveur, 'Erreur dans on_pubmsg/"cmd in ["reconnect"]\n' + str(exc))
+                if self.nk != None:
+                    serv.privmsg(auteur, "%s: done" % (auteur))
+                    log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
                 else:
-                    serv.privmsg(auteur,"%s: failed"%(auteur))
-                    log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
+                    serv.privmsg(auteur, "%s: failed" % (auteur))
+                    log(self.serveur, "priv", auteur, " ".join(message) + "[failed]")
                     for report in self.report_bugs_to:
-                        serv.privmsg(report,"Connection to NK2015 failed, invalid password ? Server dead ?")
+                        serv.privmsg(report, "Connection to NK2015 failed, invalid password ? Server dead ?")
             else:
-                notunderstood=True
-        elif cmd=="quiet":
+                notunderstood = True
+        elif cmd == u"quiet":
             if auteur in self.ops:
-                if len(message)>1:
+                if len(message) > 1:
                     if message[1] in self.quiet_channels:
-                        serv.privmsg(auteur,"Je me la ferme déjà sur %s"%(message[1]))
-                        log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
+                        serv.privmsg(auteur, "Je me la ferme déjà sur %s" % (message[1]))
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[failed]")
                     else:
                         self.quiet_channels.append(message[1])
-                        serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
-                        log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
+                        serv.privmsg(auteur, "Quiet channels : " + " ".join(self.quiet_channels))
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
                 else:
-                    serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
+                    serv.privmsg(auteur, "Quiet channels : " + " ".join(self.quiet_channels))
             else:
-                notunderstood=True
-        elif cmd=="noquiet":
+                notunderstood = True
+        elif cmd == u"noquiet":
             if auteur in self.ops:
-                if len(message)>1:
+                if len(message) > 1:
                     if message[1] in self.quiet_channels:
                         self.quiet_channels.remove(message[1])
-                        serv.privmsg(auteur,"Quiet channels : "+" ".join(self.quiet_channels))
-                        log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
+                        serv.privmsg(auteur, "Quiet channels : " + " ".join(self.quiet_channels))
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
                     else:
-                        serv.privmsg(auteur,"Je ne me la ferme pas sur %s."%(message[1]))
-                        log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
+                        serv.privmsg(auteur, "Je ne me la ferme pas sur %s." % (message[1]))
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[failed]")
             else:
-                notunderstood=True
-        elif cmd=="say":
-            if auteur in self.overops and len(message)>2:
-                serv.privmsg(message[1]," ".join(message[2:]))
-                log(self.serveur,"priv",auteur," ".join(message))
-            elif len(message)<=2:
-                serv.privmsg(auteur,"Syntaxe : SAY <channel> <message>")
+                notunderstood = True
+        elif cmd == u"say":
+            if auteur in self.overops and len(message) > 2:
+                serv.privmsg(message[1], " ".join(message[2:]))
+                log(self.serveur, "priv", auteur, " ".join(message))
+            elif len(message) <= 2:
+                serv.privmsg(auteur, "Syntaxe : SAY <channel> <message>")
             else:
-                notunderstood=True
-        elif cmd=="do":
-            if auteur in self.overops and len(message)>2:
-                serv.action(message[1]," ".join(message[2:]))
-                log(self.serveur,"priv",auteur," ".join(message))
-            elif len(message)<=2:
-                serv.privmsg(auteur,"Syntaxe : DO <channel> <action>")
+                notunderstood = True
+        elif cmd == u"do":
+            if auteur in self.overops and len(message) > 2:
+                serv.action(message[1], " ".join(message[2:]))
+                log(self.serveur, "priv", auteur, " ".join(message))
+            elif len(message) <= 2:
+                serv.privmsg(auteur, "Syntaxe : DO <channel> <action>")
             else:
-                notunderstood=True
-        elif cmd=="kick":
-            if auteur in self.overops and len(message)>2:
-                serv.kick(message[1],message[2]," ".join(message[3:]))
-                log(self.serveur,"priv",auteur," ".join(message))
-            elif len(message)<=2:
-                serv.privmsg(auteur,"Syntaxe : KICK <channel> <pseudo> [<raison>]")
+                notunderstood = True
+        elif cmd == u"kick":
+            if auteur in self.overops and len(message) > 2:
+                serv.kick(message[1], message[2], " ".join(message[3:]))
+                log(self.serveur, "priv", auteur, " ".join(message))
+            elif len(message) <= 2:
+                serv.privmsg(auteur, "Syntaxe : KICK <channel> <pseudo> [<raison>]")
             else:
-                notunderstood=True
-        elif cmd=="lost":
-            if auteur in self.ops and len(message)>1:
-                serv.privmsg(message[1],"J'ai perdu !")
-                log(self.serveur,"priv",auteur," ".join(message))
-            elif len(message)<=1:
-                serv.privmsg(auteur,"Syntaxe : LOST <channel>")
+                notunderstood = True
+        elif cmd == u"lost":
+            if auteur in self.ops and len(message) > 1:
+                serv.privmsg(message[1], "J'ai perdu !")
+                log(self.serveur, "priv", auteur, " ".join(message))
+            elif len(message) <= 1:
+                serv.privmsg(auteur, "Syntaxe : LOST <channel>")
             else:
-                notunderstood=True
-        elif cmd=="solde":
-            if len(message)==1:
+                notunderstood = True
+        elif cmd == u"solde":
+            if len(message) == 1:
                 if self.identities.has_key(auteur):
                     try:
-                        self.nk.write('["search", ["x",["pseudo"],%s]]'%(json.dumps(self.identities[auteur])))
-                        ret=json.loads(self.nk.read())
-                        solde=ret["msg"][0]["solde"]
-                        pseudo=ret["msg"][0]["pseudo"]
+                        self.nk.write('["search", ["x",["pseudo"],%s]]' % (json.dumps(self.identities[auteur])))
+                        ret = json.loads(self.nk.read())
+                        solde = ret["msg"][0]["solde"]
+                        pseudo = ret["msg"][0]["pseudo"]
                     except Exception as exc:
                         print exc
-                        serv.privmsg(auteur,"failed")
-                        log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
+                        serv.privmsg(auteur, "failed")
+                        log(self.serveur, "priv", auteur, " ".join(message) + "[failed]")
                         return
-                    serv.privmsg(auteur,"%s (%s)"%(float(solde)/100,pseudo.encode("utf8")))
-                    log(self.serveur,"priv",auteur," ".join(message)+"[successful]")
+                    serv.privmsg(auteur, "%s (%s)" % (float(solde)/100, pseudo.encode("utf8")))
+                    log(self.serveur, "priv", auteur, " ".join(message) + "[successful]")
                 else:
-                    serv.privmsg(canal,"Je ne connais pas ton pseudo note.")
+                    serv.privmsg(canal, "Je ne connais pas ton pseudo note.")
             elif auteur in self.ops:
                 try:
-                    self.nk.write('["search", ["x",["pseudo"],%s]]'%(json.dumps(message[1])))
-                    ret=json.loads(self.nk.read())
-                    solde=ret["msg"][0]["solde"]
-                    pseudo=ret["msg"][0]["pseudo"]
+                    self.nk.write('["search", ["x",["pseudo"],%s]]' % (json.dumps(message[1])))
+                    ret = json.loads(self.nk.read())
+                    solde = ret["msg"][0]["solde"]
+                    pseudo = ret["msg"][0]["pseudo"]
                 except Exception as exc:
-                    serv.privmsg(auteur,"failed")
-                    log(self.serveur,"priv",auteur," ".join(message)+"[failed]")
+                    serv.privmsg(auteur, "failed")
+                    log(self.serveur, "priv", auteur, " ".join(message) + "[failed]")
                     return
-                serv.privmsg(auteur,"%s (%s)"%(float(solde)/100,pseudo.encode("utf8")))
-        elif cmd=="ops":
+                serv.privmsg(auteur, "%s (%s)" % (float(solde)/100, pseudo.encode("utf8")))
+        elif cmd == u"ops":
             if auteur in self.overops:
-                serv.privmsg(auteur," ".join(self.ops))
+                serv.privmsg(auteur, " ".join(self.ops))
             else:
-                notunderstood=True
-        elif cmd=="overops":
+                notunderstood = True
+        elif cmd == u"overops":
             if auteur in self.overops:
-                serv.privmsg(auteur," ".join(self.overops))
+                serv.privmsg(auteur, " ".join(self.overops))
             else:
-                notunderstood=True
+                notunderstood = True
         else:
-            notunderstood=True
+            notunderstood = True
         if notunderstood:
-            serv.privmsg(auteur,"Je n'ai pas compris. Essayez HELP…")
+            serv.privmsg(auteur, "Je n'ai pas compris. Essayez HELP…")
     
     def on_pubmsg(self, serv, ev):
+        """À la réception d'un message sur un channel."""
         auteur = irclib.nm_to_n(ev.source())
         canal = ev.target()
         message = ev.arguments()[0]
         try:
-            test=bot_unicode(message)
+            message = bot_unicode(message)
         except UnicodeBotError:
             if config.utf8_trigger and not canal in self.quiet_channels:
-                serv.privmsg(canal, (u"%s: %s"%(auteur,random.choice(config.utf8_fail_answers))).encode("utf8"))
+                serv.privmsg(canal, (u"%s: %s"% ( auteur, random.choice(config.utf8_fail_answers))).encode("utf8"))
             return
-        pour_moi,message=self.pourmoi(serv,message)
+        pour_moi, message = self.pourmoi(serv, message)
         if pour_moi and message.split()!=[]:
-            cmd=message.split()[0].lower()
+            cmd = message.split()[0].lower()
             try:
-                args=" ".join(message.split()[1:])
+                args = " ".join(message.split()[1:])
             except:
-                args=""
-            if cmd in ["meurs","die","crève"]:
+                args = ""
+            if cmd in [u"meurs", u"die", u"crève"]:
                 if auteur in self.overops:
-                    log(self.serveur,canal,auteur,message+"[successful]")
+                    log(self.serveur, canal, auteur, message + "[successful]")
                     self.mourir()
                 else:
-                    serv.privmsg(canal,("%s: %s"%(auteur,random.choice(config.quit_fail_messages))).encode("utf8"))
-                    log(self.serveur,canal,auteur,message+"[failed]")
-            elif cmd == "reload":
+                    serv.privmsg(canal,(u"%s: %s"%(auteur, random.choice(config.quit_fail_messages))).encode("utf8"))
+                    log(self.serveur, canal, auteur, message + "[failed]")
+            elif cmd == u"reload":
                 if auteur in self.ops:
-                    log(self.serveur, canal, auteur, message+"[successful]")
+                    log(self.serveur, canal, auteur, message + "[successful]")
                     self.reload(canal)
-            elif cmd == "crash":
+            elif cmd == u"crash":
                 if auteur in self.overops:
                     self.crash(auteur, message)
-            elif cmd in ["part","leave","dégage","va-t-en","tut'tiresailleurs,c'estmesgalets"]:
+            elif cmd in [u"part", u"leave", u"dégage", u"va-t-en", u"tut'tiresailleurs,c'estmesgalets"]:
                 if auteur in self.ops and (not (canal in self.stay_channels)
                                            or auteur in self.overops):
                     self.quitter(canal)
-                    log(self.serveur,canal,auteur,message+"[successful]")
+                    log(self.serveur, canal, auteur, message + "[successful]")
                     if canal in self.chanlist:
                         self.chanlist.remove(canal)
                 else:
-                    serv.privmsg(canal,("%s: %s"%(auteur,random.choice(config.leave_fail_messages))).encode("utf8"))
-                    log(self.serveur,canal,auteur,message+"[failed]")
+                    serv.privmsg(canal,(u"%s: %s" % (auteur, random.choice(config.leave_fail_messages))).encode("utf8"))
+                    log(self.serveur, canal, auteur, message + "[failed]")
             
-            elif cmd in ["reconnect"]:
+            elif cmd == u"reconnect":
                 if auteur in self.ops:
                     try:
-                        self.nk=self.new_connection_NK(serv,config.note_pseudo,
-                                              config.note_password,"special")[1]
+                        self.nk = self.new_connection_NK(serv, config.note_pseudo,
+                                              config.note_password, "special")[1]
                     except Exception as exc:
-                        self.nk=None
-                        log(self.serveur,"""Erreur dans on_pubmsg/"cmd in ["reconnect"]\n"""+str(exc))
-                    if self.nk!=None:
-                        serv.privmsg(canal,"%s: done"%(auteur))
-                        log(self.serveur,canal,auteur,message+"[successful]")
+                        self.nk = None
+                        log(self.serveur, 'Erreur dans on_pubmsg/"cmd in ["reconnect"]\n' + str(exc))
+                    if self.nk != None:
+                        serv.privmsg(canal, "%s: done" % (auteur))
+                        log(self.serveur, canal, auteur, message + "[successful]")
                     else:
-                        serv.privmsg(canal,"%s: failed"%(auteur))
-                        log(self.serveur,canal,auteur,message+"[failed]")
+                        serv.privmsg(canal, "%s: failed" % (auteur))
+                        log(self.serveur, canal, auteur, message + "[failed]")
                         for report in self.report_bugs_to:
-                            serv.privmsg(report,"Connection to NK2015 failed, invalid password ? Server dead ?")
+                            serv.privmsg(report, "Connection to NK2015 failed, invalid password ? Server dead ?")
                 else:
-                    serv.privmsg(canal,"%s: %s"%(auteur,random.choice(config.pas_programme_pour_tobeir).encode("utf8")))
-                    log(self.serveur,canal,auteur,message+"[failed]")
+                    serv.privmsg(canal, "%s: %s" % (auteur, random.choice(config.pas_programme_pour_tobeir).encode("utf8")))
+                    log(self.serveur, canal, auteur, message + "[failed]")
 
-            elif cmd in ["deviens","pseudo"]:
+            elif cmd in [u"deviens", u"pseudo"]:
                 if auteur in self.ops:
-                    become=args
+                    become = args
                     serv.nick(become)
-                    log(self.serveur,canal,auteur,message+"[successful]")
+                    log(self.serveur, canal, auteur, message + "[successful]")
     
-            if cmd in ["meur", "meurt","meurre","meurres"] and not canal in self.quiet_channels:
-                serv.privmsg(canal,'%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)'%(auteur))
-            elif cmd in ["ping"] and not canal in self.quiet_channels:
-                serv.privmsg(canal,"%s: pong"%(auteur))
+            if cmd in [u"meur", u"meurt", u"meurre", u"meurres"] and not canal in self.quiet_channels:
+                serv.privmsg(canal, '%s: Mourir, impératif, 2ème personne du singulier : "meurs" (de rien)' % (auteur))
+            elif cmd in [u"ping"] and not canal in self.quiet_channels:
+                serv.privmsg(canal, "%s: pong" % (auteur))
 
-            elif cmd in ["solde","!solde"]:
+            elif cmd in [u"solde", u"!solde"]:
                 if self.identities.has_key(auteur):
-                    pseudo=self.identities[auteur]
+                    pseudo = self.identities[auteur]
                     try:
-                        self.nk.write('["search", ["x",["pseudo"],%s]]'%(json.dumps(pseudo)))
-                        ret=json.loads(self.nk.read())
-                        solde=ret["msg"][0]["solde"]
-                        pseudo=ret["msg"][0]["pseudo"]
+                        self.nk.write(json.dumps(["search", ["x", ["pseudo"], pseudo]]))
+                        ret = json.loads(self.nk.read())
+                        solde = ret["msg"][0]["solde"]
+                        pseudo = ret["msg"][0]["pseudo"]
                     except Exception as exc:
-                        serv.privmsg(canal,"%s: failed"%(auteur))
-                        log(self.serveur,canal,auteur,message+"[failed]")
+                        serv.privmsg(canal, "%s: failed"%(auteur))
+                        log(self.serveur, canal, auteur, message + "[failed]")
                     else:
-                        serv.privmsg(canal,"%s: %s (%s)"%(auteur,float(solde)/100,pseudo.encode("utf8")))
-                        log(self.serveur,canal,auteur,message+"[successful]")
+                        serv.privmsg(canal, "%s: %s (%s)" % (auteur, float(solde)/100, pseudo.encode("utf8")))
+                        log(self.serveur, canal, auteur, message + "[successful]")
                 else:
-                    serv.privmsg(canal,"%s: Je ne connais pas votre pseudo note."%(auteur))
-                    log(self.serveur,canal,auteur,message+"[unknown]")
-            elif (re.match("!?(pain au chocolat|chocolatine)",message.lower())
+                    serv.privmsg(canal, "%s: Je ne connais pas votre pseudo note." % (auteur))
+                    log(self.serveur, canal, auteur, message + "[unknown]")
+            elif (re.match("!?(pain au chocolat|chocolatine)", message.lower())
                  and not canal in self.quiet_channels):
-                serv.action(canal,"sert un pain au chocolat à %s"%(auteur))
+                serv.action(canal, "sert un pain au chocolat à %s" % (auteur))
             elif re.match("!?manzana",message.lower()) and not canal in self.quiet_channels:
                 if auteur in config.manzana:
-                    serv.action(canal,"sert une bouteille de manzana à %s"%(auteur))
+                    serv.action(canal, "sert une bouteille de manzana à %s" % (auteur))
                 elif auteur in config.manzana_bis:
-                    serv.action(canal,"sert un grand verre de jus de pomme à %s : tout le monde sait qu'il ne boit pas."%(auteur))
+                    serv.action(canal, "sert un grand verre de jus de pomme à %s : tout le monde sait qu'il ne boit pas." % (auteur))
                 else:
-                    serv.action(canal,"sert un verre de manzana à %s"%(auteur))
+                    serv.action(canal, "sert un verre de manzana à %s" % (auteur))
             if is_insult(message) and not canal in self.quiet_channels:
                 if is_not_insult(message):
-                    answer=random.choice(config.compliment_answers)
+                    answer = random.choice(config.compliment_answers)
                     for ligne in answer.split("\n"):
-                        serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
+                        serv.privmsg(canal, "%s: %s" % (auteur, ligne.encode("utf8")))
                 else:
-                    answer=random.choice(config.insultes_answers)
+                    answer = random.choice(config.insultes_answers)
                     for ligne in answer.split("\n"):
-                        serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
+                        serv.privmsg(canal, "%s: %s" % (auteur, ligne.encode("utf8")))
             elif is_compliment(message) and not canal in self.quiet_channels:
-                answer=random.choice(config.compliment_answers)
+                answer = random.choice(config.compliment_answers)
                 for ligne in answer.split("\n"):
-                    serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
-            gros_match=is_gros(message)
+                    serv.privmsg(canal, "%s: %s" % (auteur,ligne.encode("utf8")))
+            gros_match = is_gros(message)
             if gros_match and not canal in self.quiet_channels:
-                taille=get_filesize()
-                answer=u"Mais non, je ne suis pas %s, %sKo tout au plus…"%(gros_match.groups()[0],taille)
-                serv.privmsg(canal,"%s: %s"%(auteur,answer.encode("utf8")))
+                taille = get_filesize()
+                answer = u"Mais non, je ne suis pas %s, %sKo tout au plus…" % (gros_match.groups()[0], taille)
+                serv.privmsg(canal, "%s: %s"%(auteur, answer.encode("utf8")))
             if is_tesla(message) and not canal in self.quiet_channels:
-                l1,l2=config.tesla_answers,config.tesla_actions
-                n1,n2=len(l1),len(l2)
-                i=random.randrange(n1+n2)
-                if i>=n1:
-                    serv.action(canal,l2[i-n1].encode("utf8"))
+                l1, l2 = config.tesla_answers, config.tesla_actions
+                n1, n2 = len(l1), len(l2)
+                i = random.randrange(n1 + n2)
+                if i >= n1:
+                    serv.action(canal, l2[i - n1].encode("utf8"))
                 else:
-                    serv.privmsg(canal,"%s: %s"%(auteur,l1[i].encode("utf8")))
+                    serv.privmsg(canal, "%s: %s" % (auteur, l1[i].encode("utf8")))
             if is_tamere(message) and not canal in self.quiet_channels:
-                answer=random.choice(config.tamere_answers)
+                answer = random.choice(config.tamere_answers)
                 for ligne in answer.split("\n"):
-                    serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
+                    serv.privmsg(canal, "%s: %s"%(auteur, ligne.encode("utf8")))
             if is_tag(message) and not canal in self.quiet_channels:
                 if auteur in self.ops:
-                    action=random.choice(config.tag_actions)
-                    serv.action(canal,action.encode("utf8"))
+                    action = random.choice(config.tag_actions)
+                    serv.action(canal, action.encode("utf8"))
                     self.quiet_channels.append(canal)
                 else:
-                    answer=random.choice(config.tag_answers)
+                    answer = random.choice(config.tag_answers)
                     for ligne in answer.split("\n"):
-                        serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
+                        serv.privmsg(canal, "%s: %s" % (auteur, ligne.encode("utf8")))
             if is_merci(message):
-                answer=random.choice(config.merci_answers)
+                answer = random.choice(config.merci_answers)
                 for ligne in answer.split("\n"):
-                    serv.privmsg(canal,"%s: %s"%(auteur,ligne.encode("utf8")))
-            out=re.match(ur"^([A-Z[]|\\|[0-9]+|(¹|²|³|⁴|⁵|⁶|⁷|⁸|⁹|⁰)+)(?:| \?| !)$",
-                         unicode(message.upper(),"utf8"))
-            if re.match("ma bite dans ton oreille",message) and not canal in self.quiet_channels:
-                serv.privmsg(canal,"%s: Seul un olasd peut imiter un olasd dans un de ses grands jours !"%(auteur))
+                    serv.privmsg(canal, "%s: %s"%(auteur, ligne.encode("utf8")))
+            out = re.match(ur"^([A-Z[]|\\|[0-9]+|(¹|²|³|⁴|⁵|⁶|⁷|⁸|⁹|⁰)+)(?:| \?| !)$", message.upper())
+            if re.match("ma bite dans ton oreille", message) and not canal in self.quiet_channels:
+                serv.privmsg(canal, "%s: Seul un olasd peut imiter un olasd dans un de ses grands jours !" % (auteur))
             if out and not canal in self.quiet_channels:
                 out = out.groups()[0]
                 try:
                     iout = int(out)
-                    serv.privmsg(canal,"%s: %s !"%(auteur, iout + 1))
+                    serv.privmsg(canal, "%s: %s !" % (auteur, iout + 1))
                     if iout == 2147483647:
-                        serv.privmsg(canal,"%s: Ciel, un maxint ! Heureusement que je suis en python…" % (auteur))
+                        serv.privmsg(canal, "%s: Ciel, un maxint ! Heureusement que je suis en python…" % (auteur))
                         return
-                    if iout + 1 > 1000 and random.randrange(4)==0:
-                        serv.privmsg(canal,"%s: Vous savez, moi et les chiffres…"%(auteur))
+                    if iout + 1 > 1000 and random.randrange(4) == 0:
+                        serv.privmsg(canal, "%s: Vous savez, moi et les chiffres…" % (auteur))
                         return
                 except Exception as exc:
                     pass
-                if re.match("[A-Y]",out):
-                    alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                    serv.privmsg(canal,"%s: %s !"%(auteur,alphabet[alphabet.index(out)+1]))
-                elif out=="Z":
-                    serv.privmsg(canal,"%s: Je ne vous remercie pas, j'ai l'air idiot ainsi… [ ?"%(auteur))
+                if re.match("[A-Y]", out):
+                    alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                    serv.privmsg(canal, "%s: %s !"%(auteur, alphabet[alphabet.index(out) + 1]))
+                elif out == "Z":
+                    serv.privmsg(canal, "%s: Je ne vous remercie pas, j'ai l'air idiot ainsi… [ ?" % (auteur))
                 elif out in "[\\":
-                    serv.privmsg(canal,"%s: Nous devrions nous en tenir là, ça va finir par poser des problèmes…"%(auteur))
-                elif re.match(ur"(¹|²|³|⁴|⁵|⁶|⁷|⁸|⁹|⁰)+",out):
+                    serv.privmsg(canal, "%s: Nous devrions nous en tenir là, ça va finir par poser des problèmes…" % (auteur))
+                elif re.match(ur"(¹|²|³|⁴|⁵|⁶|⁷|⁸|⁹|⁰)+", out):
                     def translate(mess):
                         return "".join([{u"⁰¹²³⁴⁵⁶⁷⁸⁹0123456789"[i]:u"0123456789⁰¹²³⁴⁵⁶⁷⁸⁹"[i]
                                         for i in range(20)}[j]
                                        for j in mess])
-                    out=int(translate(out))
-                    serv.privmsg(canal,"%s: %s !"%(auteur,translate(str(out+1)).encode("utf8")))
+                    out = int(translate(out))
+                    serv.privmsg(canal,"%s: %s !" % (auteur, translate(str(out + 1)).encode("utf8")))
             if is_bonjour(message) and not canal in self.quiet_channels:
                 if is_night():
-                    answer=random.choice(config.night_answers)
+                    answer = random.choice(config.night_answers)
                 elif is_day():
-                    answer=random.choice(config.bonjour_answers)
+                    answer = random.choice(config.bonjour_answers)
                 else:
-                    answer=random.choice(config.bonsoir_answers)
-                serv.privmsg(canal,answer.format(auteur).encode("utf8"))
+                    answer = random.choice(config.bonsoir_answers)
+                serv.privmsg(canal, answer.format(auteur).encode("utf8"))
             if is_bonne_nuit(message) and not canal in self.quiet_channels:
-                answer=random.choice(config.bonne_nuit_answers)
-                serv.privmsg(canal,answer.format(auteur).encode("utf8"))
+                answer = random.choice(config.bonne_nuit_answers)
+                serv.privmsg(canal, answer.format(auteur).encode("utf8"))
             if is_pan(message) and not canal in self.quiet_channels:
-                serv.privmsg(canal,"%s: ce n'est pas sur moi qu'il faut tirer, même si je sais que j'attire l'œil !"%(auteur))
+                serv.privmsg(canal, "%s: ce n'est pas sur moi qu'il faut tirer, même si je sais que j'attire l'œil !" % (auteur))
         else:
-            if message in ["!pain au chocolat","!chocolatine"] and not canal in self.quiet_channels:
-                serv.action(canal,"sert un pain au chocolat à %s"%(auteur))
-            if message in ["!manzana"] and not canal in self.quiet_channels:
+            if message in [u"!pain au chocolat", u"!chocolatine"] and not canal in self.quiet_channels:
+                serv.action(canal, "sert un pain au chocolat à %s" % (auteur))
+            if message in [u"!manzana"] and not canal in self.quiet_channels:
                 if auteur in config.manzana:
-                    serv.action(canal,"sert une bouteille de manzana à %s"%(auteur))
+                    serv.action(canal, "sert une bouteille de manzana à %s" % (auteur))
                 elif auteur in config.manzana_bis:
-                    serv.action(canal,"sert un grand verre de jus de pomme à %s : tout le monde sait qu'il ne boit pas."%(auteur))
+                    serv.action(canal, "sert un grand verre de jus de pomme à %s : tout le monde sait qu'il ne boit pas." % (auteur))
                 else:
-                    serv.action(canal,"sert un verre de manzana à %s"%(auteur))
-            if re.match(u'^ *(.|§|!|/|/|:|)(w|b) [0-9]+$',message.decode("utf8")) and not canal in self.quiet_channels:
-                failanswers=config.buffer_fail_answers
-                answer=random.choice(failanswers)
-                serv.privmsg(canal,("%s: %s"%(auteur,answer)).encode("utf8"))
+                    serv.action(canal, "sert un verre de manzana à %s" % (auteur))
+            if re.match(u'^ *(.|§|!|/|/|:|)(w|b) [0-9]+$', message) and not canal in self.quiet_channels:
+                failanswers = config.buffer_fail_answers
+                answer = random.choice(failanswers)
+                serv.privmsg(canal, ("%s: %s"%(auteur,answer)).encode("utf8"))
             if not canal in self.quiet_channels:
-                mypseudo=self.nick
-                if re.match((u"^("+u"|".join(config.bonjour_triggers)
-                                  +ur")( {}| all| tout le monde| (à )?tous)(\.| ?!)?$"
-                             ).format(mypseudo).lower(), message.decode("utf8").strip().lower()):
-                    answer=random.choice(config.bonjour_answers)
-                    serv.privmsg(canal,answer.format(auteur).encode("utf8"))
+                mypseudo = self.nick
+                if re.match((u"^(" + u"|".join(config.bonjour_triggers)
+                                   + ur")( {}| all| tout le monde| (à )?tous)(\.| ?!)?$"
+                             ).format(mypseudo).lower(), message.strip().lower()):
+                    answer = random.choice(config.bonjour_answers)
+                    serv.privmsg(canal, answer.format(auteur).encode("utf8"))
         if (is_perdu(message) and not canal in self.quiet_channels):
             # proba de perdre sur trigger :
             #  avant 30min (enfin, config) : 0
             #  ensuite, +25%/30min, linéairement
-            deltat=time.time()-self.last_perdu
-            barre=(deltat-config.time_between_perdu)/(2*3600.0)
-            if random.uniform(0,1)<barre:
-                serv.privmsg(canal,"%s: J'ai perdu !"%(auteur))
-                self.last_perdu=time.time()
+            deltat = time.time() - self.last_perdu
+            barre = (deltat - config.time_between_perdu)/(2*3600.0)
+            if random.uniform(0, 1) < barre:
+                serv.privmsg(canal, "%s: J'ai perdu !" % (auteur))
+                self.last_perdu = time.time()
 
     def on_action(self, serv, ev):
+        """À la réception d'une action."""
         action = ev.arguments()[0]
         auteur = irclib.nm_to_n(ev.source())
         channel = ev.target()
         try:
-            test=bot_unicode(action)
+            action = bot_unicode(action)
         except UnicodeBotError:
             if config.utf8_trigger and not channel in self.quiet_channels:
                 serv.privmsg(channel, (u"%s: %s"%(auteur,random.choice(config.utf8_fail_answers))).encode("utf8"))
             return
-        mypseudo=self.nick
+        mypseudo = self.nick
         
-        if is_bad_action_trigger(action,mypseudo) and not channel in self.quiet_channels:
-            l1,l2=config.bad_action_answers,config.bad_action_actions
-            n1,n2=len(l1),len(l2)
-            i=random.randrange(n1+n2)
-            if i>=n1:
-                serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
+        if is_bad_action_trigger(action, mypseudo) and not channel in self.quiet_channels:
+            l1, l2 = config.bad_action_answers, config.bad_action_actions
+            n1, n2 = len(l1), len(l2)
+            i = random.randrange(n1 + n2)
+            if i >= n1:
+                serv.action(channel, l2[i - n1].format(auteur).encode("utf8"))
             else:
-                serv.privmsg(channel,l1[i].format(auteur).format(auteur).encode("utf8"))
-        if is_good_action_trigger(action,mypseudo) and not channel in self.quiet_channels:
-            l1,l2=config.good_action_answers,config.good_action_actions
-            n1,n2=len(l1),len(l2)
-            i=random.randrange(n1+n2)
-            if i>=n1:
-                serv.action(channel,l2[i-n1].format(auteur).format(auteur).encode("utf8"))
+                serv.privmsg(channel, l1[i].format(auteur).encode("utf8"))
+        if is_good_action_trigger(action, mypseudo) and not channel in self.quiet_channels:
+            l1, l2 = config.good_action_answers, config.good_action_actions
+            n1, n2 = len(l1), len(l2)
+            i = random.randrange(n1 + n2)
+            if i >= n1:
+                serv.action(channel, l2[i-n1].format(auteur).encode("utf8"))
             else:
-                serv.privmsg(channel,l1[i].format(auteur).format(auteur).encode("utf8"))
+                serv.privmsg(channel, l1[i].format(auteur).encode("utf8"))
     
-    def on_kick(self,serv,ev):
+    def on_kick(self, serv, ev):
+        """À la réception d'une action."""
         auteur = irclib.nm_to_n(ev.source())
         channel = ev.target()
         victime = ev.arguments()[0]
         raison = ev.arguments()[1]
-        if victime==self.nick:
-            log(self.serveur,"%s kické de %s par %s (raison : %s)" %(victime,channel,auteur,raison))
+        if victime == self.nick:
+            log(self.serveur, "%s kické de %s par %s (raison : %s)" % (victime, channel, auteur, raison))
             time.sleep(2)
             serv.join(channel)
-            l1,l2=config.kick_answers,config.kick_actions
-            n1,n2=len(l1),len(l2)
-            i=random.randrange(n1+n2)
-            if i>=n1:
-                serv.action(channel,l2[i-n1].format(auteur).encode("utf8"))
+            l1, l2 = config.kick_answers, config.kick_actions
+            n1, n2 = len(l1), len(l2)
+            i = random.randrange(n1 + n2)
+            if i >= n1:
+                serv.action(channel, l2[i-n1].format(auteur).encode("utf8"))
             else:
-                serv.privmsg(channel,l1[i].format(auteur).encode("utf8"))
+                serv.privmsg(channel, l1[i].format(auteur).encode("utf8"))
     
-    def quitter(self,chan,leave_message=None):
-        if leave_message==None:
-            leave_message=random.choice(config.leave_messages)
-        self.serv.part(chan,message=leave_message.encode("utf8"))
+    def quitter(self, chan, leave_message=None):
+        """Quitter un channel avec un message customisable."""
+        if leave_message == None:
+            leave_message = random.choice(config.leave_messages)
+        self.serv.part(chan, message=leave_message.encode("utf8"))
     
     def mourir(self):
-        quit_message=random.choice(config.quit_messages)
+        """Se déconnecter du serveur IRC avec un message customisable."""
+        quit_message = random.choice(config.quit_messages)
         self.die(msg=quit_message.encode("utf8"))
     
     def _getnick(self):
+        """Récuère le nick effectif du bot sur le serveur."""
         return self.serv.get_nickname()
-    nick=property(_getnick)
+    nick = property(_getnick)
 
     def reload(self, auteur=None):
+        """Recharge la config."""
         reload(config)
+        regexp_compile()
         if auteur in [None, "SIGHUP"]:
-            towrite = "Config reloaded" + " (SIGHUP received)"*(auteur == "SIGHUP")
+            towrite = "Config reloaded" + " (SIGHUP received)" * (auteur == "SIGHUP")
             for to in config.report_bugs_to:
                 self.serv.privmsg(to, towrite)
             log(self.serveur, towrite)
         else:
-            self.serv.privmsg(auteur,"Config reloaded")
+            self.serv.privmsg(auteur, "Config reloaded")
     
     def crash(self, chan="nowhere", who="nobody"):
-        where = u"en privé" if chan == "priv" else u"sur le chan %s" % chan
-        raise CrashError(u"Crash demandé par %s %s" % (who, where))
+        """Fait crasher le bot."""
+        where = "en privé" if chan == "priv" else "sur le chan %s" % chan
+        raise CrashError("Crash demandé par %s %s" % (who, where))
     
     def start_as_daemon(self, outfile):
         sys.stderr = Logger(outfile)
@@ -830,11 +860,12 @@ class Logger(object):
         f.close()
 
 def main():
-    if len(sys.argv)==1:
+    """Exécution principal : lecture des paramètres et lancement du bot."""
+    if len(sys.argv) == 1:
         print "Usage : basile.py <serveur> [--debug] [--no-output] [--daemon [--pidfile]] [--outfile]"
         print "        --outfile sans --no-output ni --daemon n'a aucun effet"
         exit(1)
-    serveur=sys.argv[1]
+    serveur = sys.argv[1]
     if "--daemon" in sys.argv:
         thisfile = os.path.realpath(__file__)
         thisdirectory = thisfile.rsplit("/", 1)[0]
@@ -843,13 +874,17 @@ def main():
     else:
         daemon = False
     if "debug" in sys.argv or "--debug" in sys.argv:
-        debug=True
+        debug = True
     else:
-        debug=False
+        debug = False
     if "--quiet" in sys.argv:
-        config.debug_stdout=False
-    serveurs={"a♡":"acoeur.crans.org","acoeur":"acoeur.crans.org","acoeur.crans.org":"acoeur.crans.org",
-              "irc":"irc.crans.org","crans":"irc.crans.org","irc.crans.org":"irc.crans.org"}
+        config.debug_stdout = False
+    serveurs = {"a♡" : "acoeur.crans.org",
+              "acoeur" : "acoeur.crans.org",
+              "acoeur.crans.org" : "acoeur.crans.org",
+              "irc" : "irc.crans.org",
+              "crans" : "irc.crans.org",
+              "irc.crans.org" : "irc.crans.org"}
     if "--no-output" in sys.argv or "--daemon" in sys.argv:
         outfile = "/var/log/bots/basile.full.log"
         for arg in sys.argv:
@@ -858,15 +893,16 @@ def main():
                 outfile = arg[1]
         sys.stdout = Logger(outfile)
     try:
-        serveur=serveurs[serveur]
+        serveur = serveurs[serveur]
     except KeyError:
-        print "Server Unknown : %s"%(serveur)
+        print "Server Unknown : %s" % (serveur)
         exit(404)
-    basile=Basile(serveur,debug)
+    basile = Basile(serveur,debug)
     # Si on reçoit un SIGHUP, on reload la config
     def sighup_handler(signum, frame):
         basile.reload("SIGHUP")
     signal.signal(signal.SIGHUP, sighup_handler)
+    # Daemonization
     if daemon:
         child_pid = os.fork()
         if child_pid == 0:
index 7fe9fd288c8973dcefbcb849e36ec5e4451ad6c5..245ae26449046efa667c8e3c38ed5ecc550da4d1 100644 (file)
--- a/config.py
+++ b/config.py
@@ -1,54 +1,71 @@
 #!/usr/bin/python
 # -*- coding:utf8 -*-
 
-# Configuration de Basile
+""" Configuration de Basile """
 
-debug_stdout=True
+#: Faut-il débuguer sur la sortie standard par défaut ?
+debug_stdout = True
 
-# la config irc-related
-irc_password="NK2015BasileB0t"
-irc_pseudo="Basile"
-chanlist=["#bot", "#flood"]
-stay_channels=["#bot", "#flood"]
-quiet_channels=[]
+## La config irc-related
+#: Mot de passe NickServ. TODO : le mettre dans un secrets.py
+irc_password = "NK2015BasileB0t"
+#: Pseudo IRC
+irc_pseudo = "Basile"
+#: Liste des channels à rejoindre
+chanlist = ["#bot", "#flood"]
+#: Liste des channels à ne pas quitter
+stay_channels = ["#bot", "#flood"]
+#: Liste des channels où se taire
+quiet_channels = []
 
-# la config note-related
-note_pseudo="Basile"
-note_password="NK2015BasileB0tr4nd0omp4assword]6_+{#]78{"
+## La config note-related
+#: Pseudo note
+note_pseudo = "Basile"
+#: Mot de passe note TODO : secrets
+note_password = "NK2015BasileB0tr4nd0omp4assword]6_+{#]78{"
+#: Serveur NK2015
 nk_server = "bde2.crans.org"
+#: Port NK2015
 nk_port = 4242
 
-# les logs
-logfile_template="basile.%s.log"
+#: Là où sont stockées les correspondances pseudo IRC → note
+identities_file = "identities.json"
 
-# les ops
+#: Le template des noms de fichier de log
+logfile_template = "basile.%s.log"
+
+#: Les OVEROPs, tous les droits sur le bot
 overops=["[20-100]","[20-100]_", "PEB"]
+#: Les OPs, moins de droits que les OVEROPs
 ops=["Nit"]
+#: À qui s'adresser (par IRC) quand le bot rencontre une erreur
 report_bugs_to=["[20-100]"]
 
-# config "ce bot a été codé par 20-100, tu te rappelles ?"
+#: config "ce bot a été codé par 20-100, tu te rappelles ?"
 manzana = ["[20-100]", "Petite-Peste"] 
-# config "mais PEB aussi est passé par là"
+#: config "mais PEB aussi est passé par là"
 manzana_bis = ["PEB"]
 
-# config UTF8-fail
+#: config UTF8-fail
 utf8_fail_answers = [u"Si je n'avais pas été créé avec la plus grande attention, votre encodage aurait eu raison de moi…"]
+#: Doit-on râler en cas de fial d'UTF-8
 utf8_trigger = True
-# config "tu m'traites ?"
-insultes=[u"conna(rd|sse)",u"pute",u"con(|ne)",u"enf(oiré|lure)",
-u"sal(op(|e(|rie)|ard)|aud)",u"p(e|')tite bite",u"imbécile",u"idiot",u"stupid(|e)",u"débile",u"crétin",
-u"pétasse",u"enculé",u"chagasse",u"cagole",u"abruti",u"ahuri",u"analphabète",u"andouille",
-u"atardé",u"avorton",u"bachibouzouk",u"(balais|brosse) (de|à) chiotte(|s)",
-u"batard",u"blaireau",u"bouffon",u"branque",u"bouseux",u"branleur",u"catin",u"chacal",
-u"charogne",u"chiant(|e)",u"chieur",u"cochon",u"coprophage",u"couillon",u"crapule",u"crevard",
-u"cruche",u"cuistre",u"ducon",u"décérébré",
-u"emmerdeur",u"feignasse",u"fainéant",u"fourbe",u"freluquet",u"frigide",
-u"garce",u"glandu",u"gogol",u"goujat",u"gourdasse",u"gredin",u"gringalet",u"grognasse",
-u"naze",u"truie",u"iconoclaste",
-u"peigne(-|)cul",u"ignare",u"illétré",u"lèche(|-)cul",u"malotru",u"motherfucker",u"nabot",u"nigaud",
-u"nul",u"escroc",u"pouffiasse",u"pourriture",u"raclure",u"relou",u"sagouin",u"putain",
+#: config "tu m'traites ?"
+insultes = [u"conna(rd|sse)", u"pute", u"con(|ne)", u"enf(oiré|lure)",
+u"sal(op(|e(|rie)|ard)|aud)", u"p(e|')tite bite", u"imbécile", u"idiot", u"stupid(|e)", u"débile", u"crétin",
+u"pétasse", u"enculé", u"chagasse", u"cagole", u"abruti", u"ahuri", u"analphabète", u"andouille",
+u"atardé", u"avorton", u"bachibouzouk", u"(balais|brosse) (de|à) chiotte(|s)",
+u"batard", u"blaireau", u"bouffon", u"branque", u"bouseux", u"branleur", u"catin", u"chacal",
+u"charogne", u"chiant(|e)", u"chieur", u"cochon", u"coprophage", u"couillon", u"crapule", u"crevard",
+u"cruche", u"cuistre", u"ducon", u"décérébré",
+u"emmerdeur", u"feignasse", u"fainéant", u"fourbe", u"freluquet", u"frigide",
+u"garce", u"glandu", u"gogol", u"goujat", u"gourdasse", u"gredin", u"gringalet", u"grognasse",
+u"naze", u"truie", u"iconoclaste",
+u"peigne(-|)cul", u"ignare", u"illétré", u"lèche(|-)cul", u"malotru", u"motherfucker", u"nabot", u"nigaud",
+u"nul", u"escroc", u"pouffiasse", u"pourriture", u"raclure", u"relou", u"sagouin", u"putain",
 u"péripatéticienne"]
-insultes_answers=[
+#: Réponses aux insultes
+insultes_answers = [
 u"Oh non ! Quelle insulte ! Je crois que je ne m'en relèverai jamais…\nEnfin presque.",
 u"J'entends comme un vague murmure, vous disiez ?",
 u"Je vais prendre ça pour un compliment.",
@@ -60,39 +77,45 @@ u"Le saviez-vous : l'invective ne déshonore que son auteur.",
 u"Le saviez-vous : vous perdez plus de temps à m'insulter qu'à vous taire.",
 u"Mais je ne vous permets pas ! Enfin, pas comme ça…"]
 
-# config "à peine quelques kilos octets"
-gros=[u"gros",u"énorme",u"lourd"]
+#: Regexp pour amplification
+amplifier_regexp = u"(une? (?:(?:putain|enfoiré) d(?:e |'))*|)(?:| super )(?: (?:gros|petit|grand|énorme) |)"
+
+#: config "pour quelque Ko de trop"
+gros = [u"gros", u"énorme", u"lourd"]
 
-# config spéciale-iota
-buffer_fail_answers=[u"Pas de chance !",u"Révisez vos classiques !",
+#: config spéciale-iota
+buffer_fail_answers = [u"Pas de chance !", u"Révisez vos classiques !",
 u"Encore un effort, je sais que vous pouvez le faire. ;)",
 u"Where did you learn to type?"]
 
-# config "jeu", d'ailleurs, j'ai perdu.
-premier_groupe_terminaisons=u"(e|es|ons|ez|ent|er(|ai|as|a|ons|ez|ont)|(|er)(ais|ait|ions|iez|aient)|(a(i|s|)|â(mes|tes|t)|èrent)|ass(e(|s|nt)|i(ons|ez))|é(|s|e|es))"
-regexp_etre=u"(être|suis|e(s|t)|so(mmes|nt)|êtes|(ét|ser)(ai(s|t|ent)|i(ons|ent)|)|ser(ai|as|a|ons|ez|ont)|so(i(s|t|ent)|y(ons|ez))|f(u(s|t|rent)|û(mes|tes|t))|fuss(e(|s|nt)|i(ons|ez))|étant)"
-regexp_etre_avec_c=u"c'(e(s|st)|étai(t|ent))"
-regexp_faire=u"fais"
-perdu=[u"perd(|s|ons|ez|ent|r(e|ai|as|a|ons|ez|ont)|(|r)(ais|ait|ions|iez|aient))"
+#: config "jeu", d'ailleurs, j'ai perdu.
+premier_groupe_terminaisons = u"(e|es|ons|ez|ent|er(|ai|as|a|ons|ez|ont)|(|er)(ais|ait|ions|iez|aient)|(a(i|s|)|â(mes|tes|t)|èrent)|ass(e(|s|nt)|i(ons|ez))|é(|s|e|es))"
+regexp_etre = u"(être|suis|e(s|t)|so(mmes|nt)|êtes|(ét|ser)(ai(s|t|ent)|i(ons|ent)|)|ser(ai|as|a|ons|ez|ont)|so(i(s|t|ent)|y(ons|ez))|f(u(s|t|rent)|û(mes|tes|t))|fuss(e(|s|nt)|i(ons|ez))|étant)"
+regexp_etre_avec_c = u"c'(e(s|st)|étai(t|ent))"
+regexp_faire = u"fais"
+perdu = [u"perd(|s|ons|ez|ent|r(e|ai|as|a|ons|ez|ont)|(|r)(ais|ait|ions|iez|aient))"
 u"perd(i(s|t|rent)|î(mes|tes|t))", # oui, j'ai inclus qu'il perdît
 u"perdiss(e(|s|nt)|i(ons|ez))",
-u"perdu(|s|e|es)",u"perdant(|s|e|es)",u"perte(|s)",
+u"perdu(|s|e|es)", u"perdant(|s|e|es)", u"perte(|s)",
 
-u"(gagn|trouv)"+premier_groupe_terminaisons,u"gagnant(|s|e|es)",u"gain(|s)",
+u"(gagn|trouv)" + premier_groupe_terminaisons, u"gagnant(|s|e|es)", u"gain(|s)",
 
-u"trouvant",u"trouvaille(|s)",
+u"trouvant", u"trouvaille(|s)",
 
-u"victoire(|s)",u"vaincu(|s|e|es)",
-u"loose",u"lost",u"looser(|s)",u"win(|ner)(|s)",
-u"jeu(|x)",u"game(|s)"]
-time_between_perdu_trigger=3600*3 #temps moyen pour perdre en l'absence de trigger
-time_between_perdu_trigger_delta = 30*60 #marge autorisée autour de ^^^
-time_between_perdu=30*60 #temps pendant lequel on ne peut pas perdre
+u"victoire(|s)", u"vaincu(|s|e|es)",
+u"loose", u"lost", u"looser(|s)", u"win(|ner)(|s)",
+u"jeu(|x)", u"game(|s)"]
+#: Temps moyen pour perdre en l'absence de trigger
+time_between_perdu_trigger = 3600*3
+#: Marge autorisée autour de ``time_between_perdu_trigger``
+time_between_perdu_trigger_delta = 30*60
+#: Temps pendant lequel on ne peut pas perdre
+time_between_perdu=30*60
 
-# config "tais-toi"
-tag_triggers=[u"t(|a)g",u"ta gueule",u"la ferme",u"ferme( |-)la",u"tais-toi",u"chut",u"tu fais trop de bruit",u"tu parles trop"]
-tag_actions=[u"se tait",u"se tient coi"]
-tag_answers=[
+#: config "tais-toi"
+tag_triggers = [u"t(|a)g", u"ta gueule", u"la ferme", u"ferme( |-)la", u"tais-toi", u"chut", u"tu fais trop de bruit", u"tu parles trop"]
+tag_actions = [u"se tait", u"se tient coi"]
+tag_answers = [
 u"Ç'aurait été avec plaisir, mais je ne crois pas que vous puissiez vous passer de mes services.",
 u"Dès que cela sera utile.",
 u"Une autre fois, peut-être.",
@@ -100,19 +123,19 @@ u"Si je me tais, qui vous rappellera combien vous me devez ?",
 u"J'aurais aimé accéder à votre requête, mais après mûre réflexion, j'en ai perdu l'envie.",
 u"Je ne ressens pas de besoin irrésistible de me taire, navré."]
 
-# config ping
-tesla_triggers=[u"t('|u )es là \?",u"\?",u"plop \?",u"plouf \?"]
-tesla_answers=[
+#: config ping
+tesla_triggers = [u"t('|u )es là \?", u"\?", u"plop \?", u"plouf \?"]
+tesla_answers = [
 u"Oui, je suis là.",
 u"J'écoute.",
 u"En quoi puis-je me rendre utile ?",
 u"On a besoin de moi ?"
 ]
-tesla_actions=[u"est là",u"attend des instructions",u"est toujours disponible"]
+tesla_actions = [u"est là", u"attend des instructions", u"est toujours disponible"]
 
-# config en cas de non-insulte
-compliment_triggers=[u"gentil",u"cool",u"sympa",u"efficace"]
-compliment_answers=[
+#: config en cas de non-insulte
+compliment_triggers = [u"gentil", u"cool", u"sympa", u"efficace"]
+compliment_answers = [
 u"Merci, c'est gentil de votre part. :)",
 u"Permettez-moi de vous retourner le compliment, sans ironie cette fois.",
 u"Je vous remercie.",
@@ -120,21 +143,28 @@ u"C'est trop d'honneur.",
 u"Vous êtes bien aimable."
 ]
 
-# config merci
-merci_triggers=[u"merci",u"remercie",u"thx",u"thank(|s)"]
-merci_answers=[u"Mais de rien.",u"À votre service. ;)",u"Quand vous voulez. :)",
+#: config merci
+merci_triggers = [u"merci", u"remercie", u"thx", u"thank(|s)"]
+merci_answers = [
+u"Mais de rien.",
+u"À votre service. ;)",
+u"Quand vous voulez. :)",
 u"Tout le plaisir est pour moi."]
 
-# config "ta mère" 
-tamere_triggers=[u"ta mère"]
-tamere_answers=[u"Laissez donc ma mère en dehors de ça !",
+#: config "ta mère" 
+tamere_triggers = [u"ta mère"]
+tamere_answers = [
+u"Laissez donc ma mère en dehors de ça !",
 u"Puis-je préciser que je n'ai pas de mère ? Seulement deux pères…",
 u"""Un certain Max chantait "♩ J'ai vu ta mère sur chat rouleeeeeeette ♫", vous êtes de sa famille ?""",
 u"""N'avait-on pas dit "pas les mamans" ?"""]
 
-# config pour les actions désagréables à Basile
-bad_action_triggers=[u"(frappe|cogne|tape)(| sur)",u"(démolit|dégomme|fouette|agresse|tabasse)",
-u"(vomit|pisse|chie|crache) sur",u"slap(|s)"]
+#: config pour les actions désagréables à Basile
+bad_action_triggers = [
+u"(frappe|cogne|tape)(| sur)",
+u"(démolit|dégomme|fouette|agresse|tabasse)",
+u"(vomit|pisse|chie|crache) sur",
+u"slap(|s)"]
 bad_action_answers=[
 u"Je ne peux pas dire que j'apprécie, mais je l'ai sans doute bien mérité.",
 u"{}: Pourquoi tant de violence en ce monde si doux ?",
@@ -144,33 +174,109 @@ u"{}: Entre nous, cela vous gratifie-t-il ?",
 u"{}: Une telle relation entre nous deux n'est pas saine, revenons à quelque chose de plus conventionnel. :D",
 u"J'ai la désagréable impression que {} cherche comment tuer le temps en ce moment…"
 ]
-bad_action_actions=[u"prend de la distance, par précaution…",u"esquive",u"est bon pour prendre une semaine de repos… virtuel !",u"n'aime pas servir de souffre douleur, mais n'a malheureusement pas le choix", u"s'en souviendra sans doute longtemps… de quoi parlait-on déjà ?"]
-
-# config pour les actions agréables à Basile
-good_action_triggers=[u"fait (:?des bisous|un c(?:â|a)lin|des c(?:â|a)lins) à",u"embrasse",u"c(?:â|a)line",u"caresse"]
-good_action_answers=[u":D",u"{}: Moi aussi je vous aime. ♡",u"Tant de délicatesse ne saurait être ignorée !",u"Pour une fois que quelqu'un me considère à ma juste valeur…"]
-good_action_actions=[u"ronronne",u"aimerait exprimer avec des mots simples le bonheur que {} lui procure !",u"éprouve une joie indescriptible",u"apprécie que des personnes comme {} soient sur IRC, sans quoi il n'y aurait sans doute jamais personne pour tenir compte de lui"]
-
-# config bonjour/bonsoir/que fais-tu encore debout à cette heure, gros sale !
-bonjour_triggers=[u"(s|)(a|'|)lu(t|)",u"hello",u"pl(o|i)p",u"pr(ou|ü)t",u"bonjour",u"bonsoir",u"coucou"]
-bonjour_answers=[u"Bien le bonjour, {}.",u"Bonjour {}.",u"{}: bonjour.",u"{}: Quel beau temps aujourd'hui (arrêtez-moi si je me trompe) !",u"Meteo: Cachan"]
-bonsoir_answers=[u"Bonsoir {} !",u"{}: bonsoir.",u"Quel beau te… euh… bonsoir !",u"{}: Je cherche désespérément une formule pour vous dire bonsoir, mais j'avoue que mon lexique est un peu… limité."]
-night_answers=[u"{}: vous m'avez fait peur, je m'étais assoupi !", u"Debout à une heure pareille, {} ? Que vous arrive-t-il ?",u"Vous venez prendre la relève, {} ?"]
+bad_action_actions = [u"prend de la distance, par précaution…", u"esquive", u"est bon pour prendre une semaine de repos… virtuel !", u"n'aime pas servir de souffre douleur, mais n'a malheureusement pas le choix", u"s'en souviendra sans doute longtemps… de quoi parlait-on déjà ?"]
+
+#: config pour les actions agréables à Basile
+good_action_triggers = [u"fait (:?des bisous|un c(?:â|a)lin|des c(?:â|a)lins) à", u"embrasse", u"c(?:â|a)line", u"caresse"]
+good_action_answers = [u":D", u"{}: Moi aussi je vous aime. ♡", u"Tant de délicatesse ne saurait être ignorée !", u"Pour une fois que quelqu'un me considère à ma juste valeur…"]
+good_action_actions = [u"ronronne", u"aimerait exprimer avec des mots simples le bonheur que {} lui procure !", u"éprouve une joie indescriptible", u"apprécie que des personnes comme {} soient sur IRC, sans quoi il n'y aurait sans doute jamais personne pour tenir compte de lui"]
+
+#: config bonjour/bonsoir/que fais-tu encore debout à cette heure, gros sale !
+bonjour_triggers = [u"(s|)(a|'|)lu(t|)", u"hello", u"pl(o|i)p", u"pr(ou|ü)t", u"bonjour", u"bonsoir", u"coucou"]
+bonjour_answers = [u"Bien le bonjour, {}.", u"Bonjour {}.", u"{}: bonjour.", u"{}: Quel beau temps aujourd'hui (arrêtez-moi si je me trompe) !", u"Meteo: Cachan"]
+bonsoir_answers = [u"Bonsoir {} !", u"{}: bonsoir.", u"Quel beau te… euh… bonsoir !", u"{}: Je cherche désespérément une formule pour vous dire bonsoir, mais j'avoue que mon lexique est un peu… limité."]
+night_answers = [u"{}: vous m'avez fait peur, je m'étais assoupi !", u"Debout à une heure pareille, {} ? Que vous arrive-t-il ?", u"Vous venez prendre la relève, {} ?"]
 daytime = [7,18]
 nighttime = [3, 6]
 
-# config dodo
-bonne_nuit_triggers=[u"bonne nuit",u"'?nite",u"'?nuit",u"'?night",u"good night",u"'?nenuit"]
-bonne_nuit_answers=[u"{}: thanks, make sweet dreams tonight ! ;)",u"Bonne nuit {}.",u"À demain {}. :)",u"{}: si seulement j'avais le droit de dormir… enfin, bonne nuit !",u"{}: à vous aussi !"]
+#: pan
+pan_triggers = [u"pan", u"bim", u"bang"]
 
-# config PEB est encore en train d'abuser de ses droits.
-kick_answers=[u"Suis-je de trop ici ?",u"{}: je m'excuse pour ce bruit indu qui a stimulé votre colère",u"{} a le /kick facile, sans doute la fatigue.",u"{}: j'ai l'impression que vous n'allez pas bien aujourd'hui, vous vous en prenez à un robot !"]
-kick_actions=[u"sera désormais exemplaire",u"prépare une lettre d'excuses à {}",u"essaiera de ne plus s'attirer les foudres de {}",u"croyait avoir tout bien fait… cruelle déception."]
+#: config dodo
+bonne_nuit_triggers = [u"bonne nuit", u"'?nite", u"'?nuit", u"'?night", u"good night", u"'?nenuit"]
+bonne_nuit_answers = [u"{}: thanks, make sweet dreams tonight ! ;)", u"Bonne nuit {}.", u"À demain {}. :)", u"{}: si seulement j'avais le droit de dormir… enfin, bonne nuit !", u"{}: à vous aussi !"]
 
-# config on m'a demandé de mourir/partir
-quit_messages=[u"Bien que cela me désole, je me vois dans l'obligation de vous abandonner."]
-leave_messages=quit_messages
+#: config PEB est encore en train d'abuser de ses droits.
+kick_answers = [u"Suis-je de trop ici ?", u"{}: je m'excuse pour ce bruit indu qui a stimulé votre colère", u"{} a le /kick facile, sans doute la fatigue.", u"{}: j'ai l'impression que vous n'allez pas bien aujourd'hui, vous vous en prenez à un robot !"]
+kick_actions = [u"sera désormais exemplaire", u"prépare une lettre d'excuses à {}", u"essaiera de ne plus s'attirer les foudres de {}", u"croyait avoir tout bien fait… cruelle déception."]
+
+#: config on m'a demandé de mourir/partir
+quit_messages = [u"Bien que cela me désole, je me vois dans l'obligation de vous abandonner."]
+leave_messages = quit_messages
 
 quit_fail_messages = [u"Navré, mais je me vois contraint de refuser, je ne peux pas céder aux exigences du premier venu."]
 leave_fail_messages = quit_fail_messages
 pas_programme_pour_tobeir = [u"Encore eût-il fallu que je fusse programmé pour vous obéir !"]
+
+#: Aide sur les commandes
+helpdico = {
+"help" : [u"""HELP <commande>
+ Affiche de l'aide sur la commande""", None, None],
+
+"identify" : [u"""IDENTIFY <username> <password>
+ Vérifie le mot de passe et me permet de savoir à l'avenir quel est votre pseudo note kfet.
+ Sans paramètre, je vous précise sous quel pseudo je vous connais.""", None, None],
+
+"drop" : [u"""DROP <password>
+ Vérifie le mot de passe et me fait d'oublier votre pseudo note kfet.""", None, None],
+
+"solde" : [u"""SOLDE
+ Affiche votre solde, si je connais votre pseudo note kfet.""",
+ """SOLDE <pseudo>
+ Affiche le solde de la personne désignée (par son pseudo note).""", None],
+
+"join" : [None, u"""JOIN <channel>
+ Me fait rejoindre le channel""", None],
+
+"leave" : [None, u"""LEAVE <channel>
+ Me fait quitter le channel (sauf s'il est dans ma stay_list).""", None],
+
+"quiet" : [None, u"""QUIET <channel>
+ Me rend silencieux sur le channel.""", None],
+
+"noquiet" : [None, u"""NOQUIET <channel>
+ Me rend la parole sur le channel.""", None],
+
+"lost" : [None, u"""LOST <channel>
+ Me fait perdre sur le channel.""", None],
+
+"reconnect" : [None, u"""RECONNECT
+ Établit à nouveau la connexion avec le serveur NK2015""", None],
+
+"reload" : [None, u"""RELOAD
+ Recharge la configuration.""", None],
+
+"say" : [None, None, u"""SAY <channel> <message>
+ Me fait parler sur le channel."""],
+
+"do" : [None, None, u"""DO <channel> <action>
+ Me fait faitre une action (/me) sur le channel."""],
+
+"stay" : [None, None, u"""STAY <channel>
+ Ajoute le channel à ma stay_list."""],
+
+"nostay" : [None, None, u"""NOSTAY <channel>
+ Retire le channel de ma stay_list."""],
+
+"ops" :  [None, None, u"""OPS
+ Affiche la liste des ops."""],
+
+"overops" : [None, None, u"""OVEROPS
+ Affiche la liste des overops."""],
+
+"kick" : [None, None, u"""KICK <channel> <pseudo> [<raison>]
+ Kicke <pseudo> du channel (Il faut bien entendu que j'y sois op)."""],
+
+"die" : [None, None, u"""DIE
+ Me déconnecte du serveur IRC."""],
+
+"crash" : [None, None, u"""CRASH
+ Me fait crasher"""]
+ }
+
+#: Message d'aide par défaut
+helpmsg_default = u"Liste des commandes disponibles :\nHELP IDENTIFY DROP SOLDE"
+#: Message d'aide par défaut à ajouter pour les OPs
+helpmsg_ops = u" JOIN LEAVE QUIET NOQUIET LOST RECONNECT RELOAD"
+#: Message d'aide par défaut à ajouter pour les OVEROPs
+helpmsg_overops = u" SAY DO STAY NOSTAY OPS OVEROPS KICK DIE CRASH"
diff --git a/identities.pickle b/identities.pickle
deleted file mode 100644 (file)
index 9d06eb8..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-(dp0
-S'Chopopope'
-p1
-S'chopopope'
-p2
-sS'quelu'
-p3
-S'quelu'
-p4
-sS'[20-100]'
-p5
-S'20-100'
-p6
-sS'PEB'
-p7
-S'peb'
-p8
-s.
\ No newline at end of file
diff --git a/nk.py b/nk.py
index c80adfd0ff303adc7e0be438292e4a06d6f80869..ecad88fd4a482357240b47d4947dd35790d1d2cb 100644 (file)
--- a/nk.py
+++ b/nk.py
@@ -15,7 +15,7 @@ import config
 class NKError(Exception):
     def __init__(self,msg):
         Exception.__init__(self)
-        self.msg=msg
+        self.msg = msg
     def __str__(self):
         return str(self.msg)
     def __unicode__(self):
@@ -31,42 +31,41 @@ class NKUnknownError(NKError):
     pass
 
 def connect():
-    sock=socket.socket()
+    sock = socket.socket()
     try:
         # On établit la connexion sur port 4242
         sock.connect((config.nk_server, config.nk_port))
         # On passe en SSL
-        sock=ssl.wrap_socket(sock,ca_certs='../keys/ca_.crt')
+        sock = ssl.wrap_socket(sock, ca_certs='../keys/ca_.crt')
         # On fait un hello
-        sock.write('["hello", "Basile"]')
+        sock.write(json.dumps(["hello", "Basile"]))
         # On récupère la réponse du hello
-        out=sock.read()
-        out=json.loads(out)
+        out = sock.read()
+        out = json.loads(out)
     except Exception as exc:
         # Si on a foiré quelque part, c'est que le serveur est down
         raise NKRefused(str(exc))
-    if out["retcode"]==0:
+    if out["retcode"] == 0:
         return sock
-    elif out["retcode"]==11:
+    elif out["retcode"] == 11:
         raise NKHelloFailed(out["errmsg"])
     else:
         raise NKUnknownError(out["errmsg"])
 
 
-def login(username,password,typ="bdd"):
-    sock=connect()
-    if typ=="special": # ça c'est pour Basile lui-même
-        masque='[]'
-    elif typ=="bdd":
-        masque='[[], [], true]'
+def login(username, password, typ="bdd"):
+    sock = connect()
+    if typ == "special": # ça c'est pour Basile lui-même
+        masque = []
+    elif typ == "bdd":
+        masque = [[], [], True]
     try:
         # Basile a un compte special user
-        commande='["login", [%s,%s,"%s",%s]]'%(json.dumps(username),json.dumps(password),typ,masque)
-        sock.write(commande)
-        out=sock.read()
+        commande = ["login", [username, password, typ, masque]]
+        sock.write(json.dumps(commande))
+        out = sock.read()
     except Exception as exc:
         # Si on a foiré quelque part, c'est que le serveur est down
         raise NKRefused(str(exc))
-    # On vérifie ensuite que le login
-    return json.loads(out),sock
+    return json.loads(out), sock