Commit af130c75 authored by matograine's avatar matograine
Browse files

Cleaning and documenting the script

parent d6c8c0ed
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Voir https://stackoverflow.com/questions/42009202/how-to-call-a-async-function-contained-in-a-class
# et : https://www.blog.pythonlibrary.org/2016/07/26/python-3-an-intro-to-asyncio/
# Pour le asyncio
# voir https://stackoverflow.com/questions/56042757/can-i-use-a-context-value-as-a-click-option-default
# pour le click context
from utils.common import Creating # Generator
from utils.retrieve import Retrieve, BackupRetrieve
from utils.utils import CheckConfig
......@@ -29,42 +22,43 @@ def help():
print ("Lors d'une récupération, les fichiers récupérés sont enregistrés dans {0}<année> en cas de transaction mal effectuée.\n".format(DEFAULT_FOLDER + BACKUP_FOLDER))
# main
if len(argv) > 1:
if argv[1] == "generer":
if len(argv) > 5 or len(argv) < 4:
print ("Erreur : information mal formatées.")
help()
else:
amount = float(argv[2])
pages = int(argv[3])
date = str(argv[4])
Creating (amount, date, pages).create()
if __name__ == "__main__":
if len(argv) > 1:
if argv[1] == "generer":
if len(argv) > 5 or len(argv) < 4:
print ("Erreur : information mal formatées.")
help()
else:
amount = float(argv[2])
pages = int(argv[3])
date = str(argv[4])
Creating (amount, date, pages).create()
elif argv[1] == "recuperer":
if len(argv) == 2:
Retrieve().retrieve()
elif len(argv) == 3:
Retrieve(folder=argv[2]).retrieve()
elif len(argv) == 4 and argv[2] == "fichier":
Retrieve(_file=argv[3]).retrieve()
elif len(argv) == 4 and argv[2] == "backup":
copy = BackupRetrieve(argv[3])
Retrieve(folder=copy.dest).retrieve()
copy.delete()
else:
print ("Erreur : information mal formatées.")
help()
elif argv[1] == "recuperer":
if len(argv) == 2:
Retrieve().retrieve()
elif len(argv) == 3:
Retrieve(folder=argv[2]).retrieve()
elif len(argv) == 4 and argv[2] == "fichier":
Retrieve(_file=argv[3]).retrieve()
elif len(argv) == 4 and argv[2] == "backup":
copy = BackupRetrieve(argv[3])
Retrieve(folder=copy.dest).retrieve()
copy.delete()
else:
print ("Erreur : information mal formatées.")
help()
elif argv[1] == "noeud":
if len(argv) != 4:
print ("Erreur : information mal formatées.")
help()
else:
CheckConfig().write_node_conf(argv[2], int(argv[3]))
elif argv[1] == "noeud":
if len(argv) != 4:
print ("Erreur : information mal formatées.")
help()
else:
CheckConfig().write_node_conf(argv[2], int(argv[3]))
help()
else:
else :
help()
else :
help()
......@@ -16,7 +16,7 @@ from duniterpy.key import SigningKey, ascii_armor
class Creating:
"""Generating, filling wallets"""
def __init__(self, amount, given_date, pages=1): # Pour les tests, sur 15 min par defaut.
def __init__(self, amount, given_date, pages=1):
if pages > MAX_PAGES:
message_exit("Erreur : Ğ1Don gère un maximum de 10 pages.")
self.pages = pages
......@@ -39,7 +39,6 @@ class Creating:
def __call__(self):
return self
#@coroutine
def create(self):
""" Generating, filling wallets."""
......@@ -55,11 +54,14 @@ class Creating:
self.transfer_error()
def transfer_error(self):
"""
transfer the newly created files to the backup folder.
"""
os.rename(self.pdf_output, self.backup_folder + self.output + PDF_EXTENSION)
os.rename(self.signed_output, self.backup_folder + self.output + SIGNED_EXTENSION)
print ("\nERREUR : Quelque chose s'est mal passé durant le transfert.\nLes fichiers {0}{1}/{2} ont été déplacés dans le dossier {3}.\nVérifiez si le transfert a bien eu lieu.\nVérifiez que le noeud Duniter est disponible.\n".format(self.output, PDF_EXTENSION, SIGNED_EXTENSION, self.backup_folder))
def save_json(self): #, key):
def save_json(self):
"""
write wallets data in an encrypted json file.
"""
......@@ -89,14 +91,3 @@ class Creating:
) as f:
f.write(signed_data)
# Ajouter la date au json
def tip_date(self):
"""
Set an expiring_date to custom delay.
Default is 6months.
"""
expiring_date = datetime.datetime.now().strftime("%Y-%m-%dT%Hh%M") # calculer + le délai
data = [{"expiring_date": expiring_date}] # for d in date] #self.wallets]
with open(self.output + "DATE_DEBUG_" + ".json", "w") as f:
f.write(json.dumps(data, indent=4))
......@@ -10,20 +10,6 @@ import json
import qrcode
import datetime
# Utiliser help(module) dans une console python pour avoir de l'aide.
# Dictionnaire : https://science-emergence.com/Articles/Utiliser-les-dictionnaires-de-python-tutoriel/
# Json : https://gist.github.com/YannBouyeron/39fafc26b94dfc459589c8d9e82637b6
## En fait, vu que ce programme est beaucoup moins complexe que Silkaj, j'ai peut-être intérêt à copier certaines parties de Silkaj,
## Et écrire directement les fichiers de tx.
## Juste les fonctions nécessaires pour :
## * Balance depuisune pubkey
## * send multi-tx
## * send multi-inputs
## De façon à enlever le besoin de Click.
## Avant ça, faut séparer les fonctions pour que ce soit plus propre.
class Generator:
"""Generate some wallets, create the pdf to print"""
......@@ -37,6 +23,9 @@ class Generator:
self.c = None
def generate(self):
"""
generate tips wallets ; then create the pdf file
"""
for i in range(self.pages):
for j in range(6): # 6 wallets per pages
self.new_wallet()
......@@ -44,6 +33,9 @@ class Generator:
self.make_pdf()
def new_wallet(self):
"""
generate one wallet with the associated images
"""
# Generating credentials
salt = diceware(3, separator="-", camelcase=False)
password = diceware(3, separator="-", camelcase=False)
......@@ -109,6 +101,9 @@ class Generator:
)
def gen_page(self, wallets):
"""
generate a pdf page from a wallet list with relevant images.
"""
# Create a new canvas
if self.c == None:
self.c = canvas.Canvas(self.output)
......
# This file should contain functions to get back tips after expiring_date.
......@@ -20,8 +20,13 @@ from utils.silkaj.constants import PUBKEY_PATTERN
class Retrieve():
"""
Retrieve wallets from encrypted files
"""
def __init__(self, folder=None, _file=None):
"""
check given values and set self values.
"""
if folder == None and _file == None:
self.folder = os.path.expanduser(DEFAULT_FOLDER + WALLETS_FOLDER)
......@@ -42,9 +47,11 @@ class Retrieve():
with open(file) as wallets_json:
return json.load(wallets_json)
# this function might not be necessary anymore
def get_key_list(self, retrieve_wallets):
issuers_keys, issuers = list(), list()
"""
create key for each wallet
"""
issuers_keys = list()
for wallet in retrieve_wallets:
key = auth_by_scrypt_with_IDs(wallet['salt'], wallet['password'])
issuers_keys.append(key)
......@@ -58,6 +65,9 @@ class Retrieve():
return True
def get_pubkey(self, pubkey):
"""
get credentials for each creator account
"""
while True:
print("\nEntrez les identifiants pour les clef publique : {0}\nSi vous ne savez pas, entrez des identifiants vides.".format(pubkey))
key = auth_by_scrypt(None)
......@@ -70,6 +80,9 @@ class Retrieve():
def sort_folder(self, retrieve_files):
"""
sorts retrievable files
"""
# get all files from folder
file_list = list()
for root, dirs, files in os.walk(self.folder):
......@@ -85,6 +98,10 @@ class Retrieve():
message_exit("Aucun don n'est périmé.")
def extract_files(self, doc, retrieve_files):
"""
extracts wallets data from each readable file and adds it to retrieve_files.
each found pubkey will be a ["key"] for retrieve_files dict and will contain all relevant wallets data.
"""
if os.path.isfile(doc):
try:
pubkey, content = self.open_data(doc)
......@@ -105,6 +122,9 @@ class Retrieve():
@coroutine
async def retrieve(self):
"""
retrieve money from perished tips
"""
client = ClientInstance().client
error = False
retrieve_files = dict()
......@@ -129,6 +149,9 @@ class Retrieve():
await client.close()
def open_data(self, _file):
"""
open encrypted data
"""
data_file = open(_file, "r")
signed_data = data_file.read()
pubkey = re.search(re.compile(PUBKEY_PATTERN), signed_data).group()
......@@ -137,6 +160,9 @@ class Retrieve():
return pubkey, json.loads(data["message"]["content"])
async def retrieve_wallets(self, content, key):
"""
send money from wallets
"""
try :
encrypted_wallets = content["wallets"]
retrieving_wallets = ascii_armor.AsciiArmor.parse(encrypted_wallets, key)
......@@ -157,7 +183,7 @@ class Retrieve():
#create lists : keys, issuers, amount
_range, intermediatetransaction = 0, 0
for a in range (0, len(issuers_keys)):
print(a, _range) #debug
# print(a, _range) #debug
# get inputs from all issuers
listinput_and_amount = await get_list_input_for_transaction(_range, issuers_keys[a].pubkey, len(listinput))
# print each empty G1Don
......@@ -170,7 +196,6 @@ class Retrieve():
listinput.extend(listinput_and_amount[0])
amount = amount + listinput_and_amount[1]
intermediatetransaction = listinput_and_amount[2]
# eventuellement pop() les pubkeys vides ici ?
# send transactions (intermediate if necessary)
if intermediatetransaction or (issuers_keys[a] == issuers_keys[-1] and amount !=0):
# if a wallet has a lot of sources, we want to use all sources in many transactions.
......@@ -196,6 +221,9 @@ class Retrieve():
retrieving_wallets.pop(0)
class BackupRetrieve():
"""
prepare the retrieval of backups.
"""
def __init__(self, year):
year = self.check_year(year)
self.orig = os.path.expanduser(DEFAULT_FOLDER + BACKUP_FOLDER + year)
......
......@@ -6,6 +6,10 @@ import re
from utils.constants import DEFAULT_FOLDER, WALLETS_FOLDER, BACKUP_FOLDER, PDF_BACKUP_FOLDER, PDF_EXTENSION, SIGNED_EXTENSION, CONF_FILE
def check_date(given_date):
"""
check if a given peremption date is correctly formatted.
if in the past, asks for user validation.
"""
infos_date = given_date.split("/")
if len(infos_date) != 3 or len(infos_date[2]) != 4 or len(infos_date[0]) != 2 or len(infos_date[1]) != 2:
print ("Erreur : le champs <date> doit être de forme JJ/MM/YYYY")
......@@ -26,6 +30,9 @@ def check_date(given_date):
class CheckConfig():
"""
check that the config exists. If not, create relevant folders.
"""
def __init__(self):
self.folder = os.path.expanduser(DEFAULT_FOLDER)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment