Răsfoiți Sursa

get uploads fully working

Pi 4 luni în urmă
părinte
comite
4f34f1ddda

+ 16 - 75
rest/pyapi.py

@@ -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
+
+    # extract bytes from data url
+    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)
+
+    # TODO: create ext from mime type?
+    headers['Content-Disposition'] = 'attachment; filename="%s"' % (fname or hash)
     headers['Content-Encoding'] = 'application/octet-stream'
     # if mimetype == 'auto':
     #     mimetype, encoding = mimetypes.guess_type(filename)
@@ -122,70 +126,7 @@ LIMIT 1;
     #     headers['Content-Type'] = mimetype
     #lm = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(created))
     #headers['Last-Modified'] = lm
-    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}')
-
-
-# @route('/upload/<filename:path>', method='GET')
-# def get_upload(filename):
-#     ext = 'file'
-#     if filename and filename.endswith('.qr'):
-#         filename, ext = filename.split('.', 1)
-    
-#     filename = filename and normalize_base32(filename)
-#     path = f'{filename}/{filename}.{ext}'
-    
-#     if ext == 'qr':
-#         return static_file(path, root='rest/static/files', mimetype='image/svg+xml')
-    
-#     download = True
-#     mimetype = True
-#     if request.params.download == "false":
-#         download = False
-#     mimetype = request.params.mimetype or None
-
-#     return validate_file(filename, root='rest/static/files', download=download, mimetype=mimetype)
-
+    return HTTPResponse(content, **headers)
 
 @route('/<any>/', method='GET')
 def redirect_trailing_slash(any): return redirect(f'/{any}')

+ 11 - 0
util-sqlpage/sqlpage/validate.sql

@@ -6,6 +6,10 @@ UNION
 SELECT content
 FROM goto
 WHERE hash = $hash AND $tool = 'goto'
+UNION
+SELECT content
+FROM upload
+WHERE hash = $hash AND $tool = 'upload'
 );
 
 SET qr = (
@@ -16,8 +20,15 @@ UNION
 SELECT qr
 FROM goto
 WHERE hash = $hash AND $tool = 'goto'
+UNION
+SELECT qr
+FROM upload
+WHERE hash = $hash AND $tool = 'upload'
 );
 
+SET file_name = (SELECT name FROM upload WHERE hash = $hash AND $tool = 'upload');
+SET mime_type = (SELECT mime FROM upload WHERE hash = $hash AND $tool = 'upload');
+
 SET inner = CASE COALESCE($content,'') = ''
   WHEN TRUE THEN 'sqlpage/alert.sql'
   ELSE $tool||'/form.sql'

+ 5 - 1
util-sqlpage/upload/Index.sql

@@ -1,5 +1,9 @@
 SELECT 'dynamic' AS component, sqlpage.run_sql('sqlpage/Style.sql') AS properties;
-SET content = $upload;
+SET content = CASE
+  WHEN COALESCE($data_uri, '') = ''
+  THEN $content
+  ELSE $data_uri
+END;
 SET inner = CASE COALESCE($content,'') <> '' AND COALESCE($action, '') = 'Upload'
   WHEN TRUE THEN 'upload/save.sql'
   ELSE CASE COALESCE($hash,'') = ''

+ 24 - 1
util-sqlpage/upload/form.sql

@@ -14,7 +14,7 @@ SELECT 'New' AS title
 SELECT 'Download' AS title
 , 2 AS width
 , 'gray-500' AS color
-, '/upload/download.sql?hash='||$hash AS link
+, '/upload/'||$hash AS link
 ;
 
 SELECT 'form' AS component
@@ -30,13 +30,36 @@ SELECT 'Upload' AS value
 , 'action' AS name
 WHERE NOT $view
 ;
+SELECT 'file_name' AS name
+, '' AS label
+, TRUE AS required
+, 'name.ext' AS placeholder
+, 'File Name' AS prefix
+, 4 AS width
+WHERE NOT $view
+;
 SELECT 'content' AS name
 , CASE $view WHEN FALSE THEN 'file' ELSE 'hidden' END AS type
 , '' AS label
+, TRUE AS required
 --, $view AS disabled
 , CASE COALESCE($action, '')
   WHEN 'New' THEN NULL
   ELSE $content
 END AS value
+, 8 AS width
 WHERE NOT $view
 ;
+SELECT 'card' as component
+, 1 as columns
+WHERE $view
+;
+SELECT 'Preview' as title
+, CASE WHEN substr($mime_type, 0, instr($mime_type, '/')) = 'image' THEN $content ELSE NULL END AS top_image
+, '
+Uploaded file type: ' || COALESCE($mime_type, 'null') ||'
+
+Uploaded file type: ' || COALESCE($file_name, 'null') ||'
+' AS description_md
+WHERE $view
+;

+ 5 - 2
util-sqlpage/upload/save.sql

@@ -19,11 +19,14 @@ SET request = json_object(
     )
 );
 SET qr = sqlpage.fetch($request);
-INSERT INTO upload (hash, content, qr, created) VALUES ($hash, $content, $qr, CURRENT_TIMESTAMP)
+INSERT INTO upload (hash, content, name, mime, qr, created)
+VALUES ($hash, $content, $file_name, $mime_type, $qr, CURRENT_TIMESTAMP)
 ON CONFLICT DO
 UPDATE SET
   content = excluded.content,
+  name = excluded.name,
+  mime = excluded.mime,
   created = excluded.created,
   qr = excluded.qr
-WHERE excluded.created > clip.created;
+WHERE excluded.created > upload.created;
 SELECT 'dynamic' AS component, sqlpage.run_sql('sqlpage/link.sql') AS properties;