class NKUnknownError(NKError):
pass
+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 connect():
sock = socket.socket()
try:
# On fait un hello
sock.write(json.dumps(["hello", "Basile"]))
# On récupère la réponse du hello
- out = sock.read()
- out = json.loads(out)
+ out = full_read(sock)
except Exception as exc:
# Si on a foiré quelque part, c'est que le serveur est down
raise NKRefused(str(exc))
# Basile a un compte special user
commande = ["login", [username, password, typ, masque]]
sock.write(json.dumps(commande))
- out = sock.read()
+ out = full_read(sock)
except Exception as exc:
# Si on a foiré quelque part, c'est que le serveur est down
raise NKRefused(str(exc))
- return json.loads(out), sock
+ return out, sock
def get_solde(sock, idbde, serv, canal):
- """Récupère le (solde, pseudo, success) de l'utilisateur NK n°``idbde``"""
+ """Récupère le (success, solde, pseudo) de l'utilisateur NK n°``idbde``"""
try:
sock.write(json.dumps(["compte", idbde]))
- ret = json.loads(sock.read())
+ ret = full_read(sock)
retcode = ret["retcode"]
if retcode == 0:
solde = ret["msg"]["solde"]
#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)
+