Compare commits

...

4 Commits

Author SHA1 Message Date
poka b1049bd7b7 Merge branch 'refactoGeolocProfiles' 2023-09-09 09:50:52 +02:00
poka 2c5435a18b add sublevel in json, with timestamp 2023-09-09 09:50:20 +02:00
poka 51ae54484c remove unused imports 2023-09-09 09:44:27 +02:00
poka e0ba392671 add geolocProfiles command 2023-09-09 09:38:22 +02:00
5 changed files with 552 additions and 222 deletions

348
jaklis.py
View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse, sys, os, getpass, string, random import argparse, sys, os, string, random
from os.path import join, dirname from os.path import join, dirname
from shutil import copyfile from shutil import copyfile
from dotenv import load_dotenv from dotenv import load_dotenv
@ -8,147 +8,249 @@ from duniterpy.key import SigningKey
__version__ = "0.0.5" __version__ = "0.0.5"
MY_PATH = os.path.realpath(sys.argv[0]).replace('jaklis.py','') MY_PATH = os.path.realpath(sys.argv[0]).replace("jaklis.py", "")
# Get variables environment # Get variables environment
if not os.path.isfile(MY_PATH + '.env'): if not os.path.isfile(MY_PATH + ".env"):
copyfile(MY_PATH + ".env.template",MY_PATH + ".env") copyfile(MY_PATH + ".env.template", MY_PATH + ".env")
dotenv_path = join(dirname(__file__),MY_PATH + '.env') dotenv_path = join(dirname(__file__), MY_PATH + ".env")
load_dotenv(dotenv_path) load_dotenv(dotenv_path)
# Set global values (default parameters) , regarding variables environments # Set global values (default parameters) , regarding variables environments
node = os.getenv('DUNITER') + '/gva' node = os.getenv("DUNITER") + "/gva"
if not node: if not node:
node="https://g1v1.p2p.legal/gva" node = "https://g1v1.p2p.legal/gva"
pod = os.getenv('ESNODE') pod = os.getenv("ESNODE")
if not pod: if not pod:
pod="https://g1.data.e-is.pro" pod = "https://g1.data.e-is.pro"
destPubkey = False destPubkey = False
# Parse arguments # Parse arguments
parser = argparse.ArgumentParser(description="Client CLI pour Cesium+ et Ḡchange", epilog="current node: '" + node + "', current pod: '" + pod + "'.") parser = argparse.ArgumentParser(
parser.add_argument('-v', '--version', action='store_true', help="Affiche la version actuelle du programme") description="Client CLI pour Cesium+ et Ḡchange",
parser.add_argument('-k', '--key', help="Chemin vers mon trousseau de clé (PubSec)") epilog="current node: '" + node + "', current pod: '" + pod + "'.",
parser.add_argument('-n', '--node', help="Adresse du noeud Cesium+, Gchange ou Duniter à utiliser") )
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"
)
subparsers = parser.add_subparsers(title="Commandes de jaklis", dest="cmd") subparsers = parser.add_subparsers(title="Commandes de jaklis", dest="cmd")
read_cmd = subparsers.add_parser('read', help="Lecture des messages") read_cmd = subparsers.add_parser("read", help="Lecture des messages")
send_cmd = subparsers.add_parser('send', help="Envoi d'un message") send_cmd = subparsers.add_parser("send", help="Envoi d'un message")
delete_cmd = subparsers.add_parser('delete', help="Supression 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+") getProfile_cmd = subparsers.add_parser("get", help="Voir un profile Cesium+")
getPage_cmd = subparsers.add_parser('page', help="Voir une page Cesium+") getPage_cmd = subparsers.add_parser("page", help="Voir une page Cesium+")
setProfile_cmd = subparsers.add_parser('set', help="Configurer son profile Cesium+") setProfile_cmd = subparsers.add_parser("set", help="Configurer son profile Cesium+")
eraseProfile_cmd = subparsers.add_parser('erase', help="Effacer 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)") stars_cmd = subparsers.add_parser(
unstars_cmd = subparsers.add_parser('unstars', help="Supprimer un star") "stars", help="Voir les étoiles d'un profile / Noter un profile (option -s NOTE)"
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") unstars_cmd = subparsers.add_parser("unstars", help="Supprimer un star")
deleteoffer_cmd = subparsers.add_parser('deleteoffer', help="Supprimer une annonce gchange") getoffer_cmd = subparsers.add_parser(
pay_cmd = subparsers.add_parser('pay', help="Payer en Ḡ1") "getoffer", help="Obtenir les informations d'une annonce gchange"
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") setoffer_cmd = subparsers.add_parser("setoffer", help="Créer une annonce gchange")
id_cmd = subparsers.add_parser('id', help="Voir l'identité d'une clé publique/username") deleteoffer_cmd = subparsers.add_parser(
id_balance_cmd = subparsers.add_parser('idBalance', help="Voir l'identité d'une clé publique/username et son solde") "deleteoffer", help="Supprimer une annonce gchange"
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") 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"
)
# Messages management # Messages management
read_cmd.add_argument('-n', '--number',type=int, default=3, help="Affiche les NUMBER derniers messages") read_cmd.add_argument(
read_cmd.add_argument('-j', '--json', action='store_true', help="Sort au format JSON") "-n", "--number", type=int, default=3, help="Affiche les NUMBER derniers messages"
read_cmd.add_argument('-o', '--outbox', action='store_true', help="Lit les messages envoyés") )
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(
send_cmd.add_argument('-t', '--titre', help="Titre du message à envoyer") "-d", "--destinataire", required=True, help="Destinataire du message"
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("-t", "--titre", help="Titre du message à envoyer")
send_cmd.add_argument('-o', '--outbox', action='store_true', help="Envoi le message sur la boite d'envoi") 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(
delete_cmd.add_argument('-o', '--outbox', action='store_true', help="Suppression d'un message envoyé") "-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é"
)
# Profiles management # Profiles management
setProfile_cmd.add_argument('-n', '--name', help="Nom du profile") setProfile_cmd.add_argument("-n", "--name", help="Nom du profile")
setProfile_cmd.add_argument('-d', '--description', help="Description 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("-v", "--ville", help="Ville du profile")
setProfile_cmd.add_argument('-a', '--adresse', help="Adresse 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(
setProfile_cmd.add_argument('-s', '--site', help="Site web du profile") "-pos", "--position", nargs=2, help="Points géographiques (lat + lon)"
setProfile_cmd.add_argument('-A', '--avatar', help="Chemin vers mon avatar en PNG") )
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("-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") 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("-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") getPage_cmd.add_argument(
"-a",
"--avatar",
action="store_true",
help="Récupérer également l'avatar au format raw base64",
)
# Likes management # Likes management
stars_cmd.add_argument('-p', '--profile', help="Profile cible") stars_cmd.add_argument("-p", "--profile", help="Profile cible")
stars_cmd.add_argument('-n', '--number', type=int, help="Nombre d'étoile") stars_cmd.add_argument("-n", "--number", type=int, help="Nombre d'étoile")
unstars_cmd.add_argument('-p', '--profile', help="Profile à dénoter") unstars_cmd.add_argument("-p", "--profile", help="Profile à dénoter")
# Offers management # Offers management
getoffer_cmd.add_argument('-i', '--id', help="Annonce cible à récupérer") 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("-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(
setoffer_cmd.add_argument('-c', '--category', help="Categorie de l'annonce à créer") "-d", "--description", help="Description 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("-c", "--category", help="Categorie de l'annonce à créer")
setoffer_cmd.add_argument('-ci', '--city', help="Ville de l'annonce à créer") setoffer_cmd.add_argument(
setoffer_cmd.add_argument('-pr', '--price', help="Prix de l'annonce à créer") "-l",
deleteoffer_cmd.add_argument('-i', '--id', help="Annonce cible à supprimer") "--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")
# GVA usage # GVA usage
pay_cmd.add_argument('-p', '--pubkey', help="Destinataire du paiement") 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("-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(
pay_cmd.add_argument('-m', '--mempool', action='store_true', help="Utilise les sources en Mempool") "-c", "--comment", default="", help="Commentaire de la transaction", nargs="*"
pay_cmd.add_argument('-v', '--verbose', action='store_true', help="Affiche le résultat JSON de la transaction") )
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("-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(
history_cmd.add_argument('-j', '--json', action='store_true', help="Affiche le résultat en format JSON") "-n",
history_cmd.add_argument('--nocolors', action='store_true', help="Affiche le résultat en noir et blanc") "--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("-p", "--pubkey", help="Clé publique du compte visé")
balance_cmd.add_argument('-m', '--mempool', action='store_true', help="Utilise les sources en Mempool") balance_cmd.add_argument(
id_cmd.add_argument('-p', '--pubkey', help="Clé publique du compte visé") "-m", "--mempool", action="store_true", help="Utilise les sources en Mempool"
id_cmd.add_argument('-u', '--username', help="Username du compte visé") )
id_balance_cmd.add_argument('-p', '--pubkey', help="Pubkey du compte visé") id_cmd.add_argument("-p", "--pubkey", help="Clé publique du compte visé")
currentUd.add_argument('-p', '--pubkey', help="Pubkey du compte visé") id_cmd.add_argument("-u", "--username", help="Username du compte visé")
listWallets.add_argument('-b', '--balance', action='store_true', help="Affiche les soldes") id_balance_cmd.add_argument("-p", "--pubkey", help="Pubkey du compte visé")
listWallets.add_argument('--mbr', action='store_true', help="Affiche la liste de pubkey membres brut") currentUd.add_argument("-p", "--pubkey", help="Pubkey du compte visé")
listWallets.add_argument('--non_mbr', action='store_true', help="Affiche la liste de pubkey des identités non membres brut") listWallets.add_argument(
listWallets.add_argument('--larf', action='store_true', help="Affiche la liste des pubkey non membres brut") "-b", "--balance", action="store_true", help="Affiche les soldes"
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") 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")
args = parser.parse_args() args = parser.parse_args()
cmd = args.cmd cmd = args.cmd
if args.version: if args.version:
print(__version__) print(__version__)
sys.exit(0) sys.exit(0)
if not cmd: if not cmd:
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)
def createTmpDunikey(): def createTmpDunikey():
# Generate pseudo-random nonce # Generate pseudo-random nonce
nonce=[] nonce = []
for _ in range(32): for _ in range(32):
nonce.append(random.choice(string.ascii_letters + string.digits)) nonce.append(random.choice(string.ascii_letters + string.digits))
nonce = ''.join(nonce) nonce = "".join(nonce)
keyPath = "/tmp/secret.dunikey-" + nonce keyPath = "/tmp/secret.dunikey-" + nonce
# key = SigningKey.from_credentials(getpass.getpass("Identifiant: "), getpass.getpass("Mot de passe: "), None) # key = SigningKey.from_credentials(getpass.getpass("Identifiant: "), getpass.getpass("Mot de passe: "), None)
key = SigningKey.from_credentials("sgse547yhd54xv6541srdh", "sfdgwdrhpkxdawsbszqpof1sdg65xc", None) key = SigningKey.from_credentials(
"sgse547yhd54xv6541srdh", "sfdgwdrhpkxdawsbszqpof1sdg65xc", None
)
key.save_pubsec_file(keyPath) key.save_pubsec_file(keyPath)
return keyPath return keyPath
# Check if we need dunikey # Check if we need dunikey
try: try:
pubkey = args.pubkey pubkey = args.pubkey
@ -160,7 +262,9 @@ except:
profile = False profile = False
# print(pubkey, profile) # print(pubkey, profile)
if cmd in ('history','balance','get','page','id','idBalance','listWallets') and (pubkey or profile): if cmd in ("history", "balance", "get", "page", "id", "idBalance", "listWallets") and (
pubkey or profile
):
noNeedDunikey = True noNeedDunikey = True
keyPath = False keyPath = False
try: try:
@ -173,7 +277,7 @@ else:
dunikey = args.key dunikey = args.key
keyPath = False keyPath = False
else: else:
dunikey = os.getenv('DUNIKEY') dunikey = os.getenv("DUNIKEY")
if not dunikey: if not dunikey:
keyPath = createTmpDunikey() keyPath = createTmpDunikey()
dunikey = keyPath dunikey = keyPath
@ -183,12 +287,28 @@ else:
HOME = os.getenv("HOME") HOME = os.getenv("HOME")
dunikey = HOME + dunikey dunikey = HOME + dunikey
if not os.path.isfile(dunikey): if not os.path.isfile(dunikey):
sys.stderr.write('Le fichier de trousseau {0} est introuvable.\n'.format(dunikey)) sys.stderr.write(
"Le fichier de trousseau {0} est introuvable.\n".format(dunikey)
)
sys.exit(1) sys.exit(1)
# Construct CesiumPlus object # Construct CesiumPlus object
if cmd in ("read","send","delete","set","get","page","erase","stars","unstars","getoffer","setoffer","deleteoffer"): if cmd in (
"read",
"send",
"delete",
"set",
"get",
"page",
"erase",
"stars",
"unstars",
"getoffer",
"setoffer",
"deleteoffer",
"geolocProfiles",
):
from lib.cesium import CesiumPlus from lib.cesium import CesiumPlus
if args.node: if args.node:
@ -201,10 +321,10 @@ if cmd in ("read","send","delete","set","get","page","erase","stars","unstars","
cesium.read(args.number, args.outbox, args.json) cesium.read(args.number, args.outbox, args.json)
elif cmd == "send": elif cmd == "send":
if args.fichier: if args.fichier:
with open(args.fichier, 'r') as f: with open(args.fichier, "r") as f:
msgT = f.read() msgT = f.read()
titre = msgT.splitlines(True)[0].replace('\n', '') titre = msgT.splitlines(True)[0].replace("\n", "")
msg = ''.join(msgT.splitlines(True)[1:]) msg = "".join(msgT.splitlines(True)[1:])
if args.titre: if args.titre:
titre = args.titre titre = args.titre
msg = msgT msg = msgT
@ -222,13 +342,23 @@ if cmd in ("read","send","delete","set","get","page","erase","stars","unstars","
# Profiles # Profiles
elif cmd == "set": elif cmd == "set":
cesium.set(args.name, args.description, args.ville, args.adresse, args.position, args.site, args.avatar) cesium.set(
args.name,
args.description,
args.ville,
args.adresse,
args.position,
args.site,
args.avatar,
)
elif cmd == "get": elif cmd == "get":
cesium.get(args.profile, args.avatar) cesium.get(args.profile, args.avatar)
elif cmd == "page": elif cmd == "page":
cesium.getPage(args.page, args.avatar) cesium.getPage(args.page, args.avatar)
elif cmd == "erase": elif cmd == "erase":
cesium.erase() cesium.erase()
elif cmd == "geolocProfiles":
cesium.geolocProfiles(node)
# Stars # Stars
elif cmd == "stars": elif cmd == "stars":
@ -243,12 +373,28 @@ if cmd in ("read","send","delete","set","get","page","erase","stars","unstars","
elif cmd == "getoffer": elif cmd == "getoffer":
cesium.getOffer(args.id) cesium.getOffer(args.id)
elif cmd == "setoffer": elif cmd == "setoffer":
cesium.setOffer(args.title, args.description, args.city, args.localisation, args.category, args.price, args.picture) cesium.setOffer(
args.title,
args.description,
args.city,
args.localisation,
args.category,
args.price,
args.picture,
)
elif cmd == "deleteoffer": elif cmd == "deleteoffer":
cesium.deleteOffer(args.id) cesium.deleteOffer(args.id)
# Construct GVA object # Construct GVA object
elif cmd in ("pay","history","balance","id","idBalance","currentUd","listWallets"): elif cmd in (
"pay",
"history",
"balance",
"id",
"idBalance",
"currentUd",
"listWallets",
):
from lib.gva import GvaApi from lib.gva import GvaApi
if args.node: if args.node:

View File

@ -1,17 +1,19 @@
import json
import re, string, random, base64 import re, string, random, base64
from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX
from lib.geolocProfiles import GeolocProfiles
from lib.getPages import Pages from lib.getPages import Pages
from lib.messaging import ReadFromCesium, SendToCesium, DeleteFromCesium from lib.messaging import ReadFromCesium, SendToCesium, DeleteFromCesium
from lib.profiles import Profiles from lib.profiles import Profiles
from lib.stars import ReadLikes, SendLikes, UnLikes from lib.stars import ReadLikes, SendLikes, UnLikes
from lib.offers import Offers from lib.offers import Offers
class CesiumPlus(CesiumCommon):
class CesiumPlus(CesiumCommon):
#################### Messaging #################### #################### Messaging ####################
def read(self, nbrMsg, outbox, isJSON): def read(self, nbrMsg, outbox, isJSON):
readCesium = ReadFromCesium(self.dunikey, self.pod) readCesium = ReadFromCesium(self.dunikey, self.pod)
jsonMsg = readCesium.sendDocument(nbrMsg, outbox) jsonMsg = readCesium.sendDocument(nbrMsg, outbox)
if isJSON: if isJSON:
jsonFormat = readCesium.jsonMessages(jsonMsg, nbrMsg, outbox) jsonFormat = readCesium.jsonMessages(jsonMsg, nbrMsg, outbox)
@ -24,16 +26,18 @@ class CesiumPlus(CesiumCommon):
sendCesium.recipient = recipient sendCesium.recipient = recipient
# Generate pseudo-random nonce # Generate pseudo-random nonce
nonce=[] nonce = []
for _ in range(32): for _ in range(32):
nonce.append(random.choice(string.ascii_letters + string.digits)) nonce.append(random.choice(string.ascii_letters + string.digits))
sendCesium.nonce = base64.b64decode(''.join(nonce)) sendCesium.nonce = base64.b64decode("".join(nonce))
finalDoc = sendCesium.configDoc(sendCesium.encryptMsg(title), sendCesium.encryptMsg(msg)) # Configure JSON document to send finalDoc = sendCesium.configDoc(
sendCesium.sendDocument(finalDoc, outbox) # Send final signed document sendCesium.encryptMsg(title), sendCesium.encryptMsg(msg)
) # Configure JSON document to send
sendCesium.sendDocument(finalDoc, outbox) # Send final signed document
def delete(self, idsMsgList, outbox): def delete(self, idsMsgList, outbox):
deleteCesium = DeleteFromCesium(self.dunikey, self.pod) deleteCesium = DeleteFromCesium(self.dunikey, self.pod)
# deleteCesium.issuer = recipient # deleteCesium.issuer = recipient
for idMsg in idsMsgList: for idMsg in idsMsgList:
finalDoc = deleteCesium.configDoc(idMsg, outbox) finalDoc = deleteCesium.configDoc(idMsg, outbox)
@ -41,55 +45,74 @@ class CesiumPlus(CesiumCommon):
#################### Profiles #################### #################### Profiles ####################
def set(self, name=None, description=None, ville=None, adresse=None, position=None, site=None, avatar=None): def set(
setProfile = Profiles(self.dunikey, self.pod) self,
document = setProfile.configDocSet(name, description, ville, adresse, position, site, avatar) name=None,
result = setProfile.sendDocument(document,'set') description=None,
ville=None,
adresse=None,
position=None,
site=None,
avatar=None,
):
setProfile = Profiles(self.dunikey, self.pod)
document = setProfile.configDocSet(
name, description, ville, adresse, position, site, avatar
)
result = setProfile.sendDocument(document, "set")
print(result) print(result)
return result return result
def get(self, profile=None, avatar=None): def get(self, profile=None, avatar=None):
getProfile = Profiles(self.dunikey, self.pod, self.noNeedDunikey) getProfile = Profiles(self.dunikey, self.pod, self.noNeedDunikey)
if not profile: if not profile:
profile = self.pubkey profile = self.pubkey
if not re.match(PUBKEY_REGEX, profile) or len(profile) > 45: if not re.match(PUBKEY_REGEX, profile) or len(profile) > 45:
scope = 'title' scope = "title"
else: else:
scope = '_id' scope = "_id"
document = getProfile.configDocGet(profile, scope, avatar) document = getProfile.configDocGet(profile, scope, avatar)
resultJSON = getProfile.sendDocument(document, 'get') resultJSON = getProfile.sendDocument(document, "get")
result = getProfile.parseJSON(resultJSON) result = getProfile.parseJSON(resultJSON)
print(result) print(result)
def getPage(self, page=None, avatar=None): def getPage(self, page=None, avatar=None):
getPage = Pages(self.dunikey, self.pod, self.noNeedDunikey) getPage = Pages(self.dunikey, self.pod, self.noNeedDunikey)
if not page: if not page:
page = self.pubkey page = self.pubkey
if not re.match(PUBKEY_REGEX, page) or len(page) > 45: if not re.match(PUBKEY_REGEX, page) or len(page) > 45:
scope = 'title' scope = "title"
else: else:
scope = '_id' scope = "_id"
document = getPage.configDocGet(page, scope, avatar) document = getPage.configDocGet(page, scope, avatar)
resultJSON = getPage.sendDocument(document, 'get') resultJSON = getPage.sendDocument(document, "get")
result = getPage.parseJSON(resultJSON) result = getPage.parseJSON(resultJSON)
print(result) print(result)
def erase(self): def erase(self):
eraseProfile = Profiles(self.dunikey, self.pod) eraseProfile = Profiles(self.dunikey, self.pod)
document = eraseProfile.configDocErase() document = eraseProfile.configDocErase()
result = eraseProfile.sendDocument(document,'erase') result = eraseProfile.sendDocument(document, "erase")
print(result) print(result)
def geolocProfiles(self, node):
geolocProfiles = GeolocProfiles(self.dunikey, self.pod)
cesiumProfiles = geolocProfiles.getCesiumProfiles()
gvaProfiles = geolocProfiles.getGVAProfiles(node)
result = geolocProfiles.formatProfiles(cesiumProfiles, json.loads(gvaProfiles))
print(json.dumps(result, indent=2))
#################### Likes #################### #################### Likes ####################
def readLikes(self, profile=False): def readLikes(self, profile=False):
likes = ReadLikes(self.dunikey, self.pod, self.noNeedDunikey) likes = ReadLikes(self.dunikey, self.pod, self.noNeedDunikey)
document = likes.configDoc(profile) document = likes.configDoc(profile)
result = likes.sendDocument(document) result = likes.sendDocument(document)
result = likes.parseResult(result) result = likes.parseResult(result)
@ -97,13 +120,13 @@ class CesiumPlus(CesiumCommon):
print(result) print(result)
def like(self, stars, profile=False): def like(self, stars, profile=False):
likes = SendLikes(self.dunikey, self.pod) likes = SendLikes(self.dunikey, self.pod)
document = likes.configDoc(profile, stars) document = likes.configDoc(profile, stars)
if document: if document:
likes.sendDocument(document, profile) likes.sendDocument(document, profile)
def unLike(self, pubkey, silent=False): def unLike(self, pubkey, silent=False):
likes = UnLikes(self.dunikey, self.pod) likes = UnLikes(self.dunikey, self.pod)
idLike = likes.checkLike(pubkey) idLike = likes.checkLike(pubkey)
if idLike: if idLike:
document = likes.configDoc(idLike) document = likes.configDoc(idLike)
@ -111,26 +134,37 @@ class CesiumPlus(CesiumCommon):
#################### Offer #################### #################### Offer ####################
def setOffer(self, title=None, description=None, city=None, localisation=None, category=None, price=None, picture=None): def setOffer(
setOffer = Offers(self.dunikey, self.pod) self,
document = setOffer.configDocSet(title, description, city, localisation, category, price, picture) title=None,
result = setOffer.sendDocumentSet(document,'set') description=None,
city=None,
localisation=None,
category=None,
price=None,
picture=None,
):
setOffer = Offers(self.dunikey, self.pod)
document = setOffer.configDocSet(
title, description, city, localisation, category, price, picture
)
result = setOffer.sendDocumentSet(document, "set")
# print(result) # print(result)
return result return result
def getOffer(self, id, avatar=None): def getOffer(self, id, avatar=None):
getOffer = Offers(self.dunikey, self.pod, self.noNeedDunikey) getOffer = Offers(self.dunikey, self.pod, self.noNeedDunikey)
resultJSON = getOffer.sendDocumentGet(id, 'get') resultJSON = getOffer.sendDocumentGet(id, "get")
# print(resultJSON) # print(resultJSON)
result = getOffer.parseJSON(resultJSON) result = getOffer.parseJSON(resultJSON)
print(result) print(result)
def deleteOffer(self, id): def deleteOffer(self, id):
eraseOffer = Offers(self.dunikey, self.pod) eraseOffer = Offers(self.dunikey, self.pod)
document = eraseOffer.configDocErase(id) document = eraseOffer.configDocErase(id)
result = eraseOffer.sendDocumentSet(document,'delete', id) result = eraseOffer.sendDocumentSet(document, "delete", id)
print(result) print(result)

135
lib/geolocProfiles.py Executable file
View File

@ -0,0 +1,135 @@
import requests
from time import time
from lib.cesiumCommon import CesiumCommon
from lib.gvaWallets import ListWallets
class GeolocProfiles(CesiumCommon):
# Configure JSON document POST ready to send
def getCesiumProfiles(self):
response = requests.post(
"https://g1.data.e-is.pro/user/profile/_search?scroll=2m",
json={
"query": {
"constant_score": {
"filter": [
{"exists": {"field": "geoPoint"}},
{
"geo_bounding_box": {
"geoPoint": {
"top_left": {"lat": 90, "lon": -180},
"bottom_right": {"lat": -90, "lon": 180},
}
}
},
]
}
},
"_source": [
"title",
"avatar._content_type",
"description",
"city",
"address",
"socials.url",
"creationTime",
"membersCount",
"type",
"geoPoint",
],
"size": 20000,
},
)
scroll_id = response.json()["_scroll_id"]
finalResult = response.json()["hits"]["hits"]
while True:
# Effectuez une requête de défilement pour obtenir la page suivante
response_scroll = requests.post(
"https://g1.data.e-is.pro/_search/scroll",
json={"scroll_id": scroll_id, "scroll": "2m"},
)
# Vérifiez si la réponse est vide (aucun résultat) ou si la durée du défilement est écoulée
if (
not response_scroll.json()["hits"]["hits"]
or "error" in response_scroll.json()
):
break
else:
finalResult = finalResult + response_scroll.json()["hits"]["hits"]
# Traitez les résultats ici
# Une fois terminé, supprimez le contexte de défilement
requests.delete(
"https://g1.data.e-is.pro/_search/scroll", json={"scroll_id": [scroll_id]}
)
return finalResult
def getGVAProfiles(self, node):
gva = ListWallets(node, False, False, False, False)
return gva.sendDoc()
def formatProfiles(self, cesiumProfiles, gvaProfiles):
walletsResult = []
for profile in cesiumProfiles:
source = profile["_source"]
pubkey = profile["_id"]
try:
isMember = gvaProfiles[pubkey]["id"]["isMember"]
userId = gvaProfiles[pubkey]["id"]["username"]
except:
isMember = False
userId = None
try:
title = source["title"]
except:
title = None
try:
city = source["city"]
except:
city = None
try:
avatar = source["avatar"]
except:
avatar: None
try:
socials = source["socials"]
except:
socials = None
try:
description = source["description"]
except:
description = None
try:
address = source["address"]
except:
address = None
walletsResult.append(
{
"pubkey": pubkey,
**({"address": address} if address else {}),
**({"city": city} if city else {}),
**({"description": description} if description else {}),
**({"avatar": avatar} if avatar else {}),
**({"userId": userId} if userId else {}),
"isMember": isMember,
"geoPoint": source["geoPoint"],
**({"socials": socials} if socials else {}),
**({"title": title} if title else {}),
}
)
finalResult = {"wallets": walletsResult, "time": int(time())}
return finalResult

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sys, re, os.path, json, ast import sys, json
from termcolor import colored from termcolor import colored
from lib.natools import fmt, sign, get_privkey from lib.natools import fmt, sign, get_privkey
from gql import gql, Client from gql import gql, Client
@ -8,8 +8,8 @@ from gql.transport.aiohttp import AIOHTTPTransport
PUBKEY_REGEX = "(?![OIl])[1-9A-Za-z]{42,45}" PUBKEY_REGEX = "(?![OIl])[1-9A-Za-z]{42,45}"
class ListWallets:
class ListWallets:
def __init__(self, node, brut, mbr, nonMbr, larf): def __init__(self, node, brut, mbr, nonMbr, larf):
self.mbr = mbr self.mbr = mbr
self.larf = larf self.larf = larf
@ -45,7 +45,8 @@ class ListWallets:
} }
} }
} }
""") """
)
# Send wallets document # Send wallets document
try: try:
@ -54,24 +55,34 @@ class ListWallets:
sys.stderr.write("Echec de récupération de la liste:\n" + str(e) + "\n") sys.stderr.write("Echec de récupération de la liste:\n" + str(e) + "\n")
sys.exit(1) sys.exit(1)
jsonBrut = queryResult['wallets']['edges'] jsonBrut = queryResult["wallets"]["edges"]
walletList = [] walletMap = {}
for i, trans in enumerate(jsonBrut): for i, trans in enumerate(jsonBrut):
dataWork = trans['node'] dataWork = trans["node"]
if (self.mbr and (dataWork['idty'] == None or dataWork['idty']['isMember'] == False)): continue if self.mbr and (
if (self.nonMbr and (dataWork['idty'] == None or dataWork['idty']['isMember'] == True)): continue dataWork["idty"] == None or dataWork["idty"]["isMember"] == False
if (self.larf and (dataWork['idty'] != None)): continue ):
walletList.append({'pubkey': dataWork['script'],'balance': dataWork['balance']['amount']/100,'id': dataWork['idty']}) continue
if self.nonMbr and (
dataWork["idty"] == None or dataWork["idty"]["isMember"] == True
):
continue
if self.larf and (dataWork["idty"] != None):
continue
walletMap[dataWork["script"]] = {
"balance": dataWork["balance"]["amount"] / 100,
"id": dataWork["idty"],
}
if (self.brut): if self.brut:
names = [] names = []
for dataWork in walletList: for dataWork in walletMap:
if (self.mbr or self.nonMbr): if self.mbr or self.nonMbr:
names.append(dataWork['pubkey'] + ' ' + dataWork['id']['username']) names.append(dataWork["pubkey"] + " " + dataWork["id"]["username"])
else: else:
names.append(dataWork['pubkey']) names.append(dataWork["pubkey"])
return "\n".join(names) return "\n".join(names)
else: else:
return json.dumps(walletList, indent=2) return json.dumps(walletMap, indent=2)

