From c55a17bac9174ad1932587181984572b570156b9 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 24 Jun 2021 19:24:47 +0200 Subject: [PATCH] templatetags: add a qrcode filter for string values --- tests/template-with-qrcode.odt | Bin 0 -> 9670 bytes tests/test_templates.py | 28 ++++++++++++++++++ tests/test_workflows.py | 46 ++++++++++++++++++++++++++++++ tox.ini | 1 + wcs/qommon/templatetags/qommon.py | 23 ++++++++++++++- 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 tests/template-with-qrcode.odt diff --git a/tests/template-with-qrcode.odt b/tests/template-with-qrcode.odt new file mode 100644 index 0000000000000000000000000000000000000000..062930391a9835f6c9282e905620112d693f15f9 GIT binary patch literal 9670 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.0,<3.2 pre-commit + pyzbar commands = py.test -v {env:COVERAGE:} --junitxml=junit-{envname}.xml {posargs:tests/} pylint: ./pylint.sh wcs/ tests/ diff --git a/wcs/qommon/templatetags/qommon.py b/wcs/qommon/templatetags/qommon.py index a4ecc7f9..f5fe1204 100644 --- a/wcs/qommon/templatetags/qommon.py +++ b/wcs/qommon/templatetags/qommon.py @@ -16,6 +16,7 @@ import datetime import hashlib +import io import math import random import string @@ -26,6 +27,12 @@ from decimal import DivisionByZero as DecimalDivisionByZero from decimal import InvalidOperation as DecimalInvalidOperation import pyproj + +try: + import qrcode +except ImportError: + qrcode = None + from pyproj import Geod from quixote import get_publisher @@ -42,7 +49,7 @@ from django.utils.encoding import force_bytes, force_text from django.utils.safestring import mark_safe from django.utils.timezone import is_naive, make_aware -from wcs.qommon import calendar, evalutils, tokens +from wcs.qommon import calendar, evalutils, tokens, upload_storage from wcs.qommon.admin.texts import TextsDirectory register = template.Library() @@ -817,3 +824,17 @@ def strip_metadata(value): def list_(value): # turn a generator into a list return list(unlazy(value)) + + +@register.filter(name='qrcode') +def qrcode_filter(value, name=None): + if not qrcode: + return '' + if not isinstance(value, str): + return '' + img = qrcode.make(value) + buf = io.BytesIO() + img.save(buf) + upload = upload_storage.PicklableUpload(name or 'qrcode.png', 'image/png') + upload.receive([buf.getvalue()]) + return upload -- 2.32.0.rc0