generator
This commit is contained in:
47
code/app.py
47
code/app.py
@@ -12,8 +12,12 @@ from revprox import ReverseProxied
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config.from_object(__name__)
|
||||
# Read config from json !
|
||||
app.config['UPLOAD_FOLDER'] = 'data/'
|
||||
app.config['SHARES_FILE'] = 'data/shares.json'
|
||||
app.config['DATE_FORMAT'] = "%Y-%m-%d %H:%M"
|
||||
app.config['UID'] = 1000
|
||||
|
||||
app.secret_key = 'Cz2dw5NiRt3PSMFBSLTAJJi7U2CdW7iPQqEeOaU6'
|
||||
app.wsgi_app = ReverseProxied(app.wsgi_app)
|
||||
|
||||
@@ -27,7 +31,8 @@ def index():
|
||||
public_shares = []
|
||||
for share in g.shares:
|
||||
public = get_or_none(share,'public')
|
||||
if public:
|
||||
expired = is_expired(share)
|
||||
if public and not expired:
|
||||
public_shares.append({
|
||||
'name': share['name'],
|
||||
'expire': get_or_none(share,'expire'),
|
||||
@@ -61,6 +66,7 @@ def upload():
|
||||
)
|
||||
)
|
||||
file.save(filename)
|
||||
os.chown(filename, app.config['UID'], -1)
|
||||
return redirect(url_for('list_view',name=name))
|
||||
|
||||
@app.route('/send/<name>', methods=['GET'])
|
||||
@@ -78,7 +84,14 @@ def list_view(name):
|
||||
files = []
|
||||
for file in sorted(os.listdir(share['path'])):
|
||||
files.append(file_stat(os.path.join(share['path'],file)))
|
||||
return render_template("list.html",name = share['name'], entries = files)
|
||||
return render_template(
|
||||
"list.html",
|
||||
name = share['name'],
|
||||
entries = files,
|
||||
public = get_or_none(share,'public'),
|
||||
upload = get_or_none(share,'upload'),
|
||||
expire = get_or_none(share,'expire')
|
||||
)
|
||||
#~ return jsonify({"share":share, "files": files})
|
||||
|
||||
@app.route('/download/<name>/<filename>', methods=['GET'])
|
||||
@@ -94,11 +107,27 @@ def download_file(name,filename):
|
||||
def file_stat(filename):
|
||||
s = os.stat(filename)
|
||||
return {
|
||||
'size': s.st_size,
|
||||
'mtime': s.st_mtime,
|
||||
'size': file_size_human(s.st_size),
|
||||
'mtime': file_date_human(s.st_mtime),
|
||||
'name': os.path.basename(filename)
|
||||
}
|
||||
|
||||
def file_size_human(num):
|
||||
for x in [' B','KB','MB','GB','TB']:
|
||||
if num < 1024.0:
|
||||
if x==' B':
|
||||
return "%d %s" % (num, x)
|
||||
return "%3.1f %s" % (num, x)
|
||||
num /= 1024.0
|
||||
|
||||
def file_date_human(num):
|
||||
return datetime.fromtimestamp(
|
||||
num
|
||||
).strftime(app.config['DATE_FORMAT'])
|
||||
|
||||
|
||||
|
||||
|
||||
def get_or_none(d,key):
|
||||
if key in d:
|
||||
return d[key]
|
||||
@@ -110,6 +139,8 @@ def get_share(name):
|
||||
if len(share) < 1:
|
||||
return (False,'No such share')
|
||||
share = share[0]
|
||||
if is_expired(share):
|
||||
return (False, 'Share has expired')
|
||||
authenticated = True
|
||||
if 'pass_hash' in share:
|
||||
authenticated = False
|
||||
@@ -132,8 +163,16 @@ def get_share(name):
|
||||
})
|
||||
if not os.path.exists(share['path']):
|
||||
os.makedirs(share['path'])
|
||||
os.chown(share['path'], app.config['UID'], -1)
|
||||
return (True,share)
|
||||
|
||||
def is_expired(share):
|
||||
expires = get_or_none(share, 'expire')
|
||||
if expires:
|
||||
if datetime.now() > datetime.strptime(expires, app.config['DATE_FORMAT']):
|
||||
return True
|
||||
return False
|
||||
|
||||
def printerr(s):
|
||||
sys.stderr.write(str(s)+"\n")
|
||||
sys.stderr.flush()
|
||||
|
||||
@@ -1,22 +1,36 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
<h1>{{ name }}</h1>
|
||||
{% if upload %}
|
||||
<a href="{{ url_for('send', name=name) }}">+ upload</a>
|
||||
{% else %}
|
||||
Grayed out + upload
|
||||
{% endif %}
|
||||
<br>
|
||||
{% if public %}
|
||||
Share is public
|
||||
{% else %}
|
||||
Share is private
|
||||
{% endif %}
|
||||
<br>
|
||||
{% if expire %}
|
||||
Share expires {{ expire }}
|
||||
{% else %}
|
||||
Share never expires
|
||||
{% endif %}
|
||||
<br>
|
||||
|
||||
<table class=entriesall>
|
||||
<tr>
|
||||
<th>name
|
||||
<th>time
|
||||
<th>trip
|
||||
<th>kmδ
|
||||
<th>daysδ
|
||||
<th>km/d
|
||||
<th>size
|
||||
<th>mtime
|
||||
</tr>
|
||||
{% for entry in entries %}
|
||||
<tr>
|
||||
<td>{{ entry.name }}
|
||||
<td><a href="{{ url_for('download_file', name = name, filename = entry.name) }}">{{ entry.name }}</a>
|
||||
<td>{{ entry.size|safe }}
|
||||
<td>{{ entry.mtime|safe }}
|
||||
{% else %}
|
||||
<li>no files
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
19
data/shares.json.example
Normal file
19
data/shares.json.example
Normal file
@@ -0,0 +1,19 @@
|
||||
[
|
||||
{
|
||||
"name": "test",
|
||||
"path": "files",
|
||||
"pass_hash": "86d2db203591135ea63473e49759a1d2e43fdc4d9857aeee642713c4e837be12",
|
||||
"pass_plain": "tissit",
|
||||
"upload": true,
|
||||
"public": false,
|
||||
"expire": "2018-02-28 10:30"
|
||||
},
|
||||
{
|
||||
"name": "foo",
|
||||
"path": "foo",
|
||||
"pass_hash": "86d2db203591135ea63473e49759a1d2e43fdc4d9857aeee642713c4e837be12",
|
||||
"pass_plain": "tissit",
|
||||
"upload": false,
|
||||
"public": true
|
||||
}
|
||||
]
|
||||
43
utils/share_template.py
Executable file
43
utils/share_template.py
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python
|
||||
import hashlib,argparse,json,sys
|
||||
from datetime import datetime
|
||||
parser = argparse.ArgumentParser(description='Flees share template generator')
|
||||
|
||||
parser.add_argument('-n','--name', action="store", dest="name", required = True)
|
||||
parser.add_argument('-p','--path', action="store", dest="path", required = True,help= "path relative to data folder")
|
||||
parser.add_argument('-P','--public', action="store_true", dest="public", default = False)
|
||||
parser.add_argument('-u','--upload', action="store_true", dest="upload", default = False)
|
||||
parser.add_argument('--pass-plain', action="store", dest="plain", default = False)
|
||||
parser.add_argument('--pass-hashed', action="store", dest="hashed", default = False)
|
||||
parser.add_argument('-e','--expire', action="store", dest="expire", default = False, help = "expire date in format 2018-12-24 21:00")
|
||||
|
||||
opts = parser.parse_args()
|
||||
|
||||
share = {
|
||||
'name': opts.name,
|
||||
'path': opts.path,
|
||||
'public': opts.public,
|
||||
'upload': opts.upload,
|
||||
}
|
||||
if opts.plain:
|
||||
share.update({
|
||||
'pass_plain': opts.plain
|
||||
})
|
||||
if opts.hashed:
|
||||
share.update({
|
||||
'pass_hash': hashlib.sha256(opts.hashed).hexdigest()
|
||||
})
|
||||
if opts.expire:
|
||||
try:
|
||||
date_object = datetime.strptime(opts.expire,"%Y-%m-%d %H:%M")
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
share.update({
|
||||
'expire': opts.expire
|
||||
})
|
||||
|
||||
|
||||
print(json.dumps(share, indent = 2))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user