소스 검색

embed content when possible

Daniel Sheffield 1 년 전
부모
커밋
d7b27b7ea6
3개의 변경된 파일42개의 추가작업 그리고 14개의 파일을 삭제
  1. 11 4
      app/rest/pyapi.py
  2. 14 3
      app/rest/templates/upload.tpl
  3. 17 7
      app/rest/validate.py

+ 11 - 4
app/rest/pyapi.py

@@ -18,7 +18,7 @@ from psycopg.rows import TupleRow
 from linkpreview import link_preview
 
 from .qr import get_qr_code
-from .validate import validate, validate_file, validate_parameter, validate_url
+from .validate import get_file_mimetype, get_filename, validate, validate_file, validate_parameter, validate_url
 from .hash_util import normalize_base32
 from .route_decorators import normalize, poison, cursor
 from .query_to_xml import get_categories, get_groups, get_products, get_tags
@@ -176,14 +176,18 @@ def upload():
 
     if request.method == 'GET':
         _hash = request.params.hash
+        mimetype = None
         if _hash:
             _hash = normalize_base32(_hash)
-
+            name = get_filename(_hash)
+            mimetype = get_file_mimetype(name)
+        
         link = f'{LOCATION}/upload/{_hash}' if _hash else f'{LOCATION}/upload'
         response.content_type = 'text/html; charset=utf-8'
         form = template('file-form', action='/upload', method='post')
         svg = get_qr_code(link)
-        return template('upload', form=form, svg=svg, link=link)
+        
+        return template('upload', form=form, svg=svg, link=link, mimetype=mimetype)
 
     if request.method == 'POST':
         if 'paste' not in request.files:
@@ -201,8 +205,11 @@ def upload():
 @route('/upload/<filename:path>', method='GET')
 def get_upload(filename):
     filename = filename and normalize_base32(filename)
+    download = True
+    if request.params.download == "false":
+        download = False
 
-    return validate_file(filename)
+    return validate_file(filename, download=download)
 
 
 @route('/goto', method=['GET', 'POST'])

+ 14 - 3
app/rest/templates/upload.tpl

@@ -1,7 +1,6 @@
 % link = setdefault("link", "") or ""
 % disabled = setdefault("disabled", "") and 'disabled="true"'
-% download = setdefault("download", "") or ""
-% download_disabled = "" if download else 'disabled="true"'
+% mimetype = (setdefault("mimetype", None) is not True and mimetype) or None
 <!DOCTYPE html>
 <html>
   <head>
@@ -19,6 +18,11 @@ svg {
   color: black;
   max-height: min(100vh, calc(100vw * 9 / 16));
   max-width: calc(100vw - 2em);
+}
+iframe {
+  color: floralwhite;
+  background: darkgray;
+  height: 60vh;
 }
     </style>
     <title>Upload</title>
@@ -37,12 +41,19 @@ svg {
       </div>
       <div class="pure-u-1">
         <div class="pure-button" style="margin: 1em 0 0; background: #afaf0f;">
-          <a href="{{!link}}" style="color: floralwhite;">{{ link }}</a>
+          <a href="{{link}}" style="color: floralwhite;">{{ link }}</a>
         </div>
       </div>
       <div class="pure-u-1">
         <p><details><summary> Show QR code ...</summary>{{!svg}}</details></p>
 {{!form}}
+        <p>
+        % if mimetype and not mimetype.startswith('text'):
+        <embed type="{{mimetype}}" src="{{link}}" width="80%"></embed>
+        % elif mimetype:
+        <iframe src="{{link}}?download=false" width="80%" height="50%"></iframe>
+        % end
+        </p>
       </div>
     </div>
   </body>

+ 17 - 7
app/rest/validate.py

@@ -58,19 +58,28 @@ def validate(filename: str) -> bytes:
         return abort(410, f"Paste content differs")
     return content
 
-def validate_file(filename: str, root: str = 'app/rest/static') -> HTTPResponse:
+
+def get_filename(filename: str, root: str = 'app/rest/static'):
     path = '/'.join([filename,]*2)
     try:
         with open(f'{root}/{path}.name', "r") as f:
             name = f.read()
+        return name
     except:
-        name = None
-    if name:
-        mimetype, enc = mimetypes.guess_type(name)
-    else:
-        mimetype = True
+        pass
+
+def get_file_mimetype(name):
+    mimetype = mimetypes.guess_type(name, strict=False)[0] if name else True
+    return mimetype
+
+
+def validate_file(filename: str, root: str = 'app/rest/static', download=True) -> HTTPResponse:
+    path = '/'.join([filename,]*2)
+
+    name = get_filename(filename)
+    mimetype = get_file_mimetype(name)
     
-    ret = static_file(f'{path}.file', root=root, download=name or True, mimetype=mimetype)
+    ret = static_file(f'{path}.file', root=root, download=name if name and download else download, mimetype=mimetype)
     if isinstance(ret, HTTPError):
         return abort(404, f"No such upload: {filename}")
 
@@ -80,6 +89,7 @@ def validate_file(filename: str, root: str = 'app/rest/static') -> HTTPResponse:
         return abort(410, f"Uploaded content differs")
     return ret
 
+
 def validate_parameter(request: LocalRequest, name: str) -> bytes:
     if name not in request.params:
         return abort(400, f"Missing parameter: '{name}'")