new version allows downloads from subfolders

This commit is contained in:
Ville Rantanen
2018-03-10 15:28:34 +02:00
parent 4b2280049b
commit 00008c9c7d
4 changed files with 108 additions and 56 deletions

View File

@@ -1,4 +1,3 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os,sys,time,stat
@@ -8,13 +7,13 @@ from flask import Flask, render_template, jsonify, current_app, Response, \
redirect, url_for, request, g, session, send_file, send_from_directory
from werkzeug.utils import secure_filename
import zipfile
import urllib
from multiprocessing import Process
from revprox import ReverseProxied
from utils.utils import *
from utils.crypt import *
__FLEES_VERSION__ = "20180302.0"
__FLEES_VERSION__ = "20180310.0"
app = Flask(__name__)
app.config.from_object(__name__)
# Read config from json !
@@ -42,6 +41,7 @@ if 'notifier' in config_values:
app.secret_key = config_values['app_secret_key']
app.wsgi_app = ReverseProxied(app.wsgi_app)
@app.before_request
def before_request():
g.shares = json.load(open(app.config['SHARES_FILE'],'rt'))
@@ -49,6 +49,7 @@ def before_request():
g.site_name = app.config['SITE_NAME']
g.max_zip_size = app.config['MAX_ZIP_SIZE']
@app.route("/")
def index():
public_shares = []
@@ -71,6 +72,7 @@ def index():
return render_template("index.html", entries=public_shares)
@app.route('/authenticate/<name>', methods=['GET','POST'])
def authenticate(name):
if request.method == 'GET':
@@ -80,6 +82,7 @@ def authenticate(name):
session[name] = password_hash(user_password, app.secret_key)
return redirect(url_for('list_view',name=name))
@app.route('/upload/<name>/<token>', methods=['POST'])
@app.route('/upload', methods=['POST'])
def upload(name = None, token = None):
@@ -158,9 +161,6 @@ def upload_join_splitted(name, token):
except:
return "Joining failed\n", 400
return "Joining started\n", 200
#~ return Response(joiner(target_name, parts), mimetype="text/plain", content_type="text/event-stream")
#~ return "%d parts joined"%(len(parts),), 200
@app.route('/send/<name>', methods=['GET'])
@@ -170,22 +170,19 @@ def send(name):
return share
return render_template('send.html',name=name)
@app.route('/files/<name>/<token>', methods=['GET'])
def list_files(name, token):
(ok,share) = get_share(name, token = token)
if not ok:
return share
files = []
for file in sorted(os.listdir(share['path'])):
fp = os.path.join(share['path'],file)
if os.path.isdir(fp):
continue
if file.startswith("."):
continue
files.append(urllib.parse.quote_plus(file))
for file in iter_folder_files(share['path']):
files.append(path2url(file))
files.append("")
return "\n".join(files), 200
@app.route('/list/<name>/<token>', methods=['GET'])
@app.route('/list/<name>', methods=['GET'])
def list_view(name, token = None):
@@ -197,15 +194,13 @@ def list_view(name, token = None):
return redirect(url_for('list_view',name=name))
files = []
for file in sorted(os.listdir(share['path'])):
for file in iter_folder_files(share['path']):
fp = os.path.join(share['path'],file)
if os.path.isdir(fp):
continue
if file.startswith("."):
continue
status = file_stat(fp)
status.update({
'token': get_direct_token(share, file)
'token': get_direct_token(share, file),
'name': file,
'url': path2url(file)
})
files.append(status)
# direct share links not allowed if password isnt set
@@ -227,6 +222,7 @@ def list_view(name, token = None):
description = get_or_none('description', share, "")
)
@app.route('/logout/<name>', methods=['GET'])
def logout(name):
if name in session:
@@ -236,7 +232,8 @@ def logout(name):
name = name
)
@app.route('/direct/<name>/<token>/<filename>', methods=['GET'])
@app.route('/direct/<name>/<token>/<path:filename>', methods=['GET'])
def download_direct(name,token,filename):
(ok,share) = get_share(name, require_auth = False)
if not ok:
@@ -244,6 +241,8 @@ def download_direct(name,token,filename):
allow_direct = get_or_none('direct_links', share)
if allow_direct != True:
return 'Direct download not allowed', 403
if not is_path_safe(filename):
return 'Incorrect relative path'+filename, 403
file_token = get_direct_token(share, filename)
if file_token == None:
return 'Cannot generate token', 400
@@ -251,7 +250,7 @@ def download_direct(name,token,filename):
return 'Incorrect token', 403
file_path = os.path.join(share['path'], filename)
if not os.path.exists(file_path):
return 'no such file', 404
return 'No such file', 404
notify({
"recipient": get_or_none('recipient', share),
"share": name,
@@ -261,22 +260,14 @@ def download_direct(name,token,filename):
return send_from_directory(directory=share['path'], filename=filename)
@app.route('/download/<name>/<token>/<filename>', methods=['GET'])
@app.route('/download/<name>/<filename>', methods=['GET'])
def download_file(name, filename, token = None):
(ok,share) = get_share(name, token = token)
if not ok:
return share
file_path = os.path.join(share['path'], filename)
if not os.path.exists(file_path):
return 'no such file', 404
notify({
"recipient": get_or_none('recipient', share),
"share": name,
"filename": file_path,
"operation": "download"
})
return send_from_directory(directory=share['path'], filename=filename)
@app.route('/download/gui/<name>/<path:filename>', methods=['GET'])
def download_gui(name, filename):
return download_file(name, filename, token = None)
@app.route('/download/<name>/<token>/<path:filename>', methods=['GET'])
def download_token(name, filename, token):
return download_file(name, filename, token = token)
@app.route('/zip/<name>/<token>', methods=['GET'])
@@ -302,6 +293,7 @@ def download_zip(name, token = None):
attachment_filename = name + ".zip"
)
@app.route('/script/upload/<name>/<token>', methods=['GET'])
def script_upload(name = None, token = None):
(ok,share) = get_share(name, token = token)
@@ -518,8 +510,8 @@ done
token
)
class uploadJoiner:
class uploadJoiner:
def __init__(self, target_name, parts):
self.target_name = target_name
self.parts = parts
@@ -528,6 +520,7 @@ class uploadJoiner:
p.daemon = True
p.start()
def run(self):
with open(self.target_name,'wb') as writer:
for part in self.parts:
@@ -539,6 +532,24 @@ class uploadJoiner:
os.remove(part)
def download_file(name, filename, token = None):
(ok,share) = get_share(name, token = token)
if not ok:
return share
if not is_path_safe(filename):
return "Incorrect path", 403
file_path = os.path.join(share['path'], filename)
if not os.path.exists(file_path):
return 'No such file, '+file_path, 404
notify({
"recipient": get_or_none('recipient', share),
"share": name,
"filename": file_path,
"operation": "download"
})
return send_from_directory(directory=share['path'], filename=filename)
def file_versionize(filename):
""" Move file to versioned with integer """
stats = file_stat(filename)
@@ -635,7 +646,6 @@ def set_rights(path):
def zip_share(share):
if not os.path.exists(app.config['ZIP_FOLDER']):
os.makedirs(app.config['ZIP_FOLDER'])
set_rights(app.config['ZIP_FOLDER'])
@@ -648,7 +658,7 @@ def zip_share(share):
)
)
zf = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED)
for file in sorted(os.listdir(share['path'])):
for file in iter_folder_files(share['path']):
fp = os.path.join(share['path'], file)
if os.path.isdir(fp):
continue
@@ -677,6 +687,7 @@ def zip_clean():
if __name__ == "__main__":
zip_clean()
app.run(debug=True)