View File

@ -1,4 +1,4 @@
import sys, re, json, requests, base64 import sys, json, requests, base64
from time import time from time import time
from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX
@ -9,71 +9,74 @@ class Profiles(CesiumCommon):
timeSent = int(time()) timeSent = int(time())
data = {} data = {}
if name: data['title'] = name if name:
if description: data['description'] = description data["title"] = name
if address: data['address'] = address if description:
if city: data['city'] = city data["description"] = description
if pos: if address:
data["address"] = address
if city:
data["city"] = city
if pos:
geoPoint = {} geoPoint = {}
geoPoint['lat'] = pos[0] geoPoint["lat"] = pos[0]
geoPoint['lon'] = pos[1] geoPoint["lon"] = pos[1]
data['geoPoint'] = geoPoint data["geoPoint"] = geoPoint
if socials: if socials:
data['socials'] = [] data["socials"] = []
data['socials'].append({}) data["socials"].append({})
data['socials'][0]['type'] = "web" data["socials"][0]["type"] = "web"
data['socials'][0]['url'] = socials data["socials"][0]["url"] = socials
if avatar: if avatar:
avatar = open(avatar, 'rb').read() avatar = open(avatar, "rb").read()
avatar = base64.b64encode(avatar).decode() avatar = base64.b64encode(avatar).decode()
data['avatar'] = {} data["avatar"] = {}
data['avatar']['_content'] = avatar data["avatar"]["_content"] = avatar
data['avatar']['_content_type'] = "image/png" data["avatar"]["_content_type"] = "image/png"
data['time'] = timeSent data["time"] = timeSent
data['issuer'] = self.pubkey data["issuer"] = self.pubkey
data['version'] = 2 data["version"] = 2
data['tags'] = [] data["tags"] = []
document = json.dumps(data) document = json.dumps(data)
return self.signDoc(document) return self.signDoc(document)
# Configure JSON document GET to send # Configure JSON document GET to send
def configDocGet(self, profile, scope='title', getAvatar=None): def configDocGet(self, profile, scope="title", getAvatar=None):
if getAvatar: if getAvatar:
avatar = "avatar" avatar = "avatar"
else: else:
avatar = "avatar._content_type" avatar = "avatar._content_type"
data = { data = {
"query": { "query": {
"bool": { "bool": {
"should":[ "should": [
{ {"match": {scope: {"query": profile, "boost": 2}}},
"match":{ {"prefix": {scope: profile}},
scope:{
"query": profile,"boost":2
}
}
},{
"prefix": {scope: profile}
}
] ]
} }
},"highlight": { },
"fields": { "highlight": {"fields": {"title": {}, "tags": {}}},
"title":{}, "from": 0,
"tags":{} "size": 100,
} "_source": [
},"from":0, "title",
"size":100, avatar,
"_source":["title", avatar,"description","city","address","socials.url","creationTime","membersCount","type","geoPoint"], "description",
"indices_boost":{"user":100,"page":1,"group":0.01 "city",
} "address",
"socials.url",
"creationTime",
"membersCount",
"type",
"geoPoint",
],
"indices_boost": {"user": 100, "page": 1, "group": 0.01},
} }
document = json.dumps(data) document = json.dumps(data)
return document return document
@ -82,44 +85,45 @@ class Profiles(CesiumCommon):
timeSent = int(time()) timeSent = int(time())
data = {} data = {}
data['time'] = timeSent data["time"] = timeSent
data['id'] = self.pubkey data["id"] = self.pubkey
data['issuer'] = self.pubkey data["issuer"] = self.pubkey
data['version'] = 2 data["version"] = 2
data['index'] = "user" data["index"] = "user"
data['type'] = "profile" data["type"] = "profile"
document = json.dumps(data) document = json.dumps(data)
return self.signDoc(document) return self.signDoc(document)
def sendDocument(self, document, type): def sendDocument(self, document, type):
headers = { headers = {
'Content-type': 'application/json', "Content-type": "application/json",
} }
# Send JSON document and get JSON result # Send JSON document and get JSON result
if type == 'set': if type == "set":
reqQuery = '{0}/user/profile?pubkey={1}/_update?pubkey={1}'.format(self.pod, self.pubkey) reqQuery = "{0}/user/profile?pubkey={1}/_update?pubkey={1}".format(
elif type == 'get': self.pod, self.pubkey
reqQuery = '{0}/user,page,group/profile,record/_search'.format(self.pod) )
elif type == 'erase': elif type == "get":
reqQuery = '{0}/history/delete'.format(self.pod) reqQuery = "{0}/user,page,group/profile,record/_search".format(self.pod)
elif type == "erase":
reqQuery = "{0}/history/delete".format(self.pod)
result = requests.post(reqQuery, headers=headers, data=document) result = requests.post(reqQuery, headers=headers, data=document)
if result.status_code == 200: if result.status_code == 200:
# print(result.text) # print(result.text)
return result.text return result.text
else: else:
sys.stderr.write("Echec de l'envoi du document...\n" + result.text + '\n') sys.stderr.write("Echec de l'envoi du document...\n" + result.text + "\n")
def parseJSON(self, doc): def parseJSON(self, doc):
doc = json.loads(doc)['hits']['hits'] doc = json.loads(doc)["hits"]["hits"]
if doc: if doc:
pubkey = { "pubkey": doc[0]['_id'] } pubkey = {"pubkey": doc[0]["_id"]}
rest = doc[0]['_source'] rest = doc[0]["_source"]
final = {**pubkey, **rest} final = {**pubkey, **rest}
return json.dumps(final, indent=2) return json.dumps(final, indent=2)
else: else:
return 'Profile vide' return "Profile vide"