瀏覽代碼

prepare for PWA by adding an Open button

Breaking change: 'person' parameter is keyed off the route. All goto hashes will be invalidated
Daniel Sheffield 1 年之前
父節點
當前提交
b61627c80b

+ 6 - 3
rest/pyapi.py

@@ -35,7 +35,7 @@ def clip():
         _hash = request.params.hash
         if _hash:
             _hash = normalize_base32(_hash)
-            content = validate(_hash).decode('utf-8')
+            content = validate(_hash, 'clip', root='rest/static/files').decode('utf-8')
         else:
             content = None
         link = f'{LOCATION}/clip/{_hash}' if content else f'{LOCATION}/clip'
@@ -81,6 +81,9 @@ def clip():
             download=None
         )
 
+@route('/<route:re:(clip|upload|goto)>/open')
+def _get_clip(route):
+    return template('form-open', tool=route, action=f'/{route}', method='get')
 
 @route('/clip/<filename:path>', method='GET')
 def get_clip(filename):
@@ -99,7 +102,7 @@ def get_clip(filename):
         # TODO: return a form with timeout to a GET instead ?
         return redirect(f'/clip?hash={filename}')
 
-    ret = validate(filename)
+    ret = validate(filename, 'clip', root='rest/static/files')
     if isinstance(ret, HTTPError):
         return ret
 
@@ -176,7 +179,7 @@ def goto():
         _hash = request.params.hash
         if _hash:
             _hash = normalize_base32(_hash)
-            content = validate(_hash, root='rest/static/files').decode('utf-8')
+            content = validate(_hash, 'goto', root='rest/static/files').decode('utf-8')
         else:
             content = None
 

+ 1 - 0
rest/templates/clip-form.tpl

