rsfiles.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import hashlib
  2. import time
  3. import uuid
  4. import os.path
  5. try:
  6. from fsdb import Fsdb
  7. except ImportError:
  8. Fsdb = None
  9. from rscli.httputils import req
  10. from rscli import retroshare
  11. def get_fsdb(args):
  12. if Fsdb is None:
  13. raise Exception("ERROR: library Fsdb is needed for file publishing")
  14. store_dir = os.path.expanduser("~/.config/rscli/store/default")
  15. return Fsdb(store_dir, fmode="660")
  16. def filename_to_hash(args, dir_virtualname, filename):
  17. r = req(args, "/rsFiles/getSharedDirectories")
  18. dir_filename = [
  19. d["filename"] for d in r.json()["dirs"] if d["virtualname"] == dir_virtualname
  20. ][0]
  21. r = req(args, "/rsFiles/requestDirDetails", {"handle": 0})
  22. children = [
  23. c for c in r.json()["details"]["children"] if c["name"] != "[Extra List]"
  24. ]
  25. for possibile_root in children:
  26. r = req(
  27. args, "/rsFiles/requestDirDetails", {"handle": possibile_root["handle"]}
  28. )
  29. found = [
  30. c for c in r.json()["details"]["children"] if c["name"] == dir_filename
  31. ]
  32. if not found:
  33. raise Exception("Error: could not find shared file in RS")
  34. handle = found[0]["handle"]
  35. r = req(args, "/rsFiles/ForceDirectoryCheck")
  36. time.sleep(5)
  37. looking_for = filename.split(os.path.sep)
  38. hashlib
  39. for next_component in looking_for:
  40. r = req(args, "/rsFiles/requestDirDetails", {"handle": handle})
  41. found = [
  42. c for c in r.json()["details"]["children"] if c["name"] == next_component
  43. ]
  44. if not found:
  45. raise Exception("Error: could not find shared file in RS")
  46. handle = found[0]["handle"]
  47. r = req(args, "/rsFiles/requestDirDetails", {"handle": handle})
  48. filehash = r.json()["details"]["hash"]
  49. return filehash
  50. def file_publish(args, fnames):
  51. fsdb = get_fsdb(args)
  52. virtualname_path = os.path.join(fsdb.fsdbRoot, "virtualname.txt")
  53. if os.path.exists(virtualname_path):
  54. virtualname = open(virtualname_path).read().strip()
  55. else:
  56. virtualname = "rscli-%s" % uuid.uuid4()
  57. open(virtualname_path, "w").write(virtualname)
  58. r = req(args, "/rsFiles/getSharedDirectories")
  59. if virtualname not in [shared["virtualname"] for shared in r.json()["dirs"]]:
  60. r = req(
  61. args,
  62. "/rsFiles/addSharedDirectory",
  63. {
  64. "dir": {
  65. "filename": fsdb.fsdbRoot,
  66. "virtualname": virtualname,
  67. "shareflags": retroshare.DIR_FLAGS.ANONYMOUS_DOWNLOAD,
  68. }
  69. },
  70. )
  71. if not r.json()["retval"]:
  72. raise Exception("Error: could not create shared dir for default store")
  73. time.sleep(1)
  74. for fname in fnames:
  75. fsdb.add(fname)
  76. # print(filename_to_hash(args, virtualname, fsdb.get_file_path(digest)))
  77. h = hashlib.new("sha1")
  78. h.update(open(fname, "rb").read())
  79. yield h.hexdigest()
  80. r = req(args, "/rsFiles/ForceDirectoryCheck")
  81. def get_file_link(args, hash_digest, fname=None, size=None):
  82. fsdb = get_fsdb(args)
  83. if fname is None:
  84. # TODO: check file name on filesystem
  85. fname = os.path.basename(fsdb.get_file_path(hash_digest))
  86. if size is None:
  87. size = os.stat(fsdb.get_file_path(hash_digest)).st_size
  88. return "retroshare://file?name=%s&size=%d&hash=%s" % (fname, size, hash_digest)