#!/usr/bin/env python3 import sys, re, os.path, json, ast, time from datetime import datetime from termcolor import colored from lib.natools import fmt, sign, get_privkey from gql import gql, Client from gql.transport.aiohttp import AIOHTTPTransport PUBKEY_REGEX = "(?![OIl])[1-9A-Za-z]{42,45}" class History: def __init__(self, dunikey, node, pubkey, useMempool=False): self.dunikey = dunikey self.pubkey = pubkey if pubkey else get_privkey(dunikey, "pubsec").pubkey self.useMempool = useMempool self.node = node if not re.match(PUBKEY_REGEX, self.pubkey) or len(self.pubkey) > 45: sys.stderr.write("La clé publique n'est pas au bon format.\n") sys.exit(1) # Define Duniter GVA node transport = AIOHTTPTransport(url=node) self.client = Client(transport=transport, fetch_schema_from_transport=True) def sendDoc(self): # Build TX generation document queryBuild = gql( """ query ($pubkey: String!){ transactionsHistory(pubkey: $pubkey) { received { writtenTime issuers outputs comment } sent { writtenTime issuers outputs comment } receiving { issuers outputs comment } sending { issuers outputs comment } } balance(script: $pubkey) { amount } } """ ) paramsBuild = { "pubkey": self.pubkey } # Send TX document try: self.historyDoc = self.client.execute(queryBuild, variable_values=paramsBuild) except Exception as e: message = ast.literal_eval(str(e))["message"] sys.stderr.write("Echec de récupération de l'historique:\n" + message + "\n") sys.exit(1) def parseHistory(self): res = self.historyDoc['transactionsHistory']['received'] transIn=[[0 for x in range(0)] for y in range(len(res))] for i, bloc in enumerate(res): for output in bloc['outputs']: if re.search(self.pubkey, output): transIn[i].append("IN") transIn[i].append(bloc['writtenTime']) transIn[i].append(bloc['issuers'][0]) transIn[i].append(int(output.split(':')[0])/100) transIn[i].append(bloc['comment']) res = self.historyDoc['transactionsHistory']['sent'] transOut=[[0 for x in range(0)] for y in range(len(res))] i = 0 for bloc in res: for output in bloc['outputs']: if not re.search(self.pubkey, output): transOut[i].append("OUT") transOut[i].append(bloc['writtenTime']) transOut[i].append(output.split("SIG(")[1].replace(')','')) transOut[i].append(int(output.split(':')[0])/100) transOut[i].append(bloc['comment']) i += 1 res = self.historyDoc['transactionsHistory']['receiving'] transInMempool=[[0 for x in range(0)] for y in range(len(res))] for i, bloc in enumerate(res): for output in bloc['outputs']: if re.search(self.pubkey, output): transInMempool[i].append("INM") transInMempool[i].append(int(time.time())) transInMempool[i].append(bloc['issuers'][0]) transInMempool[i].append(int(output.split(':')[0])/100) transInMempool[i].append(bloc['comment']) res = self.historyDoc['transactionsHistory']['sending'] transOutMempool=[[0 for x in range(0)] for y in range(len(res))] i = 0 for bloc in res: for output in bloc['outputs']: if not re.search(self.pubkey, output): transOutMempool[i].append("OUTM") transOutMempool[i].append(int(time.time())) transOutMempool[i].append(output.split("SIG(")[1].replace(')','')) transOutMempool[i].append(int(output.split(':')[0])/100) transOutMempool[i].append(bloc['comment']) i += 1 trans = transIn + transOut + transInMempool + transOutMempool trans = list(filter(None, trans)) trans.sort(key=lambda x: x[1]) # Get balance balance = self.historyDoc['balance']['amount']/100 # Get terminal size rows = int(os.popen('stty size', 'r').read().split()[1]) print('-'.center(rows, '-')) print("\033[1m{: <20} | {: <45} | {: <7} | {: <30}\033[0m".format(" Date"," De / À (clé publique)","Montant (Ḡ1)","Commentaire")) for i in trans: if i[0] == "IN": color = "green" elif i[0] == "INM": color = "yellow" elif i[0] == "OUTM": color = "red" else: color = "blue" date = datetime.fromtimestamp(i[1]).strftime("%d/%m/%Y à %H:%M") print('-'.center(rows, '-')) print(colored("| {: <18} | {: <45} | {: <9} | {: <30}".format(date, *i[2:]), color)) print('-'.center(rows, '-')) print('\033[1mSolde du compte: {0} Ḡ1\033[0m'.format(balance).center(rows, ' ')) print('-'.center(rows, '-')) print(colored('Reçus', 'green'), '-', colored('En cours de réception', 'yellow'), '-', colored('Envoyé', 'blue'), '-', colored("En cours d'envoi", 'red')) def history(self): self.sendDoc() self.parseHistory()