templatetags: add a qrcode filter for string values (#55189)
This commit is contained in:
parent
bc4112b4c5
commit
e9c5baba07
Binary file not shown.
|
@ -11,6 +11,10 @@ try:
|
|||
except ImportError:
|
||||
langdetect = None
|
||||
|
||||
import PIL
|
||||
from pyzbar.pyzbar import ZBarSymbol
|
||||
from pyzbar.pyzbar import decode as zbar_decode_qrcode
|
||||
|
||||
from wcs import fields
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.qommon.http_request import HTTPRequest
|
||||
|
@ -1217,3 +1221,27 @@ def test_iterate_days_until(pub):
|
|||
)
|
||||
|
||||
assert t.render({'value': 'error1', 'value2': 'error2'}) == ''
|
||||
|
||||
|
||||
def test_qrcode(pub):
|
||||
with pub.complex_data():
|
||||
img = Template('{{ url|qrcode }}').render({'url': 'http://example.com/', 'allow_complex': True})
|
||||
assert pub.has_cached_complex_data(img)
|
||||
value = pub.get_cached_complex_data(img)
|
||||
assert value.orig_filename == 'qrcode.png'
|
||||
assert value.content_type == 'image/png'
|
||||
with value.get_file_pointer() as fp:
|
||||
img = PIL.Image.open(fp)
|
||||
assert img.size == (330, 330)
|
||||
assert (
|
||||
zbar_decode_qrcode(img, symbols=[ZBarSymbol.QRCODE])[0].data.decode() == 'http://example.com/'
|
||||
)
|
||||
|
||||
img = Template('{{ url|qrcode:"qrcode2.png" }}').render(
|
||||
{'url': 'http://example.com/', 'allow_complex': True}
|
||||
)
|
||||
value = pub.get_cached_complex_data(img)
|
||||
assert value.orig_filename == 'qrcode2.png'
|
||||
|
||||
img = Template('{{ url|qrcode }}').render({'url': 1, 'allow_complex': True})
|
||||
assert img == ''
|
||||
|
|
|
@ -17,6 +17,8 @@ except ImportError:
|
|||
Image = None
|
||||
|
||||
from django.utils.encoding import force_bytes, force_text
|
||||
from pyzbar.pyzbar import ZBarSymbol
|
||||
from pyzbar.pyzbar import decode as zbar_decode_qrcode
|
||||
from quixote import cleanup, get_publisher, get_response
|
||||
from quixote.http_request import Upload as QuixoteUpload
|
||||
|
||||
|
@ -3823,6 +3825,50 @@ def test_export_to_model_image(pub, template_name):
|
|||
)
|
||||
|
||||
|
||||
def test_export_to_model_qrcode(pub):
|
||||
FormDef.wipe()
|
||||
|
||||
formdef = FormDef()
|
||||
formdef.name = 'baz'
|
||||
formdef.fields = []
|
||||
formdef.store()
|
||||
|
||||
formdef.data_class().wipe()
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {}
|
||||
formdata.just_created()
|
||||
formdata.store()
|
||||
pub.substitutions.feed(formdata)
|
||||
|
||||
item = ExportToModel()
|
||||
item.convert_to_pdf = False
|
||||
item.method = 'non-interactive'
|
||||
template_filename = os.path.join(os.path.dirname(__file__), 'template-with-qrcode.odt')
|
||||
with open(template_filename, 'rb') as fd:
|
||||
template = fd.read()
|
||||
upload = QuixoteUpload('/foo/template.odt', content_type='application/octet-stream')
|
||||
upload.fp = io.BytesIO()
|
||||
upload.fp.write(template)
|
||||
upload.fp.seek(0)
|
||||
item.model_file = UploadedFile(pub.app_dir, None, upload)
|
||||
item.attach_to_history = True
|
||||
|
||||
item.perform(formdata)
|
||||
|
||||
assert formdata.evolution[-1].parts[-1].base_filename == 'template.odt'
|
||||
with zipfile.ZipFile(formdata.evolution[-1].parts[0].filename, mode='r') as zfile:
|
||||
# base template use a jpg images and export_to_model does not rename it
|
||||
# event when content is PNG, but it still works inside LibreOffice
|
||||
# which ignores the filename extension.
|
||||
image_filename = [name for name in zfile.namelist() if name.endswith('.jpg')][0]
|
||||
with zfile.open(image_filename, 'r') as image_fd:
|
||||
img = Image.open(image_fd)
|
||||
assert (
|
||||
zbar_decode_qrcode(img, symbols=[ZBarSymbol.QRCODE])[0].data.decode()
|
||||
== 'http://example.net/backoffice/management/baz/1/'
|
||||
)
|
||||
|
||||
|
||||
def test_export_to_model_backoffice_field(pub):
|
||||
wf = Workflow(name='email with attachments')
|
||||
wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
|
||||
|
|
1
tox.ini
1
tox.ini
|
@ -43,6 +43,7 @@ deps =
|
|||
pylint
|
||||
Quixote>=3.0,<3.2
|
||||
pre-commit
|
||||
pyzbar
|
||||
commands =
|
||||
py.test -v {env:COVERAGE:} --junitxml=junit-{envname}.xml {posargs:tests/}
|
||||
pylint: ./pylint.sh wcs/ tests/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue