From 14249c61b1e2cdc4d0eb82a33a56bd0a997d8567 Mon Sep 17 00:00:00 2001 From: boyska Date: Sat, 11 Jan 2020 20:22:56 +0100 Subject: [PATCH 1/5] file upload draft --- cli.py | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/cli.py b/cli.py index 364e524..715f0dd 100644 --- a/cli.py +++ b/cli.py @@ -1,8 +1,11 @@ #!/usr/bin/env python3 import sys +import time +import uuid from pprint import pprint import requests import argparse +import os.path try: from colors import color @@ -11,6 +14,14 @@ except ImportError: def color(text, *args, **kwargs): return text +try: + from fsdb import Fsdb +except ImportError: + Fsdb = None + + +def err(msg): + print(color(msg, fg='red', style='bold')) def is_group_subscribed(mSubscribeFlags): return bool(mSubscribeFlags & 4) @@ -165,6 +176,65 @@ def main_channel_post(args): return main_channel_post_v1(args) +def _file_publish(args, fnames): + if Fsdb is None: + raise Exception('ERROR: library Fsdb is needed for file publishing') + store_dir = os.path.expanduser('~/.config/rscli/store/default') + fsdb = Fsdb(store_dir, fmode='660') + + virtualname_path = os.path.join(store_dir, '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': store_dir, + 'virtualname': virtualname + }}) + if not r.json()['retval']: + raise Exception("Error: could not create shared dir for default store") + r = req(args, '/rsFiles/getSharedDirectories') + dir_filename = [d['filename'] + for d in r.json()['dirs'] + if d['virtualname'] == 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'] + + for fname in fnames: + digest = fsdb.add(fname) + r = req(args, '/rsFiles/ForceDirectoryCheck') + time.sleep(5) + # mo lo ricerchiamo va + looking_for = os.path.relpath(fsdb.get_file_path(digest), + store_dir).split(os.path.sep) + 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'] + yield filehash + + +def main_file_publish(args): + ret = _file_publish(args, args.fnames) + for filehash, fname in zip(ret, args.fnames): + print(color(filehash, fg='green') + ' \t%s' % fname) + def get_parser(): p = argparse.ArgumentParser() p.add_argument("--endpoint", default="http://127.0.0.1:9092") @@ -214,6 +284,18 @@ def get_parser(): forum_read.add_argument("--num-posts", type=int, default=10) forum_read.set_defaults(mainfunc=main_forum_read) + files = p_sub.add_parser("file") + files_sub = files.add_subparsers() + files_list = files_sub.add_parser("publish") + files_list.add_argument( + "--fname", + nargs="+", + required=True, + dest='fnames' + ) + files_list.set_defaults(mainfunc=main_file_publish) + + # TODO: channel rss -> read and convert to rss return p From 106f97bd10a5ddc84562fa038fa5d2b7fef7869a Mon Sep 17 00:00:00 2001 From: boyska Date: Sun, 12 Jan 2020 02:00:06 +0100 Subject: [PATCH 2/5] file upload: found a shortcut to find file hash ... just running sha1 directly --- cli.py | 66 ++++++++++++++++++++++++++++++++++++--------------- retroshare.py | 30 +++++++++++++++++++++++ 2 files changed, 77 insertions(+), 19 deletions(-) create mode 100644 retroshare.py diff --git a/cli.py b/cli.py index 715f0dd..e190500 100644 --- a/cli.py +++ b/cli.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import hashlib import sys import time import uuid @@ -7,6 +8,8 @@ import requests import argparse import os.path +import retroshare + try: from colors import color except ImportError: @@ -176,13 +179,15 @@ def main_channel_post(args): return main_channel_post_v1(args) -def _file_publish(args, fnames): +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') - fsdb = Fsdb(store_dir, fmode='660') + return Fsdb(store_dir, fmode='660') - virtualname_path = os.path.join(store_dir, 'virtualname.txt') +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: @@ -190,7 +195,7 @@ def _file_publish(args, fnames): 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': store_dir, + r = req(args, '/rsFiles/addSharedDirectory', {'dir':{ 'filename': fsdb.fsdbRoot, 'virtualname': virtualname }}) if not r.json()['retval']: @@ -213,27 +218,50 @@ def _file_publish(args, fnames): for fname in fnames: digest = fsdb.add(fname) - r = req(args, '/rsFiles/ForceDirectoryCheck') - time.sleep(5) - # mo lo ricerchiamo va - looking_for = os.path.relpath(fsdb.get_file_path(digest), - store_dir).split(os.path.sep) - 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'] - yield filehash + # correct implementation: check hash inside storage + # unfortunately it is very slow because we can't give + # an hint to ForceDirectoryCheck for where to look + # for new files + # after the comment, there is a valid implementation, which has the defect + # of being very coupled to retroshare implementation + # r = req(args, '/rsFiles/ForceDirectoryCheck') + #time.sleep(5) + ## mo lo ricerchiamo va + #looking_for = os.path.relpath(fsdb.get_file_path(digest), + # fsdb.fsdbRoot).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'] + #yield filehash + + 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) def main_file_publish(args): ret = _file_publish(args, args.fnames) for filehash, fname in zip(ret, args.fnames): print(color(filehash, fg='green') + ' \t%s' % fname) + print(' ' + get_file_link(args, filehash, fname=fname)) def get_parser(): p = argparse.ArgumentParser() diff --git a/retroshare.py b/retroshare.py new file mode 100644 index 0000000..f4a0762 --- /dev/null +++ b/retroshare.py @@ -0,0 +1,30 @@ +import enum # py3.4 + +try: + IntFlag = enum.IntFlag +except AttributeError: + # requires py < 3.6 + IntFlag = enum.Int + +class RS_FILE_HINTS(IntFlag): + CACHE_deprecated = 0x00000001 + EXTRA = 0x00000002 + LOCAL = 0x00000004 + REMOTE = 0x00000008 + DOWNLOAD = 0x00000010 + UPLOAD = 0x00000020 + SPEC_ONLY = 0x01000000 + NETWORK_WIDE = 0x00000080 + + BROWSABLE = 0x00000100 + SEARCHABLE = 0x00000200 + + PERMISSION_MASK = 0x00000380 + + + +# FileStorageFlags +DIR_FLAGS_ANONYMOUS_DOWNLOAD = 0x0080 +DIR_FLAGS_BROWSABLE= 0x0400 +DIR_FLAGS_ANONYMOUS_SEARCH= 0x0800 + From f5413ab2ea6ca0f3f5f79b52e2743ed70e669e8a Mon Sep 17 00:00:00 2001 From: boyska Date: Sun, 12 Jan 2020 02:32:28 +0100 Subject: [PATCH 3/5] code (re)organization. file upload. now it must be installed with pip install . also, forum/channel sorted by date. --- retroshare.py | 30 ---------- cli.py => rscli/cli.py | 125 +++++------------------------------------ rscli/httputils.py | 14 +++++ rscli/retroshare.py | 29 ++++++++++ rscli/rsfiles.py | 101 +++++++++++++++++++++++++++++++++ setup.py | 15 +++++ 6 files changed, 173 insertions(+), 141 deletions(-) delete mode 100644 retroshare.py rename cli.py => rscli/cli.py (61%) create mode 100644 rscli/httputils.py create mode 100644 rscli/retroshare.py create mode 100644 rscli/rsfiles.py create mode 100644 setup.py diff --git a/retroshare.py b/retroshare.py deleted file mode 100644 index f4a0762..0000000 --- a/retroshare.py +++ /dev/null @@ -1,30 +0,0 @@ -import enum # py3.4 - -try: - IntFlag = enum.IntFlag -except AttributeError: - # requires py < 3.6 - IntFlag = enum.Int - -class RS_FILE_HINTS(IntFlag): - CACHE_deprecated = 0x00000001 - EXTRA = 0x00000002 - LOCAL = 0x00000004 - REMOTE = 0x00000008 - DOWNLOAD = 0x00000010 - UPLOAD = 0x00000020 - SPEC_ONLY = 0x01000000 - NETWORK_WIDE = 0x00000080 - - BROWSABLE = 0x00000100 - SEARCHABLE = 0x00000200 - - PERMISSION_MASK = 0x00000380 - - - -# FileStorageFlags -DIR_FLAGS_ANONYMOUS_DOWNLOAD = 0x0080 -DIR_FLAGS_BROWSABLE= 0x0400 -DIR_FLAGS_ANONYMOUS_SEARCH= 0x0800 - diff --git a/cli.py b/rscli/cli.py similarity index 61% rename from cli.py rename to rscli/cli.py index e190500..57c43ff 100644 --- a/cli.py +++ b/rscli/cli.py @@ -1,14 +1,11 @@ #!/usr/bin/env python3 -import hashlib import sys -import time -import uuid from pprint import pprint import requests import argparse -import os.path -import retroshare +from rscli import rsfiles +from rscli.httputils import req try: from colors import color @@ -17,30 +14,16 @@ except ImportError: def color(text, *args, **kwargs): return text -try: - from fsdb import Fsdb -except ImportError: - Fsdb = None def err(msg): - print(color(msg, fg='red', style='bold')) + print(color(msg, fg="red", style="bold")) + def is_group_subscribed(mSubscribeFlags): return bool(mSubscribeFlags & 4) -def req(args, location, data=None): - kwargs = {} - if data is not None: - kwargs["json"] = data - r = requests.post( - args.endpoint + location, auth=tuple(args.auth.split(":", 2)), **kwargs - ) - r.raise_for_status() - # TODO: handle r.status_code != 200 - return r - def main_forum_list(args): r = req(args, "/rsGxsForums/getForumsSummaries") @@ -61,6 +44,7 @@ def main_forum_list(args): def main_forum_read(args): r = req(args, "/rsGxsForums/getForumMsgMetaData", {"forumId": args.forum_id}) items = r.json()["msgMetas"] + items.sort(key=lambda p: p['mPublishTs'], reverse=True) if args.long: msgs = [item["mMsgId"] for item in items[: args.num_posts]] items_r = req( @@ -69,13 +53,14 @@ def main_forum_read(args): {"forumId": args.forum_id, "msgsIds": msgs}, ) items = items_r.json()["msgs"] + items.sort(key=lambda p: p['mMeta']['mPublishTs'], reverse=True) for item in items: print(color(item["mMeta"]["mMsgName"], style="bold", fg="green")) print() print(item["mMsg"]) # TODO: html2txt print() else: - for item in posts[: args.num_posts]: + for item in items[: args.num_posts]: print(color(item["mMsgName"], style="bold", fg="green")) print(" " + color(item["mMsgId"], style="underline")) @@ -99,6 +84,7 @@ def main_channel_list(args): def main_channel_read(args): r = req(args, "/rsGxsChannels/getContentSummaries", {"channelId": args.channel_id}) posts = r.json()["summaries"] + posts.sort(key=lambda p: p['mPublishTs'], reverse=True) if args.long: msgs = [post["mMsgId"] for post in posts[: args.num_posts]] posts_r = req( @@ -107,6 +93,7 @@ def main_channel_read(args): {"channelId": args.channel_id, "contentsIds": msgs}, ) posts = posts_r.json()["posts"] + posts.sort(key=lambda p: p['mMeta']['mPublishTs'], reverse=True) for post in posts: print(color(post["mMeta"]["mMsgName"], style="bold", fg="green")) print() @@ -130,7 +117,6 @@ def main_channel_show(args): def main_channel_post_v1(args): - chid = args.channel_id r = req( args, "/rsGxsChannels/createPost", @@ -154,7 +140,6 @@ def main_channel_post_v1(args): def main_channel_post(args): - chid = args.channel_id try: r = req( args, @@ -179,89 +164,13 @@ def main_channel_post(args): return main_channel_post_v1(args) -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 _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 - }}) - if not r.json()['retval']: - raise Exception("Error: could not create shared dir for default store") - r = req(args, '/rsFiles/getSharedDirectories') - dir_filename = [d['filename'] - for d in r.json()['dirs'] - if d['virtualname'] == 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'] - - for fname in fnames: - digest = fsdb.add(fname) - # correct implementation: check hash inside storage - # unfortunately it is very slow because we can't give - # an hint to ForceDirectoryCheck for where to look - # for new files - # after the comment, there is a valid implementation, which has the defect - # of being very coupled to retroshare implementation - # r = req(args, '/rsFiles/ForceDirectoryCheck') - #time.sleep(5) - ## mo lo ricerchiamo va - #looking_for = os.path.relpath(fsdb.get_file_path(digest), - # fsdb.fsdbRoot).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'] - #yield filehash - - 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) - def main_file_publish(args): - ret = _file_publish(args, args.fnames) + ret = rsfiles.file_publish(args, args.fnames) for filehash, fname in zip(ret, args.fnames): - print(color(filehash, fg='green') + ' \t%s' % fname) - print(' ' + get_file_link(args, filehash, fname=fname)) + print(color(filehash, fg="green") + " \t%s" % fname) + print(" " + rsfiles.get_file_link(args, filehash, fname=fname)) + def get_parser(): p = argparse.ArgumentParser() @@ -315,15 +224,9 @@ def get_parser(): files = p_sub.add_parser("file") files_sub = files.add_subparsers() files_list = files_sub.add_parser("publish") - files_list.add_argument( - "--fname", - nargs="+", - required=True, - dest='fnames' - ) + files_list.add_argument("--fname", nargs="+", required=True, dest="fnames") files_list.set_defaults(mainfunc=main_file_publish) - # TODO: channel rss -> read and convert to rss return p diff --git a/rscli/httputils.py b/rscli/httputils.py new file mode 100644 index 0000000..654179f --- /dev/null +++ b/rscli/httputils.py @@ -0,0 +1,14 @@ +import requests + +def req(args, location, data=None): + kwargs = {} + if data is not None: + kwargs["json"] = data + r = requests.post( + args.endpoint + location, auth=tuple(args.auth.split(":", 2)), **kwargs + ) + r.raise_for_status() + # TODO: handle r.status_code != 200 + return r + + diff --git a/rscli/retroshare.py b/rscli/retroshare.py new file mode 100644 index 0000000..3b5d92c --- /dev/null +++ b/rscli/retroshare.py @@ -0,0 +1,29 @@ +import enum # py3.4 + +try: + IntFlag = enum.IntFlag +except AttributeError: + # requires py < 3.6 + IntFlag = enum.Int + + +class RS_FILE_HINTS(IntFlag): + CACHE_deprecated = 0x00000001 + EXTRA = 0x00000002 + LOCAL = 0x00000004 + REMOTE = 0x00000008 + DOWNLOAD = 0x00000010 + UPLOAD = 0x00000020 + SPEC_ONLY = 0x01000000 + NETWORK_WIDE = 0x00000080 + + BROWSABLE = 0x00000100 + SEARCHABLE = 0x00000200 + + PERMISSION_MASK = 0x00000380 + + +class DIR_FLAGS(IntFlag): + ANONYMOUS_DOWNLOAD = 0x0080 + BROWSABLE = 0x0400 + ANONYMOUS_SEARCH = 0x0800 diff --git a/rscli/rsfiles.py b/rscli/rsfiles.py new file mode 100644 index 0000000..6641981 --- /dev/null +++ b/rscli/rsfiles.py @@ -0,0 +1,101 @@ +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) + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..1e15380 --- /dev/null +++ b/setup.py @@ -0,0 +1,15 @@ +from setuptools import setup + +setup(name='rscli', + version='0.1', + # description='The funniest joke in the world', + # url='http://github.com/storborg/funniest', + author='boyska', + author_email='', + license='AGPL3', + packages=['rscli'], + + entry_points = { + 'console_scripts': ['rscli=rscli.cli:main'], + }, + zip_safe=False) From 483ba1299dc79384d1af12a9ee28c4952edcfc19 Mon Sep 17 00:00:00 2001 From: boyska Date: Sun, 12 Jan 2020 02:42:19 +0100 Subject: [PATCH 4/5] FIX deps + multiple file publish --- requirements.txt | 7 ------- rscli/cli.py | 2 +- setup.py | 10 ++++++++++ 3 files changed, 11 insertions(+), 8 deletions(-) delete mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 8914523..0000000 --- a/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -ansicolors==1.1.8 -certifi==2019.11.28 -chardet==3.0.4 -idna==2.8 -pkg-resources==0.0.0 -requests==2.22.0 -urllib3==1.25.7 diff --git a/rscli/cli.py b/rscli/cli.py index 57c43ff..efa9bcf 100644 --- a/rscli/cli.py +++ b/rscli/cli.py @@ -224,7 +224,7 @@ def get_parser(): files = p_sub.add_parser("file") files_sub = files.add_subparsers() files_list = files_sub.add_parser("publish") - files_list.add_argument("--fname", nargs="+", required=True, dest="fnames") + files_list.add_argument("fnames", nargs="+", metavar='fname' ) files_list.set_defaults(mainfunc=main_file_publish) # TODO: channel rss -> read and convert to rss diff --git a/setup.py b/setup.py index 1e15380..7a45b1a 100644 --- a/setup.py +++ b/setup.py @@ -9,6 +9,16 @@ setup(name='rscli', license='AGPL3', packages=['rscli'], + install_requires=[ + 'ansicolors==1.1.8', + 'certifi==2019.11.28', + 'chardet==3.0.4', + 'idna==2.8', + 'pkg-resources==0.0.0', + 'requests==2.22.0', + 'urllib3==1.25.7', + 'Fsdb==1.2.2', + ], entry_points = { 'console_scripts': ['rscli=rscli.cli:main'], }, From 19b42c21c765aa3f1a95ed68cdb6c0c1057fcf4c Mon Sep 17 00:00:00 2001 From: boyska Date: Sun, 12 Jan 2020 02:44:10 +0100 Subject: [PATCH 5/5] disable colors on pipe --- rscli/cli.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rscli/cli.py b/rscli/cli.py index efa9bcf..d3b5892 100644 --- a/rscli/cli.py +++ b/rscli/cli.py @@ -9,8 +9,11 @@ from rscli.httputils import req try: from colors import color + has_colors = True except ImportError: + has_colors = False +if not has_colors or not sys.stdout.isatty(): def color(text, *args, **kwargs): return text