diff --git a/.env.template b/.env.template index 58f704f..eae4676 100755 --- a/.env.template +++ b/.env.template @@ -2,10 +2,11 @@ DUNIKEY= # Noeud Duniter -DUNITER=https://duniter-g1.p2p.legal/gva +DUNITER="https://g1.librelois.fr" # Adresse du pod Cesium ou Gchange à utiliser -ESNODE="https://g1.data.e-is.pro" +ESNODE="https://g1.data.presles.fr" +#ESNODE="https://g1.data.e-is.pro" #ESNODE="https://g1.data.adn.life" #ESNODE=https://g1.data.le-sou.org #ESNODE=https://g1.data.duniter.fr diff --git a/jaklis.py b/jaklis.py index 83c07a0..65437e1 100755 --- a/jaklis.py +++ b/jaklis.py @@ -19,7 +19,7 @@ load_dotenv(dotenv_path) # Set global values (default parameters) , regarding variables environments node = os.getenv('DUNITER') + '/gva' if not node: - node="https://duniter-g1.p2p.legal/gva" + node="https://g1.librelois.fr/gva" pod = os.getenv('ESNODE') if not pod: @@ -38,6 +38,7 @@ 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)") @@ -79,6 +80,9 @@ setProfile_cmd.add_argument('-A', '--avatar', help="Chemin vers mon avatar en PN 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") + # Likes management stars_cmd.add_argument('-p', '--profile', help="Profile cible") stars_cmd.add_argument('-n', '--number', type=int, help="Nombre d'étoile") @@ -156,7 +160,7 @@ except: profile = False # print(pubkey, profile) -if cmd in ('history','balance','get','id','idBalance','listWallets') and (pubkey or profile): +if cmd in ('history','balance','get','page','id','idBalance','listWallets') and (pubkey or profile): noNeedDunikey = True keyPath = False try: @@ -184,7 +188,7 @@ else: # Construct CesiumPlus object -if cmd in ("read","send","delete","set","get","erase","stars","unstars","getoffer","setoffer","deleteoffer"): +if cmd in ("read","send","delete","set","get","page","erase","stars","unstars","getoffer","setoffer","deleteoffer"): from lib.cesium import CesiumPlus if args.node: @@ -221,6 +225,8 @@ if cmd in ("read","send","delete","set","get","erase","stars","unstars","getoffe 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) + elif cmd == "page": + cesium.getPage(args.page, args.avatar) elif cmd == "erase": cesium.erase() diff --git a/lib/cesium.py b/lib/cesium.py index e822529..94ffd8d 100755 --- a/lib/cesium.py +++ b/lib/cesium.py @@ -1,5 +1,6 @@ import re, string, random, base64 from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX +from lib.getPages import Pages from lib.messaging import ReadFromCesium, SendToCesium, DeleteFromCesium from lib.profiles import Profiles from lib.stars import ReadLikes, SendLikes, UnLikes @@ -62,6 +63,21 @@ class CesiumPlus(CesiumCommon): result = getProfile.parseJSON(resultJSON) print(result) + + def getPage(self, page=None, avatar=None): + getPage = Pages(self.dunikey, self.pod, self.noNeedDunikey) + if not page: + page = self.pubkey + if not re.match(PUBKEY_REGEX, page) or len(page) > 45: + scope = 'title' + else: + scope = '_id' + + document = getPage.configDocGet(page, scope, avatar) + resultJSON = getPage.sendDocument(document, 'get') + result = getPage.parseJSON(resultJSON) + + print(result) def erase(self): eraseProfile = Profiles(self.dunikey, self.pod) diff --git a/lib/getPages.py b/lib/getPages.py new file mode 100644 index 0000000..3109ba2 --- /dev/null +++ b/lib/getPages.py @@ -0,0 +1,125 @@ +import sys, re, json, requests, base64 +from time import time +from lib.cesiumCommon import CesiumCommon, PUBKEY_REGEX + + +class Pages(CesiumCommon): + # Configure JSON document SET to send + def configDocSet(self, name, description, city, address, pos, socials, avatar): + timeSent = int(time()) + + data = {} + if name: data['title'] = name + if description: data['description'] = description + if address: data['address'] = address + if city: data['city'] = city + if pos: + geoPoint = {} + geoPoint['lat'] = pos[0] + geoPoint['lon'] = pos[1] + data['geoPoint'] = geoPoint + if socials: + data['socials'] = [] + data['socials'].append({}) + data['socials'][0]['type'] = "web" + data['socials'][0]['url'] = socials + if avatar: + avatar = open(avatar, 'rb').read() + avatar = base64.b64encode(avatar).decode() + data['avatar'] = {} + data['avatar']['_content'] = avatar + data['avatar']['_content_type'] = "image/png" + data['time'] = timeSent + data['issuer'] = self.pubkey + data['version'] = 2 + data['tags'] = [] + + document = json.dumps(data) + + return self.signDoc(document) + + # Configure JSON document GET to send + def configDocGet(self, profile, scope='title', getAvatar=None): + + if getAvatar: + avatar = "avatar" + else: + avatar = "avatar._content_type" + + data = { + "query": { + "bool": { + "should":[ + { + "match":{ + scope:{ + "query": profile,"boost":2 + } + } + },{ + "prefix": {scope: profile} + } + ] + } + },"highlight": { + "fields": { + "title":{}, + "tags":{} + } + },"from":0, + "size":100, + "_source":["title", avatar,"description","city","address","socials.url","creationTime","membersCount","type","geoPoint"], + "indices_boost":{"user":100,"page":1,"group":0.01 + } + } + + document = json.dumps(data) + + return document + + # Configure JSON document SET to send + def configDocErase(self): + timeSent = int(time()) + + data = {} + data['time'] = timeSent + data['id'] = self.pubkey + data['issuer'] = self.pubkey + data['version'] = 2 + data['index'] = "user" + data['type'] = "profile" + + document = json.dumps(data) + + return self.signDoc(document) + + def sendDocument(self, document, type): + + headers = { + 'Content-type': 'application/json', + } + + # Send JSON document and get JSON result + if type == 'set': + reqQuery = '{0}/user/profile?pubkey={1}/_update?pubkey={1}'.format(self.pod, self.pubkey) + elif type == 'get': + 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) + if result.status_code == 200: + # print(result.text) + return result.text + else: + sys.stderr.write("Echec de l'envoi du document...\n" + result.text + '\n') + + def parseJSON(self, doc): + doc = json.loads(doc)['hits']['hits'] + if doc: + pubkey = { "pubkey": doc[0]['_id'] } + rest = doc[0]['_source'] + final = {**pubkey, **rest} + return json.dumps(final, indent=2) + else: + return 'Profile vide' diff --git a/lib/messaging.py b/lib/messaging.py index 2165182..0478d0c 100755 --- a/lib/messaging.py +++ b/lib/messaging.py @@ -46,6 +46,7 @@ class ReadFromCesium(CesiumCommon): # Parse JSON result and display messages def readMessages(self, msgJSON, nbrMsg, outbox): def decrypt(msg): + if msg is None: return '' msg64 = base64.b64decode(msg) return box_decrypt(msg64, get_privkey(self.dunikey, "pubsec"), self.issuer, nonce).decode() @@ -94,6 +95,7 @@ class ReadFromCesium(CesiumCommon): # Parse JSON result and display messages def jsonMessages(self, msgJSON, nbrMsg, outbox): def decrypt(msg): + if msg is None: return '' msg64 = base64.b64decode(msg) return box_decrypt(msg64, get_privkey(self.dunikey, "pubsec"), self.issuer, nonce).decode()