diff --git a/code/app.py b/code/app.py index 98371fe..942df4b 100644 --- a/code/app.py +++ b/code/app.py @@ -14,7 +14,7 @@ from utils.utils import * from utils.crypt import * -__FLEES_VERSION__ = "20180721.1" +__FLEES_VERSION__ = "20180724.0" app = Flask(__name__) app.config.from_object(__name__) # Read config from json ! @@ -251,7 +251,7 @@ def editor(name = None): content = "" if os.path.isfile(pathname): if pathname.endswith(".txt"): - content = open(pathname, 'rt').read(10 * 1024) + content = open(pathname, 'rt').read(65536) return render_template( 'editor.html', diff --git a/code/templates/client.py b/code/templates/client.py index dab818c..6a52218 100644 --- a/code/templates/client.py +++ b/code/templates/client.py @@ -4,6 +4,7 @@ from subprocess import call, Popen, PIPE, STDOUT import readline import glob from io import StringIO +import tempfile, hashlib try: from tabulate import tabulate except ImportError: @@ -71,11 +72,13 @@ class Completer(object): return results[state] -def download_file(file, opts): +def download_file(file, opts, filename = False): print("Download " + file['name']) + if not filename: + filename = file['name'] cmd = [ 'curl','--create-dirs', - '-o', file['name'], + '-o', filename, '%s%s/%s/%s/%s'%( opts.rooturl, "download", @@ -96,23 +99,43 @@ def download_file(file, opts): return +def file_hash(file): + buf = 65536 # lets read stuff in 64kb chunks! + + md5 = hashlib.md5() + with open(file, 'rb') as f: + while True: + data = f.read(buf) + if not data: + break + md5.update(data) + return md5.hexdigest() + + +def edit_file(file): + old_hash = file_hash(file) + editor = os.environ.get('EDITOR','vim') + call([editor, file]) + new_hash = file_hash(file) + return new_hash != old_hash + + def menu(opts): - commands = [ - 'Download', - 'Upload' - ] + commands = { + '1': {'name': 'Download', 'cmd': menu_download}, + '2': {'name': 'Upload', 'cmd': menu_upload}, + '3': {'name': 'Edit', 'cmd': menu_edit}, + } print_title("Main menu") - for i,command in enumerate(commands): - print(" %d. %s"%( i+1, command, )) - comp = Completer(choices = ["1","2"]) + for command in sorted(commands): + print(" %s. %s"%( command, commands[command]['name'])) + comp = Completer(choices = commands.keys()) readline.set_completer(comp.complete) print("\n[Empty to exit]") choice = user_input("Number of action: ").strip() - if choice == "1": - menu_download(opts) - if choice == "2": - menu_upload(opts) - if choice == "": + if choice in commands: + commands[choice]['cmd'](opts) + else: sys.exit(0) @@ -149,6 +172,40 @@ def menu_download(opts): download_file(files[choice], opts) +def menu_edit(opts): + while True: + print_title("Edit file") + files = json.loads(run_command("file/details", opts)) + file_table = [] + for f in files: + if not f['editable']: + continue + file_table.append(( + f['name'], + float(f['size'].replace(",","")), + f['mtime'] + )) + print(tabulate(file_table, headers = ("Name", "Size [Mb]", "Modified"))) + name_list = [x['name'] for x in files] + comp = Completer(choices = name_list) + # we want to treat '/' as part of a word, so override the delimiters + readline.set_completer(comp.complete) + print("\n[Empty to return, new name to create new file]") + choice = user_input('Edit file: ').strip() + if choice == "": + return + tfp, tmp = tempfile.mkstemp( + suffix = ".txt" + ) + if choice in name_list: + file = [f for f in files if f['name'] == choice][0] + download_file(file, opts, filename = tmp) + changed = edit_file(tmp) + if changed: + upload_named_file(tmp, opts, choice) + os.remove(tmp) + + def menu_upload(opts): while True: print_title("Upload") @@ -268,41 +325,21 @@ def upload_file(file, opts): return - cmd1 = [ - 'curl','-s', - '%s%s/%s/%s'%( +def upload_named_file(file, opts, filename): + print("Upload " + filename) + p = Popen( + "curl -F 'file=@%s;filename=%s' %s%s/%s/%s"%( + file, + filename, opts.rooturl, - "script/upload_split", + "upload", opts.share, - opts.token, + opts.token ), - ] - cmd2 = [ - 'python', '-', - '-s', str(opts.split), - file - ] - p1 = Popen( - cmd1, - stderr = PIPE, stdout = PIPE, + shell = True ) - script, stderr = p1.communicate() - p2 = Popen( - cmd2, - stdin = PIPE, - stdout = PIPE, - stderr = PIPE, - bufsize = 1 - ) - p2.stdin.write(script) - p2.stdin.close() - for char in iter(lambda: p2.stderr.read(1), ''): - if not char: - break - sys.stderr.write(char) - sys.stderr.flush() - + read_output(p.stdout) return diff --git a/code/utils/utils.py b/code/utils/utils.py index e9aa70a..085d6c8 100644 --- a/code/utils/utils.py +++ b/code/utils/utils.py @@ -67,7 +67,7 @@ def file_stat(path, filename): 'mtime': file_date_human(s.st_mtime), 'name': filename, 'url': path2url(filename), - 'editable': (s.st_size < 10240 and filename.endswith(".txt")) + 'editable': (s.st_size < 65536 and filename.endswith(".txt")) }