]> gitweb.pimeys.fr Git - bots/basile.git/blobdiff - nk.py
Meteo : bot mort et enterré depuis longtemps
[bots/basile.git] / nk.py
diff --git a/nk.py b/nk.py
index 6de4691497ac52b34fa01a47940d567b82e74fa9..0aafbc16aff64606b07b40e5d5ccf0e6a6ea6e69 100644 (file)
--- a/nk.py
+++ b/nk.py
@@ -34,19 +34,25 @@ class NKUnknownError(NKError):
 class NKDeadServer(NKError):
     pass
 
-def full_read(sock):
-    """Lit sur la socket jusqu'à ce que l'output soit déJSON-izable"""
-    output = ""
-    i = 0
-    while True:
-        output += sock.read()
-        i += 1
-        try:
-            return json.loads(output)
-        except:
-            pass
-        if i == 10 and output == "":
-            raise NKDeadServer
+def full_read(socket):
+    # On récupère d'abord la taille du message
+    length_str = ''
+    char = socket.recv(1)
+    while char != '\n':
+        length_str += char
+        char = socket.recv(1)
+    total = int(length_str)
+    # On utilise une memoryview pour recevoir les données chunk par chunk efficacement
+    view = memoryview(bytearray(total))
+    next_offset = 0
+    while total - next_offset > 0:
+        recv_size = socket.recv_into(view[next_offset:], total - next_offset)
+        next_offset += recv_size
+    try:
+        msg = json.loads(view.tobytes())
+    except (TypeError, ValueError) as e:
+        raise NKNotJson("L'objet reçu n'est pas un JSON")
+    return msg
 
 def connect():
     sock = socket.socket()
@@ -86,25 +92,29 @@ def login(username, password, typ="bdd"):
         raise NKRefused(str(exc))
     return out, sock
 
-def get_solde(sock, idbde, serv, canal):
-    """Récupère le (success, solde, pseudo) de l'utilisateur NK n°``idbde``"""
+def get_infos(sock, idbde, serv, canal):
+    """Récupère les données de l'utilisateur NK n°``idbde``"""
     try:
         sock.write(json.dumps(["compte", idbde]))
         ret = full_read(sock)
         retcode = ret["retcode"]
         if retcode == 0:
-            solde = ret["msg"]["solde"]
-            pseudo = ret["msg"]["pseudo"]
-            return (True, solde, pseudo)
+            return ret["msg"]
         else:
-            serv.privmsg(canal, ret["errmsg"])
-            return (False, None, None)
+            serv.privmsg(canal, ret["errmsg"].encode("utf-8"))
     except Exception as exc:
         trace = traceback.format_exc()
         msg = "failed\n%s" % trace
         for l in msg.split("\n"):
             serv.privmsg(canal, l)
         #log(self.serveur, "priv", auteur, " ".join(message) + "[failed]")
+
+def get_solde(sock, idbde, serv, canal):
+    """Récupère le (success, solde, pseudo) de l'utilisateur NK n°``idbde``"""
+    infos = get_infos(sock, idbde, serv, canal)
+    if infos:
+        return (True, infos["solde"], infos["pseudo"])
+    else:
         return (False, None, None)
 
 def consomme(sock, idbde, conso, serv, canal):
@@ -115,18 +125,21 @@ def consomme(sock, idbde, conso, serv, canal):
         retcode = ret["retcode"]
         if retcode == 0:
             boutons = ret["msg"]
-            ibouton = [b["label"].lower() for b in boutons].index(conso.lower())
-            bouton = boutons[ibouton]
+            boutons = [b for b in boutons if b["label"].lower() == conso.lower()]
+            if len(boutons) == 0:
+                serv.privmsg(canal, (u"Impossible de trouver la conso %s" % (conso)).encode("utf-8"))
+                return False
+            bouton = boutons[0]
             sock.write(json.dumps(["consos", [[bouton["id"], idbde, 1]]]))
             ret = full_read(sock)
             if ret["retcode"] == 0:
                 [[retcode, [idbouton, idbde], errmsg]] = ret["msg"]
                 if retcode != 0:
-                    serv.privmsg(canal, errmsg)
+                    serv.privmsg(canal, errmsg.encode("utf-8"))
                 else:
                     success, solde, pseudo = get_solde(sock, idbde, serv, canal)
                     if success:
-                        serv.privmsg(canal, (u"%s consomme 1 %s (nouveau solde : %s)" % (pseudo, bouton["label"], solde)).encode("utf-8"))
+                        serv.privmsg(canal, (u"%s consomme 1 %s (nouveau solde : %.2f)" % (pseudo, bouton["label"], solde/100.0)).encode("utf-8"))
                     else:
                         serv.privmsg(canal, (u"%s consommé mais impossible de récupérer le solde après transaction." % (bouton["label"])).encode("utf-8"))
                     return True # on a réussi à consommer la conso