Parcourir la source

make qr size deterministic and move hash performance tests into test dir

Daniel Sheffield il y a 1 an
Parent
commit
8604ff3207
5 fichiers modifiés avec 44 ajouts et 45 suppressions
  1. 0 32
      app/rest/hash_util.py
  2. 3 3
      app/rest/pyapi.py
  3. 21 7
      app/rest/qr.py
  4. 6 2
      app/rest/save.py
  5. 14 1
      test/rest/test_hash_util.py

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 32
app/rest/hash_util.py


+ 3 - 3
app/rest/pyapi.py

@@ -112,7 +112,7 @@ def clip():
         else:
             content = None
         link = f'{LOCATION}/clip/{_hash}' if content else f'{LOCATION}/clip'
-        svg = get_qr_code(link if not content or len(content) > 300 else content)
+        svg = get_qr_code(content, fallback=link)
 
         response.content_type = 'text/html; charset=utf-8'
         form = template(
@@ -146,7 +146,7 @@ def clip():
             disabled=False
         )
         link = f'{LOCATION}/clip'
-        svg = get_qr_code(link if not content or len(content) > 300 else content)
+        svg = get_qr_code(content, fallback=link)
         return template(
             'paste',
             form=form,
@@ -221,7 +221,7 @@ def goto():
             return redirect(target)
 
         link = f'{LOCATION}/goto/{_hash}' if content else f'{LOCATION}/goto'
-        svg = get_qr_code(link if not content or len(content) > 300 else content)
+        svg = get_qr_code(content, fallback=link)
         disabled = True if content else False
         response.content_type = 'text/html; charset=utf-8'
         form = template(

+ 21 - 7
app/rest/qr.py

@@ -1,20 +1,34 @@
 import io
+from typing import Union
 from qrcode import QRCode
-from qrcode.constants import ERROR_CORRECT_H
+from qrcode.constants import ERROR_CORRECT_L, ERROR_CORRECT_M, ERROR_CORRECT_Q, ERROR_CORRECT_H
 from qrcode.image.styledpil import StyledPilImage
 from qrcode.image.svg import SvgPathImage
 from qrcode.image.styles.moduledrawers.svg import SvgCircleDrawer
 from qrcode.image.styles.colormasks import RadialGradiantColorMask
 
-def get_qr_code(data: bytes):
-    qr = QRCode(error_correction=ERROR_CORRECT_H)
-    qr.add_data(data.encode('utf-8'))
+QR_MAX_BYTES = {
+    ERROR_CORRECT_H: 1273,
+    ERROR_CORRECT_Q: 1663,
+    ERROR_CORRECT_M: 2331,
+    ERROR_CORRECT_L: 2953,
+}
+def get_qr_code(data: Union[bytes, str], fallback: Union[bytes, str] = None):
+    err_lvl = ERROR_CORRECT_H
+    qr = QRCode(error_correction=err_lvl)
+    if data is not None and isinstance(data, str):
+        data = data.encode('utf-8')
+    if fallback is not None and isinstance(fallback, str):
+        fallback = fallback.encode('utf-8')
+    if fallback is not None and data and len(data) > QR_MAX_BYTES[err_lvl]:
+        qr.add_data(fallback, optimize=0)
+    else:
+        qr.add_data(data or fallback, optimize=0)
 
-    img_1 = qr.make_image(image_factory=SvgPathImage,)
-    #module_drawer=SvgCircleDrawer())
+    img_1 = qr.make_image(image_factory=SvgPathImage)
     with io.BytesIO() as f:
         img_1.save(f)
         f.flush()
         ret = f.getvalue()
     return ret
-    
+    

+ 6 - 2
app/rest/save.py

@@ -5,7 +5,7 @@
 # THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
 
 from hashlib import blake2b
-from io import BufferedRandom
+from io import BufferedRandom, BytesIO
 import os
 from uuid import uuid4
 from .hash_util import DIGEST_SIZE_BYTES, blake, bytes_to_base32
@@ -34,7 +34,11 @@ def save_upload(name: str, content: BufferedRandom, root='app/rest/static') -> s
     unique = uuid4()
     fd = os.open(f'{tmpdir}/{unique.hex}', os.O_WRONLY | os.O_TRUNC | os.O_CREAT, 0o600)
     with open(fd, "wb") as f:
-        while content.peek(1):
+        done = False
+        if isinstance(content, BytesIO):
+            f.write(content.getvalue())
+            done = True
+        while not done and content.peek(1):
             seg = content.read(1024)
             f.write(seg)
     

Fichier diff supprimé car celui-ci est trop grand
+ 14 - 1
test/rest/test_hash_util.py


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff