Shorten the form URL by compressing and b64 encoding it. In a real-world example, the baseline URL goes from 1086 characters to 620. This is good for the resulting QR barcode.
This commit is contained in:
parent
ce6b4a4420
commit
eae08e81f9
2 changed files with 30 additions and 3 deletions
|
|
@ -1,10 +1,12 @@
|
|||
import datetime
|
||||
import base64
|
||||
import html
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import traceback
|
||||
import uuid
|
||||
import zlib
|
||||
|
||||
import jinja2
|
||||
from tornado.web import Application, RequestHandler, StaticFileHandler
|
||||
|
|
@ -131,6 +133,14 @@ class CalculatorForm(BaseRequestHandler):
|
|||
self.finish(report)
|
||||
|
||||
|
||||
class CompressedCalculatorFormInputs(BaseRequestHandler):
|
||||
def get(self, compressed_args: str):
|
||||
# Convert a base64 zlib encoded shortened URL into a non compressed
|
||||
# URL, and redirect.
|
||||
args = zlib.decompress(base64.b64decode(compressed_args)).decode()
|
||||
self.redirect(f'/calculator?{args}')
|
||||
|
||||
|
||||
class ReadmeHandler(BaseRequestHandler):
|
||||
def get(self):
|
||||
template = self.settings['template_environment'].get_template("userguide.html.j2")
|
||||
|
|
@ -146,6 +156,7 @@ def make_app(debug=False, prefix='/calculator'):
|
|||
calculator_static_dir = Path(__file__).absolute().parent / 'static'
|
||||
urls = [
|
||||
(r'/?', LandingPage),
|
||||
(r'/c/(.*)', CompressedCalculatorFormInputs),
|
||||
(r'/static/(.*)', StaticFileHandler, {'path': static_dir}),
|
||||
(prefix + r'/?', CalculatorForm),
|
||||
(prefix + r'/report', ConcentrationModel),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from datetime import datetime
|
|||
import io
|
||||
from pathlib import Path
|
||||
import typing
|
||||
import zlib
|
||||
|
||||
import qrcode
|
||||
import urllib
|
||||
|
|
@ -70,7 +71,22 @@ def calculate_report_data(model: models.ExposureModel):
|
|||
|
||||
def generate_qr_code(prefix, form: FormData):
|
||||
form_dict = FormData.to_dict(form)
|
||||
url = prefix + "?" + urllib.parse.urlencode(form_dict)
|
||||
|
||||
# Generate the calculator URL arguments that would be needed to re-create this
|
||||
# form.
|
||||
args = urllib.parse.urlencode(form_dict)
|
||||
|
||||
# Then zlib compress + base64 encode the string. To be inverted by the
|
||||
# /c/ endpoint.
|
||||
qr_url = prefix + "/c/" + base64.b64encode(
|
||||
zlib.compress(args.encode())
|
||||
).decode()
|
||||
|
||||
# We show the human-friendly URL when hovering over the link, but for now
|
||||
# let's keep it the same as the QR URL to ensure everything continues to work
|
||||
# as expected (it takes more effort to validate QR barcodes than it does links).
|
||||
# url = prefix + "/calculator/?" + args
|
||||
url = qr_url
|
||||
|
||||
qr = qrcode.QRCode(
|
||||
version=1,
|
||||
|
|
@ -78,7 +94,7 @@ def generate_qr_code(prefix, form: FormData):
|
|||
box_size=10,
|
||||
border=4,
|
||||
)
|
||||
qr.add_data(url)
|
||||
qr.add_data(qr_url)
|
||||
qr.make(fit=True)
|
||||
img = qr.make_image(fill_color="black", back_color="white").convert('RGB')
|
||||
|
||||
|
|
@ -272,7 +288,7 @@ def build_report(base_url: str, model: models.ExposureModel, form: FormData):
|
|||
context.update(calculate_report_data(model))
|
||||
alternative_scenarios = manufacture_alternative_scenarios(form)
|
||||
context['alternative_scenarios'] = comparison_report(alternative_scenarios)
|
||||
context['qr_code'] = generate_qr_code(f'{base_url}/calculator', form)
|
||||
context['qr_code'] = generate_qr_code(base_url, form)
|
||||
|
||||
cara_templates = Path(__file__).parent.parent / "templates"
|
||||
calculator_templates = Path(__file__).parent / "templates"
|
||||
|
|
|
|||
Loading…
Reference in a new issue