@@ -36,3 +36,4 @@ textarea::-webkit-scrollbar-thumb {
   <input id="copy" name="copy" type="text" value="true" hidden="true" />
 </form>
 <form id="new" method="get" action="{{ action }}"></form>
+<form id="open" method="get" action="{{ action }}/open"></form>

+ 2 - 1
rest/templates/file-form.tpl

@@ -3,4 +3,5 @@
 <form id="upload" method="{{ method }}" action="{{ action }}" enctype="multipart/form-data">
   <input type="file" name="paste" required="true" {{disabled}} />
 </form>
-<form id="new" method="get" action="{{ action }}"></form>
+<form id="new" method="get" action="{{ action }}"></form>
+<form id="open" method="get" action="{{ action }}/open"></form>

+ 48 - 0
rest/templates/form-open.tpl

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+html {
+  --scrollbarBG: #333333;
+  --thumbBG: #080808;
+}
+body {
+  background-color: #080808;
+  color: #cccccc;
+}
+label span {
+    font-size: 2em;
+}
+input[type=text] {
+    font-size: 3em;
+    text-align: center;
+}
+button[type=submit] {
+    font-size: 1.5em;
+}
+    </style>
+    <title>Open {{tool}}</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/purecss@2.1.0/build/pure-min.css" integrity="sha384-yHIFVG6ClnONEA5yB5DJXfW2/KC173DIQrYoZMEtBvGzmf0PKiGyNEqe9N6BNDBH" crossorigin="anonymous"/>
+    <link rel="stylesheet" href="https://shandan.one/css/grids-responsive-min.css"/>
+    <link rel="stylesheet" href="https://shandan.one/css/responsive-visibility-collapse.css"/>
+  </head>
+  <body align="center" style="text-align: center">
+      % include('button-style')
+      <form id="{{tool}}-open" action="{{action}}" method="{{method}}">
+        <label for="{{tool}}-code"><span>Enter Code</span></label>
+        <br/>
+        <input
+          type="text"
+          id="{{tool}}-code"
+          name="hash"
+          placeholder="ABC12"
+          required="true"
+          pattern="[A-TV-Za-tv-z0-9]{5}"
+          size="5"
+        ></input>
+        <p/>
+        <button class="button-resize pure-button" type="submit" form="{{tool}}-open"> Open </button>
+    </form>
+  </body>
+</html>

+ 1 - 0
rest/templates/goto-form.tpl

@@ -32,3 +32,4 @@ input[type="url"]::-webkit-scrollbar-thumb {
   ></input>
 </form>
 <form id="new" method="get" action="{{ action }}"></form>
+<form id="open" method="get" action="{{ action }}/open"></form>

+ 1 - 0
rest/templates/goto.tpl

@@ -31,6 +31,7 @@ img {
       % include('button-style')
       <div class="pure-u-1">
         <div class="pure-button-group" role="action" style="padding: 1em 0 0;">
+          <button class="button-resize pure-button" type="submit" form="open"> Open </button>
           <button class="button-resize pure-button" type="submit" form="new"> New </button>
           <button class="button-resize pure-button" type="submit" form="goto" {{!disabled}}> Shrtn It! </button>
         </div>

+ 1 - 0
rest/templates/paste.tpl

@@ -32,6 +32,7 @@ img {
       % include('button-style')
       <div class="pure-u-1">
         <div class="pure-button-group" role="action" style="padding: 1em 0 0;">
+          <button class="button-resize pure-button" type="submit" form="open"> Open </button>
           <button class="button-resize pure-button" type="submit" form="new"> New </button>
           <button class="button-resize pure-button" type="submit" form="copy"> Edit as New </button>
           <button class="button-resize pure-button" type="submit" form="paste" {{!disabled}}> Paste </button>

+ 1 - 0
rest/templates/upload.tpl

@@ -45,6 +45,7 @@ object.text {
       % include('button-style')
       <div class="pure-u-1">
         <div class="pure-button-group" role="action" style="padding: 1em 0 0;">
+          <button class="button-resize pure-button" type="submit" form="open"> Open </button>
           <button class="button-resize pure-button" type="submit" form="new"> New </button>
           <button class="button-resize pure-button" type="submit" form="upload" {{!disabled}}> Upload </button>
           <button class="button-resize pure-button" type="submit" form="download" {{!download_disabled}}> Download </button>

+ 12 - 7
rest/validate.py

@@ -43,20 +43,20 @@ URL_MUST_ESCAPE = bytes([
 URL_SAFE = bytes(( i for i in range(int('0xff',0)+1) if i not in map(int, URL_MUST_ESCAPE) ))
 
 CLIP_SIZE_LIMIT = 65535
-def validate(filename: str, root='rest/static/files') -> bytes:
+def validate(filename: str, tool: str, root='rest/static/files') -> bytes:
     ret = static_file('/'.join([filename,]*2) + '.file', root=root)
     if isinstance(ret, HTTPError):
-        return abort(404, f"No such paste: {filename}")
+        return abort(404, f"No such `{tool.title()}`: {filename}")
 
     if ret.content_length > CLIP_SIZE_LIMIT:
-        return abort(418, f"Paste size exceeds {CLIP_SIZE_LIMIT}")
+        return abort(418, f"{tool.title()} size exceeds {CLIP_SIZE_LIMIT}")
 
     content: bytes = ret.body.read() if isinstance(ret.body, BufferedReader) else ret.body.encode('utf-8')
 
-    _bytes = blake(content, person='clip'.encode('utf-8'))
+    _bytes = blake(content, person=tool.encode('utf-8'))
     _b32 = bytes_to_base32(_bytes)
     if _b32 != filename:
-        return abort(410, f"Paste content differs")
+        return abort(410, f"{tool.title()} content differs")
     return content
 
 
@@ -86,9 +86,14 @@ def validate_file(filename: str, root: str = 'rest/static/files', download=True,
     name = get_filename(filename)
     mimetype = mimetype if mimetype and mimetype is not True else get_file_mimetype(name)
     
-    ret = static_file(f'{path}.file', root=root, download=name if name and download else download, mimetype=mimetype)
+    ret = static_file(
+        f'{path}.file',
+        root=root,
+        download=name if name and download else download,
+        mimetype='auto' if mimetype is True else mimetype
+    )
     if isinstance(ret, HTTPError):
-        return abort(404, f"No such upload: {filename}")
+        return abort(404, f"No such `Upload`: {filename}")
 
     _bytes = blake_file(f'{path}.file', person='upload'.encode('utf-8'), root=root)
     _b32 = bytes_to_base32(_bytes)