diff --git a/README.md b/README.md index 377a999..37cf515 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,12 @@ Operation is one of download, direct_download, zip_download, or upload Upload file from the browser - @app.route('/upload_join//', methods=['POST']) Commence joining of a splitted upload file +- @app.route('/paste//', methods=['POST']) + Upload a string from command line +- @app.route('/paste', methods=['POST']) + Upload a string from the browser +- @app.route('/editor', methods=['POST','GET']) + Open text editor. - @app.route('/files//', methods=['GET']) Return plain text list of files in the share - @app.route('/list//', methods=['GET']) diff --git a/code/app.py b/code/app.py index 7127765..ab4750c 100644 --- a/code/app.py +++ b/code/app.py @@ -14,7 +14,7 @@ from utils.utils import * from utils.crypt import * -__FLEES_VERSION__ = "20180702.0" +__FLEES_VERSION__ = "20180720.0" app = Flask(__name__) app.config.from_object(__name__) # Read config from json ! @@ -227,6 +227,85 @@ def upload_url(): return "File uploaded\n", 200 +@app.route('/editor', methods = ['GET','POST']) +@app.route('/editor/', methods = ['GET','POST']) +def editor(name = None): + filename = 'paste.txt' + if request.method == 'POST': + name = request.form['editor_name'] + filename = request.form['editor_filename'] + + (ok,share) = get_share(name) + if not ok: + notify({ + "share": name, + "operation": "unauthorized_editor" + }) + return share + pathname = os.path.join( + share['path'], + filename + ) + content = "" + if os.path.isfile(pathname): + if pathname.endswith(".txt"): + content = open(pathname, 'rt').read(10 * 1024) + + return render_template( + 'editor.html', + name = name, + filename = filename, + content = content + ) + + +@app.route('/paste//', methods=['POST']) +@app.route('/paste/', methods=['POST']) +def paste(name = None, token = None): + if request.method == 'POST': + file = request.form['filename'] + paste = request.form['paste'] + if name == None: + name = request.form['name'] + (ok,share) = get_share(name, token = token) + if not ok: + notify({ + "share": name, + "operation": "unauthorized_paste" + }) + return share + if not get_or_none('upload', share) == True: + return "Upload not allowed\n",400 + if file: + filename = os.path.join( + share['path'], + secure_filename( + file + ) + ) + if get_or_none('overwrite', share) == False: + if os.path.exists(filename): + file_versionize(filename) + #~ return "Overwrite forbidden", 403 + print_debug("Saving " + filename) + with open(filename, 'wt') as fp: + fp.write(paste) + fp.close() + set_rights(filename) + notify({ + "recipient": get_or_none('recipient', share), + "share": name, + "filename": filename, + "operation": "paste" + }) + if 'from_gui' in request.form: + if request.form['from_gui'] == "true": + return redirect(url_for('list_view',name=name)) + return "File uploaded\n", 200 + else: + return "Use the 'file' variable to paste\n",400 + + @app.route('/file/list//', methods=['GET']) def file_list(name, token): diff --git a/code/static/css/styles.css b/code/static/css/styles.css index c9a4d86..16690b9 100644 --- a/code/static/css/styles.css +++ b/code/static/css/styles.css @@ -219,6 +219,21 @@ tr:nth-child(odd) { word-wrap: break-word; } +.edit_form { + display: inline-block; +} +.edit_form_submit { + display: inline-block; + margin-left: 1em; + background-color: inherit; + border: none; + color: var(--text-color); + text-align: center; + text-decoration: underline; + cursor: pointer; +} + + /* index */ #index_title { diff --git a/code/static/js/scripts.js b/code/static/js/scripts.js index 224ebdd..6587387 100644 --- a/code/static/js/scripts.js +++ b/code/static/js/scripts.js @@ -15,6 +15,7 @@ function index_form_enter(event) { }; } + function index_form_submit() { window.location = window.location + "/list/" + document.getElementById("index_form_name").value; @@ -29,7 +30,9 @@ function infoToggle() { function scriptToggle() { var el = document.getElementById("list_script"); - el.style.display = el.style.display === 'block' ? 'none' : 'block'; + if (el) { + el.style.display = el.style.display === 'block' ? 'none' : 'block'; + } } @@ -104,6 +107,7 @@ function FileSelectHandler(e) { // Variable to stop parallel uploads var uploadTurn = -1; + function UploadURL() { var URL = document.getElementById("list_url_upload_text").value; var xhr = new XMLHttpRequest(); @@ -150,3 +154,20 @@ function UploadURL() { function changeTitle(newTitle) { document.title = "Flees - " + newTitle; } + +function back() { + window.history.back(); +} + +function keyboardEntry(ev){ + var kC=ev.keyCode; + var k=String.fromCharCode(ev.keyCode); + if ( document.activeElement === document.getElementById("list_url_upload_text")) { + return + } + if (/T/.test(k)) { + infoToggle(); + } +} + +document.onkeyup = keyboardEntry; diff --git a/code/templates/editor.html b/code/templates/editor.html new file mode 100644 index 0000000..6a86a5b --- /dev/null +++ b/code/templates/editor.html @@ -0,0 +1,21 @@ +{% extends "layout.html" %} +{% block body %} +
+ Add text file to {{ name|safe }} +
+
+ + +
+ + +
+ + +
+
+
+ +{% endblock %} diff --git a/code/templates/list.html b/code/templates/list.html index 20127e0..ddd3e65 100644 --- a/code/templates/list.html +++ b/code/templates/list.html @@ -18,7 +18,7 @@ {% endif %} -
Share tools
+
Share tools
@@ -54,6 +54,7 @@ {% endif %}
  • Download as zip
  • Command line info +
  • Paste or write a file
  • Return to index
  • Logout
  • @@ -76,7 +77,16 @@ {% if direct %} {% endif %} - {{ entry.name }} + {{ entry.name }} + {% if upload %} + {% if entry.editable %} + + + + + + {% endif %} + {% endif %} {{ entry.size|safe }} {{ entry.mtime|safe }} diff --git a/code/utils/utils.py b/code/utils/utils.py index 7340672..10d207b 100644 --- a/code/utils/utils.py +++ b/code/utils/utils.py @@ -36,7 +36,8 @@ def file_stat(path, filename): 'size': file_size_MB(s.st_size), 'mtime': file_date_human(s.st_mtime), 'name': filename, - 'url': path2url(filename) + 'url': path2url(filename), + 'editable': (s.st_size < 10240 and filename.endswith(".txt")) }