|
@@ -13,6 +13,7 @@ from bottle import (
|
|
|
template, static_file,
|
|
|
HTTPResponse,
|
|
|
)
|
|
|
+from base64 import urlsafe_b64decode as b64decode
|
|
|
from linkpreview import link_preview
|
|
|
|
|
|
from .validate import CLIP_SIZE_LIMIT, get_file_mimetype, get_file_size, get_filename, validate_file
|
|
@@ -92,25 +93,28 @@ def get_clip(route, filename):
|
|
|
def get_upload(hash, db=None):
|
|
|
hash = hash and normalize_base32(hash)
|
|
|
con = connect('util.db')
|
|
|
+ fname, mimetype, content = (None, None, None)
|
|
|
try:
|
|
|
- ret: Row = con.cursor().execute(f"""
|
|
|
-SELECT content
|
|
|
-FROM clip
|
|
|
+ fname, mimetype, content = con.cursor().execute(f"""
|
|
|
+SELECT name, mime, content
|
|
|
+FROM upload
|
|
|
WHERE hash = '{hash}'
|
|
|
LIMIT 1;
|
|
|
-""").fetchall()[0][0].encode('utf-8')
|
|
|
+""").fetchall()[0]
|
|
|
finally:
|
|
|
con.close()
|
|
|
-
|
|
|
- download = True
|
|
|
- mimetype = True
|
|
|
+
|
|
|
+
|
|
|
+ content = content.split(';')[-1]
|
|
|
+ content = b64decode(content + '==')
|
|
|
+
|
|
|
if request.params.download == "false":
|
|
|
download = False
|
|
|
- mimetype = request.params.mimetype or None
|
|
|
headers = {}
|
|
|
- headers['Content-Length'] = len(ret)
|
|
|
- fname = 'noddy'
|
|
|
- headers['Content-Disposition'] = 'attachment; filename="%s"' % fname
|
|
|
+ headers['Content-Length'] = len(content)
|
|
|
+
|
|
|
+
|
|
|
+ headers['Content-Disposition'] = 'attachment; filename="%s"' % (fname or hash)
|
|
|
headers['Content-Encoding'] = 'application/octet-stream'
|
|
|
|
|
|
|
|
@@ -122,70 +126,7 @@ LIMIT 1;
|
|
|
|
|
|
|
|
|
|
|
|
- return HTTPResponse(ret, **headers)
|
|
|
-
|
|
|
-@route('/upload', method=['GET', 'POST'])
|
|
|
-def upload():
|
|
|
-
|
|
|
- if request.method == 'GET':
|
|
|
- _hash = request.params.hash
|
|
|
- mimetype = None
|
|
|
- if _hash:
|
|
|
- _hash = normalize_base32(_hash)
|
|
|
- size = get_file_size(_hash)
|
|
|
- name = get_filename(_hash)
|
|
|
- mimetype = get_file_mimetype(name)
|
|
|
- validate_file(_hash, root='rest/static/files', download=True, mimetype=mimetype)
|
|
|
- if mimetype and mimetype is not True and mimetype.startswith('text'):
|
|
|
- mimetype = None if size and size > CLIP_SIZE_LIMIT else mimetype
|
|
|
-
|
|
|
- link = f'{LOCATION}/upload/{_hash}' if _hash else f'{LOCATION}/upload'
|
|
|
- response.content_type = 'text/html; charset=utf-8'
|
|
|
- disabled = True if _hash else False
|
|
|
- form = template('form-upload', action='/upload', method='post', disabled=disabled)
|
|
|
-
|
|
|
- return template(
|
|
|
- 'upload',
|
|
|
- form=form,
|
|
|
- qr=f'{LOCATION}/upload/{_hash}.qr' if _hash else f'{LOCATION}/static/upload/qr.svg',
|
|
|
- link=link,
|
|
|
- mimetype=mimetype,
|
|
|
- disabled=disabled
|
|
|
- )
|
|
|
-
|
|
|
- if request.method == 'POST':
|
|
|
- if 'paste' not in request.files:
|
|
|
- return abort(400, "Parameter 'paste' must be specified")
|
|
|
-
|
|
|
- upload = request.files['paste']
|
|
|
- if isinstance(upload.file, BytesIO):
|
|
|
- if len(upload.file.read()) == 0:
|
|
|
- return abort(400, "File is empty")
|
|
|
-
|
|
|
- _b32 = save_upload(upload.raw_filename, LOCATION, upload.file, root='rest/static/files')
|
|
|
- return redirect(f'/upload?hash={_b32}')
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ return HTTPResponse(content, **headers)
|
|
|
|
|
|
@route('/<any>/', method='GET')
|
|
|
def redirect_trailing_slash(any): return redirect(f'/{any}')
|