X-Git-Url: http://gitweb.pimeys.fr/?a=blobdiff_plain;f=nk.py;h=7cec40aec4bcd2a15924f604ff56213a168fe17f;hb=ee7a287b0f564671d100fa29ae0269c482ef4efe;hp=0ecf6f7c78ff9e3431bfaeef223306ae61304c88;hpb=a87c11b7881cce338b226c13e695300f84bd13d8;p=bots%2Fbasile.git diff --git a/nk.py b/nk.py index 0ecf6f7..7cec40a 100644 --- 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() @@ -97,7 +103,7 @@ def get_solde(sock, idbde, serv, canal): pseudo = ret["msg"]["pseudo"] return (True, solde, pseudo) else: - serv.privmsg(canal, ret["errmsg"]) + serv.privmsg(canal, ret["errmsg"].encode("utf-8")) return (False, None, None) except Exception as exc: trace = traceback.format_exc() @@ -107,3 +113,40 @@ def get_solde(sock, idbde, serv, canal): #log(self.serveur, "priv", auteur, " ".join(message) + "[failed]") return (False, None, None) +def consomme(sock, idbde, conso, serv, canal): + """Fais consommer une conso à l'utilisateur NK n°``idbde``""" + try: + sock.write(json.dumps(["get_boutons", ["", ""]])) + ret = full_read(sock) + retcode = ret["retcode"] + if retcode == 0: + boutons = ret["msg"] + 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.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 : %.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 + else: + serv.privmsg(canal, ret["errmsg"].encode("utf-8")) + return False + else: + serv.privmsg(canal, ret["errmsg"]) + except Exception as exc: + trace = traceback.format_exc() + msg = "failed\n%s" % trace + for l in msg.split("\n"): + serv.privmsg(canal, l) +