import hashlib import time import uuid import os.path try: from fsdb import Fsdb except ImportError: Fsdb = None from rscli.httputils import req from rscli import retroshare def get_fsdb(args): if Fsdb is None: raise Exception("ERROR: library Fsdb is needed for file publishing") store_dir = os.path.expanduser("~/.config/rscli/store/default") return Fsdb(store_dir, fmode="660") def filename_to_hash(args, dir_virtualname, filename): r = req(args, "/rsFiles/getSharedDirectories") dir_filename = [ d["filename"] for d in r.json()["dirs"] if d["virtualname"] == dir_virtualname ][0] r = req(args, "/rsFiles/requestDirDetails", {"handle": 0}) children = [ c for c in r.json()["details"]["children"] if c["name"] != "[Extra List]" ] for possibile_root in children: r = req( args, "/rsFiles/requestDirDetails", {"handle": possibile_root["handle"]} ) found = [ c for c in r.json()["details"]["children"] if c["name"] == dir_filename ] if not found: raise Exception("Error: could not find shared file in RS") handle = found[0]["handle"] r = req(args, "/rsFiles/ForceDirectoryCheck") time.sleep(5) looking_for = filename.split(os.path.sep) hashlib for next_component in looking_for: r = req(args, "/rsFiles/requestDirDetails", {"handle": handle}) found = [ c for c in r.json()["details"]["children"] if c["name"] == next_component ] if not found: raise Exception("Error: could not find shared file in RS") handle = found[0]["handle"] r = req(args, "/rsFiles/requestDirDetails", {"handle": handle}) filehash = r.json()["details"]["hash"] return filehash def file_publish(args, fnames): fsdb = get_fsdb(args) virtualname_path = os.path.join(fsdb.fsdbRoot, "virtualname.txt") if os.path.exists(virtualname_path): virtualname = open(virtualname_path).read().strip() else: virtualname = "rscli-%s" % uuid.uuid4() open(virtualname_path, "w").write(virtualname) r = req(args, "/rsFiles/getSharedDirectories") if virtualname not in [shared["virtualname"] for shared in r.json()["dirs"]]: r = req( args, "/rsFiles/addSharedDirectory", { "dir": { "filename": fsdb.fsdbRoot, "virtualname": virtualname, "shareflags": retroshare.DIR_FLAGS.ANONYMOUS_DOWNLOAD, } }, ) if not r.json()["retval"]: raise Exception("Error: could not create shared dir for default store") time.sleep(1) for fname in fnames: fsdb.add(fname) # print(filename_to_hash(args, virtualname, fsdb.get_file_path(digest))) h = hashlib.new("sha1") h.update(open(fname, "rb").read()) yield h.hexdigest() r = req(args, "/rsFiles/ForceDirectoryCheck") def get_file_link(args, hash_digest, fname=None, size=None): fsdb = get_fsdb(args) if fname is None: # TODO: check file name on filesystem fname = os.path.basename(fsdb.get_file_path(hash_digest)) if size is None: size = os.stat(fsdb.get_file_path(hash_digest)).st_size return "retroshare://file?name=%s&size=%d&hash=%s" % (fname, size, hash_digest)