Mesh decentralized Unified P2P Fat Protocol Layer. Connectors between Libre Money, ScuttleButt, IPFS, ... Salamalec between Nodes and Human.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

209 lines
7.6 KiB

#!/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):
self.dunikey = dunikey
self.pubkey = pubkey if pubkey else get_privkey(dunikey, "pubsec").pubkey
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 history 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
base
}
node {
peer {
currency
}
}
currentUd {
amount
base
}
}
"""
)
paramsBuild = {
"pubkey": self.pubkey
}
# Send history 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):
trans = []
i = 0
currentBase = int(self.historyDoc['currentUd']['base'])
self.UD = self.historyDoc['currentUd']['amount']/100
for sens in 'received','sent','receiving','sending':
res = self.historyDoc['transactionsHistory'][sens]
for bloc in res:
output = bloc['outputs'][0]
outPubkey = output.split("SIG(")[1].replace(')','')
if sens in ('received','receiving') or self.pubkey != outPubkey:
trans.append(i)
trans[i] = []
trans[i].append(sens)
if sens in ('receiving','sending'):
trans[i].append(int(time.time()))
else:
trans[i].append(bloc['writtenTime'])
if sens in ('sent','sending'):
trans[i].append(outPubkey)
amount = int('-' + output.split(':')[0])
else:
trans[i].append(bloc['issuers'][0])
amount = int(output.split(':')[0])
base = int(output.split(':')[1])
applyBase = base-currentBase
amount = round(amount*pow(10,applyBase)/100, 2)
# if referential == 'DU': amount = round(amount/UD, 2)
trans[i].append(amount)
trans[i].append(round(amount/self.UD, 2))
trans[i].append(bloc['comment'])
trans[i].append(base)
i += 1
# Order transactions by date
trans.sort(key=lambda x: x[1])
# Keep only base if there is base change
lastBase = 0
for i in trans:
if i[6] == lastBase: i[6] = None
else: lastBase = i[6]
return trans
def printHistory(self, trans, noColors):
# Get balance
balance = self.historyDoc['balance']['amount']/100
balanceUD = round(balance/self.UD, 2)
# Get currency
currency = self.historyDoc['node']['peer']['currency']
if currency == 'g1': currency = 'Ḡ1'
elif currency == 'g1-test': currency = 'GT'
# if referential == 'DU': currency = 'DU/' + currency.lower()
# Get terminal size
rows = int(os.popen('stty size', 'r').read().split()[1])
# Display history
print('+', end='')
print('-'.center(rows-1, '-'))
if noColors: isBold = isBoldEnd = ''
else:
isBold = '\033[1m'
isBoldEnd = '\033[0m'
print(isBold + "|{: <19} | {: <12} | {: <7} | {: <7} | {: <30}".format(" Date"," De / À"," {0}".format(currency)," DU/{0}".format(currency.lower()),"Commentaire") + isBoldEnd)
print('|', end='')
for t in trans:
if t[0] == "received": color = "green"
elif t[0] == "receiving": color = "yellow"
elif t[0] == "sending": color = "red"
else: color = "blue"
if noColors:
color = None
if t[0] in ('receiving','sending'):
comment = '(EN ATTENTE) ' + t[5]
else:
comment = t[5]
else:
comment = t[5]
date = datetime.fromtimestamp(t[1]).strftime("%d/%m/%Y à %H:%M")
print('-'.center(rows-1, '-'))
if t[6]:
print('|', end='')
print(' Changement de base : {0} '.format(t[6]).center(rows-1, '#'))
print('|', end='')
print('-'.center(rows-1, '-'))
print('|', end='')
printKey = t[2][0:8] + '\u2026' + t[2][-3:]
if noColors:
print(" {: <18} | {: <12} | {: <7} | {: <7} | {: <30}".format(date, printKey, t[3], t[4], comment))
else:
print(colored(" {: <18} | {: <12} | {: <7} | {: <7} | {: <30}".format(date, printKey, t[3], t[4], comment), color))
print('|', end='')
print('-'.center(rows-1, '-'))
print('|', end='')
print(isBold + 'Solde du compte: {0} {1} ({2} DU/{3})'.format(balance, currency, balanceUD, currency.lower()).center(rows-1, ' ') + isBoldEnd)
print('+', end='')
print(''.center(rows-1, '-'))
if not noColors:
print(colored('Reçus', 'green'), '-', colored('En cours de réception', 'yellow'), '-', colored('Envoyé', 'blue'), '-', colored("En cours d'envoi", 'red'))
return trans
def jsonHistory(self, transList):
dailyJSON = []
for i, trans in enumerate(transList):
dailyJSON.append(i)
dailyJSON[i] = {}
dailyJSON[i]['date'] = trans[1]
dailyJSON[i]['pubkey'] = trans[2]
dailyJSON[i]['amount'] = trans[3]
dailyJSON[i]['amountUD'] = trans[4]
dailyJSON[i]['comment'] = trans[5]
dailyJSON = json.dumps(dailyJSON, indent=2)
# If we want to write JSON to a file
#jsonFile = open("history-{0}.json".format(self.pubkey[0:8]), "w")
#jsonFile.writelines(dailyJSON + '\n')
#jsonFile.close()
return dailyJSON