jaklis/jaklis.py

426 lines
13 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
2020-11-18 05:45:20 +01:00
2023-09-09 09:44:27 +02:00
import argparse, sys, os, string, random
from os.path import join, dirname
2020-11-18 05:45:20 +01:00
from shutil import copyfile
from dotenv import load_dotenv
2020-12-02 09:54:11 +01:00
from duniterpy.key import SigningKey
__version__ = "0.0.5"
2020-11-18 05:45:20 +01:00
2023-09-09 09:38:22 +02:00
MY_PATH = os.path.realpath(sys.argv[0]).replace("jaklis.py", "")
2020-12-05 03:15:05 +01:00
2020-11-24 07:42:47 +01:00
# Get variables environment
2023-09-09 09:38:22 +02:00
if not os.path.isfile(MY_PATH + ".env"):
copyfile(MY_PATH + ".env.template", MY_PATH + ".env")
dotenv_path = join(dirname(__file__), MY_PATH + ".env")
load_dotenv(dotenv_path)
# Set global values (default parameters) , regarding variables environments
2023-09-09 09:38:22 +02:00
node = os.getenv("DUNITER") + "/gva"
if not node:
2023-09-09 09:38:22 +02:00
node = "https://g1v1.p2p.legal/gva"
2023-09-09 09:38:22 +02:00
pod = os.getenv("ESNODE")
if not pod:
2023-09-09 09:38:22 +02:00
pod = "https://g1.data.e-is.pro"
destPubkey = False
2020-11-18 06:38:35 +01:00
# Parse arguments
2023-09-09 09:38:22 +02:00
parser = argparse.ArgumentParser(
description="Client CLI pour Cesium+ et Ḡchange",
epilog="current node: '" + node + "', current pod: '" + pod + "'.",
)
parser.add_argument(
"-v",
"--version",
action="store_true",
help="Affiche la version actuelle du programme",
)
parser.add_argument("-k", "--key", help="Chemin vers mon trousseau de clé (PubSec)")
parser.add_argument(
"-n", "--node", help="Adresse du noeud Cesium+, Gchange ou Duniter à utiliser"
)
2020-11-20 03:04:09 +01:00
2020-12-05 02:17:14 +01:00
subparsers = parser.add_subparsers(title="Commandes de jaklis", dest="cmd")
2023-09-09 09:38:22 +02:00
read_cmd = subparsers.add_parser("read", help="Lecture des messages")
send_cmd = subparsers.add_parser("send", help="Envoi d'un message")
delete_cmd = subparsers.add_parser("delete", help="Supression d'un message")
getProfile_cmd = subparsers.add_parser("get", help="Voir un profile Cesium+")
getPage_cmd = subparsers.add_parser("page", help="Voir une page Cesium+")
setProfile_cmd = subparsers.add_parser("set", help="Configurer son profile Cesium+")
eraseProfile_cmd = subparsers.add_parser("erase", help="Effacer son profile Cesium+")
stars_cmd = subparsers.add_parser(
"stars", help="Voir les étoiles d'un profile / Noter un profile (option -s NOTE)"
)
unstars_cmd = subparsers.add_parser("unstars", help="Supprimer un star")
getoffer_cmd = subparsers.add_parser(
"getoffer", help="Obtenir les informations d'une annonce gchange"
)
setoffer_cmd = subparsers.add_parser("setoffer", help="Créer une annonce gchange")
deleteoffer_cmd = subparsers.add_parser(
"deleteoffer", help="Supprimer une annonce gchange"
)
pay_cmd = subparsers.add_parser("pay", help="Payer en Ḡ1")
history_cmd = subparsers.add_parser(
"history", help="Voir l'historique des transactions d'un compte Ḡ1"
)
balance_cmd = subparsers.add_parser("balance", help="Voir le solde d'un compte Ḡ1")
id_cmd = subparsers.add_parser("id", help="Voir l'identité d'une clé publique/username")
id_balance_cmd = subparsers.add_parser(
"idBalance", help="Voir l'identité d'une clé publique/username et son solde"
)
currentUd = subparsers.add_parser(
"currentUd", help="Affiche la montant actuel du dividende Universel"
)
listWallets = subparsers.add_parser(
"listWallets", help="Liste de toutes les portefeuilles G1"
)
geolocProfiles = subparsers.add_parser(
"geolocProfiles", help="Obtenir le JSON de tous les comptes géolocalisés"
)
2020-11-20 03:04:09 +01:00
2020-12-02 08:04:04 +01:00
# Messages management
2023-09-09 09:38:22 +02:00
read_cmd.add_argument(
"-n", "--number", type=int, default=3, help="Affiche les NUMBER derniers messages"
)
read_cmd.add_argument("-j", "--json", action="store_true", help="Sort au format JSON")
read_cmd.add_argument(
"-o", "--outbox", action="store_true", help="Lit les messages envoyés"
)
send_cmd.add_argument(
"-d", "--destinataire", required=True, help="Destinataire du message"
)
send_cmd.add_argument("-t", "--titre", help="Titre du message à envoyer")
send_cmd.add_argument("-m", "--message", help="Message à envoyer")
send_cmd.add_argument(
"-f", "--fichier", help="Envoyer le message contenu dans le fichier 'FICHIER'"
)
send_cmd.add_argument(
"-o", "--outbox", action="store_true", help="Envoi le message sur la boite d'envoi"
)
delete_cmd.add_argument(
"-i",
"--id",
action="append",
nargs="+",
required=True,
help="ID(s) du/des message(s) à supprimer",
)
delete_cmd.add_argument(
"-o", "--outbox", action="store_true", help="Suppression d'un message envoyé"
)
2020-11-20 03:04:09 +01:00
2020-12-02 08:04:04 +01:00
# Profiles management
2023-09-09 09:38:22 +02:00
setProfile_cmd.add_argument("-n", "--name", help="Nom du profile")
setProfile_cmd.add_argument("-d", "--description", help="Description du profile")
setProfile_cmd.add_argument("-v", "--ville", help="Ville du profile")
setProfile_cmd.add_argument("-a", "--adresse", help="Adresse du profile")
setProfile_cmd.add_argument(
"-pos", "--position", nargs=2, help="Points géographiques (lat + lon)"
)
setProfile_cmd.add_argument("-s", "--site", help="Site web du profile")
setProfile_cmd.add_argument("-A", "--avatar", help="Chemin vers mon avatar en PNG")
getProfile_cmd.add_argument("-p", "--profile", help="Nom du profile")
getProfile_cmd.add_argument(
"-a",
"--avatar",
action="store_true",
help="Récupérer également l'avatar au format raw base64",
)
getPage_cmd.add_argument("-p", "--page", help="Nom de la page")
getPage_cmd.add_argument(
"-a",
"--avatar",
action="store_true",
help="Récupérer également l'avatar au format raw base64",
)
2022-10-23 03:31:27 +02:00
2020-12-02 08:04:04 +01:00
# Likes management
2023-09-09 09:38:22 +02:00
stars_cmd.add_argument("-p", "--profile", help="Profile cible")
stars_cmd.add_argument("-n", "--number", type=int, help="Nombre d'étoile")
unstars_cmd.add_argument("-p", "--profile", help="Profile à dénoter")
2020-12-02 08:04:04 +01:00
2021-02-14 18:18:01 +01:00
# Offers management
2023-09-09 09:38:22 +02:00
getoffer_cmd.add_argument("-i", "--id", help="Annonce cible à récupérer")
setoffer_cmd.add_argument("-t", "--title", help="Titre de l'annonce à créer")
setoffer_cmd.add_argument(
"-d", "--description", help="Description de l'annonce à créer"
)
setoffer_cmd.add_argument("-c", "--category", help="Categorie de l'annonce à créer")
setoffer_cmd.add_argument(
"-l",
"--localisation",
nargs=2,
help="Localisation de l'annonce à créer (lat + lon)",
)
setoffer_cmd.add_argument("-p", "--picture", help="Image de l'annonce à créer")
setoffer_cmd.add_argument("-ci", "--city", help="Ville de l'annonce à créer")
setoffer_cmd.add_argument("-pr", "--price", help="Prix de l'annonce à créer")
deleteoffer_cmd.add_argument("-i", "--id", help="Annonce cible à supprimer")
2021-02-14 18:18:01 +01:00
# GVA usage
2023-09-09 09:38:22 +02:00
pay_cmd.add_argument("-p", "--pubkey", help="Destinataire du paiement")
pay_cmd.add_argument("-a", "--amount", type=float, help="Montant de la transaction")
pay_cmd.add_argument(
"-c", "--comment", default="", help="Commentaire de la transaction", nargs="*"
)
pay_cmd.add_argument(
"-m", "--mempool", action="store_true", help="Utilise les sources en Mempool"
)
pay_cmd.add_argument(
"-v",
"--verbose",
action="store_true",
help="Affiche le résultat JSON de la transaction",
)
history_cmd.add_argument("-p", "--pubkey", help="Clé publique du compte visé")
history_cmd.add_argument(
"-n",
"--number",
type=int,
default=10,
help="Affiche les NUMBER dernières transactions",
)
history_cmd.add_argument(
"-j", "--json", action="store_true", help="Affiche le résultat en format JSON"
)
history_cmd.add_argument(
"--nocolors", action="store_true", help="Affiche le résultat en noir et blanc"
)
balance_cmd.add_argument("-p", "--pubkey", help="Clé publique du compte visé")
balance_cmd.add_argument(
"-m", "--mempool", action="store_true", help="Utilise les sources en Mempool"
)
id_cmd.add_argument("-p", "--pubkey", help="Clé publique du compte visé")
id_cmd.add_argument("-u", "--username", help="Username du compte visé")
id_balance_cmd.add_argument("-p", "--pubkey", help="Pubkey du compte visé")
currentUd.add_argument("-p", "--pubkey", help="Pubkey du compte visé")
listWallets.add_argument(
"-b", "--balance", action="store_true", help="Affiche les soldes"
)
listWallets.add_argument(
"--mbr", action="store_true", help="Affiche la liste de pubkey membres brut"
)
listWallets.add_argument(
"--non_mbr",
action="store_true",
help="Affiche la liste de pubkey des identités non membres brut",
)
listWallets.add_argument(
"--larf", action="store_true", help="Affiche la liste des pubkey non membres brut"
)
listWallets.add_argument(
"--brut", action="store_true", help="Affiche la liste de toutes les pubkey brut"
)
listWallets.add_argument("-p", "--pubkey", help="useless but needed")
2020-11-18 05:45:20 +01:00
args = parser.parse_args()
2020-12-05 01:34:30 +01:00
cmd = args.cmd
2020-11-18 05:45:20 +01:00
2020-11-22 03:09:30 +01:00
if args.version:
2023-09-09 09:38:22 +02:00
print(__version__)
sys.exit(0)
2020-11-22 03:09:30 +01:00
if not cmd:
parser.print_help()
sys.exit(1)
2023-09-09 09:38:22 +02:00
2020-12-02 09:54:11 +01:00
def createTmpDunikey():
# Generate pseudo-random nonce
2023-09-09 09:38:22 +02:00
nonce = []
2020-12-03 09:25:46 +01:00
for _ in range(32):
2020-12-02 09:54:11 +01:00
nonce.append(random.choice(string.ascii_letters + string.digits))
2023-09-09 09:38:22 +02:00
nonce = "".join(nonce)
2020-12-02 09:54:11 +01:00
keyPath = "/tmp/secret.dunikey-" + nonce
2021-08-27 22:59:16 +02:00
# key = SigningKey.from_credentials(getpass.getpass("Identifiant: "), getpass.getpass("Mot de passe: "), None)
2023-09-09 09:38:22 +02:00
key = SigningKey.from_credentials(
"sgse547yhd54xv6541srdh", "sfdgwdrhpkxdawsbszqpof1sdg65xc", None
)
2020-12-02 09:54:11 +01:00
key.save_pubsec_file(keyPath)
2020-12-02 09:54:11 +01:00
return keyPath
2023-09-09 09:38:22 +02:00
2020-12-08 23:15:24 +01:00
# Check if we need dunikey
try:
pubkey = args.pubkey
except:
pubkey = False
try:
profile = args.profile
except:
profile = False
2021-08-27 22:59:16 +02:00
# print(pubkey, profile)
2023-09-09 09:38:22 +02:00
if cmd in ("history", "balance", "get", "page", "id", "idBalance", "listWallets") and (
pubkey or profile
):
2020-12-08 23:15:24 +01:00
noNeedDunikey = True
2020-12-02 09:54:11 +01:00
keyPath = False
2020-12-08 23:15:24 +01:00
try:
dunikey = args.pubkey
except:
dunikey = args.profile
2020-12-03 09:09:18 +01:00
else:
2020-12-08 23:15:24 +01:00
noNeedDunikey = False
if args.key:
dunikey = args.key
2020-12-03 09:09:18 +01:00
keyPath = False
2020-12-08 23:15:24 +01:00
else:
2023-09-09 09:38:22 +02:00
dunikey = os.getenv("DUNIKEY")
2020-12-08 23:15:24 +01:00
if not dunikey:
keyPath = createTmpDunikey()
dunikey = keyPath
else:
keyPath = False
2020-12-03 09:09:18 +01:00
if not os.path.isfile(dunikey):
2020-12-08 23:15:24 +01:00
HOME = os.getenv("HOME")
dunikey = HOME + dunikey
if not os.path.isfile(dunikey):
2023-09-09 09:38:22 +02:00
sys.stderr.write(
"Le fichier de trousseau {0} est introuvable.\n".format(dunikey)
)
2020-12-08 23:15:24 +01:00
sys.exit(1)
2020-12-02 09:54:11 +01:00
# Construct CesiumPlus object
2023-09-09 09:38:22 +02:00
if cmd in (
"read",
"send",
"delete",
"set",
"get",
"page",
"erase",
"stars",
"unstars",
"getoffer",
"setoffer",
"deleteoffer",
"geolocProfiles",
):
from lib.cesium import CesiumPlus
2020-12-08 23:15:24 +01:00
if args.node:
pod = args.node
2020-12-08 23:15:24 +01:00
cesium = CesiumPlus(dunikey, pod, noNeedDunikey)
# Messaging
if cmd == "read":
cesium.read(args.number, args.outbox, args.json)
elif cmd == "send":
if args.fichier:
2023-09-09 09:38:22 +02:00
with open(args.fichier, "r") as f:
msgT = f.read()
2023-09-09 09:38:22 +02:00
titre = msgT.splitlines(True)[0].replace("\n", "")
msg = "".join(msgT.splitlines(True)[1:])
if args.titre:
titre = args.titre
msg = msgT
elif args.titre and args.message:
titre = args.titre
msg = args.message
else:
titre = input("Indiquez le titre du message: ")
msg = input("Indiquez le contenu du message: ")
cesium.send(titre, msg, args.destinataire, args.outbox)
elif cmd == "delete":
cesium.delete(args.id[0], args.outbox)
# Profiles
elif cmd == "set":
2023-09-09 09:38:22 +02:00
cesium.set(
args.name,
args.description,
args.ville,
args.adresse,
args.position,
args.site,
args.avatar,
)
elif cmd == "get":
cesium.get(args.profile, args.avatar)
2022-10-23 03:31:27 +02:00
elif cmd == "page":
cesium.getPage(args.page, args.avatar)
elif cmd == "erase":
cesium.erase()
2023-09-09 09:38:22 +02:00
elif cmd == "geolocProfiles":
cesium.geolocProfiles(node)
2020-12-15 19:53:25 +01:00
# Stars
elif cmd == "stars":
if args.number or args.number == 0:
cesium.like(args.number, args.profile)
else:
cesium.readLikes(args.profile)
2020-12-15 19:53:25 +01:00
elif cmd == "unstars":
cesium.unLike(args.profile)
2021-02-14 18:18:01 +01:00
# Offers
elif cmd == "getoffer":
cesium.getOffer(args.id)
elif cmd == "setoffer":
2023-09-09 09:38:22 +02:00
cesium.setOffer(
args.title,
args.description,
args.city,
args.localisation,
args.category,
args.price,
args.picture,
)
2021-02-14 18:18:01 +01:00
elif cmd == "deleteoffer":
cesium.deleteOffer(args.id)
# Construct GVA object
2023-09-09 09:38:22 +02:00
elif cmd in (
"pay",
"history",
"balance",
"id",
"idBalance",
"currentUd",
"listWallets",
):
from lib.gva import GvaApi
if args.node:
node = args.node
if args.pubkey:
destPubkey = args.pubkey
2020-12-08 23:15:24 +01:00
gva = GvaApi(dunikey, node, destPubkey, noNeedDunikey)
if cmd == "pay":
gva.pay(args.amount, args.comment, args.mempool, args.verbose)
elif cmd == "history":
2020-12-15 21:19:36 +01:00
gva.history(args.json, args.nocolors, args.number)
elif cmd == "balance":
gva.balance(args.mempool)
elif cmd == "id":
gva.id(args.pubkey, args.username)
2021-02-26 04:11:02 +01:00
elif cmd == "idBalance":
gva.idBalance(args.pubkey)
2021-06-30 06:10:48 +02:00
elif cmd == "currentUd":
gva.currentUd()
2021-08-27 05:02:16 +02:00
elif cmd == "listWallets":
2021-08-28 02:47:20 +02:00
gva.listWallets(args.brut, args.mbr, args.non_mbr, args.larf)
2020-12-02 08:04:04 +01:00
2020-12-02 09:54:11 +01:00
if keyPath:
os.remove(keyPath)