Remove qrcode library and replace with django-qre-code

Required some rework to make qr-codes work via a template machanism. I think
that the new solution is working neatly as well.
This commit is contained in:
Paul Konstantin Gerke 2022-08-30 21:26:45 +02:00
parent 9723bccc40
commit be4f987d35
7 changed files with 16 additions and 109 deletions

View File

@ -23,7 +23,7 @@ pyyaml = "*"
uritemplate = "*"
whitenoise = "*"
django-taggit = "*"
qrcode = "*"
django-qr-code = "*"
[dev-packages]
coveralls = "*"

View File

@ -36,6 +36,7 @@ INSTALLED_APPS = [
"imagekit",
"storages",
"import_export",
"qr_code",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",

View File

@ -0,0 +1,4 @@
{% load i18n widget_tweaks babybuddy_tags qr_code %}
{% url 'babybuddy:root-router' as relative_root_url %}
{% make_absolute_url relative_root_url as absolute_root_url %}
BABYBUDDY-LOGIN:{"url":"{{ absolute_root_url }}","api_key":"{{ user.settings.api_key }}"}

View File

@ -1,5 +1,5 @@
{% extends 'babybuddy/page.html' %}
{% load i18n widget_tweaks babybuddy_tags %}
{% load i18n widget_tweaks babybuddy_tags qr_code %}
{% block title %}{% trans "User Settings" %}{% endblock %}
@ -87,12 +87,9 @@
<div class="form-group row">
<label class="col-sm-2 col-form-label">{% trans "Login QR code" %}</label>
<div class="col-sm-10">
{% url 'babybuddy:root-router' as relative_root_url %}
{% make_absolute_url relative_root_url as absolute_root_url %}
<img src="{% qrcodepng stripwhitespace %}
BABYBUDDY-LOGIN:{"url":"{{ absolute_root_url }}","api_key":"{{ user.settings.api_key }}"}
{% endqrcodepng %}">
<div style="display:inline-block;background-color:white;">
{% qr_from_text qr_code_data size="s" %}
</div>
</div>
</div>
</fieldset>

View File

@ -67,103 +67,3 @@ def make_absolute_url(context, url):
request = context["request"]
abs_url = request.build_absolute_uri(url)
return abs_url
class QrCodeNode(template.Node):
def __init__(self, nodelist, strip, border, box_size) -> None:
super().__init__()
self.__nodelist = nodelist
self.__strip = strip
self.__border = border
self.__box_size = box_size
def render(self, context):
contents = ""
for node in self.__nodelist:
contents += node.render(context)
if self.__strip:
contents = contents.strip()
import qrcode
qr = qrcode.QRCode(border=self.__border, box_size=self.__box_size)
qr.add_data(contents)
qr.make(fit=True)
image = qr.make_image()
bytesio = io.BytesIO()
image.save(bytesio, format="png")
base64_data = base64.b64encode(bytesio.getbuffer()).decode()
return f"data:image/png;base64,{base64_data}"
@register.tag_function
def qrcodepng(parser, token):
"""
This template tag allows the generation of arbirary qr code pngs that
can be displayed, for example, in <img src="..."> html tags.
The template tag can be used as follows:
<img src="{% qrcodepng %}
Hello world
{% endqrcodepng %}">
This will produce a qrcode that encodes the
string "\n Hello World\n ". One can use the qrcode parameter
``stripwhitespace`` to strip the extra whitespace at the start and end of
the string:
{% qrcodepng stripwhitespace %}
All supported arguments:
- stripwhitespace: strip whitespace of the qrcode-contents
- border=[int]: Border of the qrcode in pixels (default: 1)
- box_size=[int]: Pixel size of the qr-code blocks (default: 5)
"""
contents = token.split_contents()
params = contents[1:]
def get_parameter(name: str, value_type=None):
search_for = name
if value_type is not None:
search_for += "="
for p in params:
if p.startswith(search_for):
if value_type is None:
if p != search_for:
continue
params.remove(p)
return True
else:
str_value = p[len(search_for) :]
try:
result = value_type(str_value)
except ValueError:
raise template.TemplateSyntaxError(
f"Invalid parameter '{p}' does "
f"not have type '{value_type}'"
)
else:
params.remove(p)
return result
if value_type is None:
return False
return None
strip = get_parameter("stripwhitespace")
border = get_parameter("border", int) or 1
box_size = get_parameter("box_size", int) or 5
if params:
raise template.TemplateSyntaxError(
f"Unkown arguments for qrcode template tag: {', '.join(params)}"
)
nodelist = parser.parse(("endqrcodepng",))
parser.delete_first_token()
return QrCodeNode(nodelist, strip, border, box_size)

View File

@ -160,16 +160,21 @@ class UserSettings(LoginRequiredMixin, View):
form_user_class = forms.UserForm
form_settings_class = forms.UserSettingsForm
template_name = "babybuddy/user_settings_form.html"
qr_code_template = "babybuddy/login_qr_code.txt"
def get(self, request):
settings = request.user.settings
qr_code_response = render(request, self.qr_code_template)
qr_code_data = qr_code_response.content.decode().strip()
return render(
request,
self.template_name,
{
"form_user": self.form_user_class(instance=request.user),
"form_settings": self.form_settings_class(instance=settings),
"qr_code_data": qr_code_data,
},
)

View File

@ -12,6 +12,7 @@ django-filter==22.1
django-imagekit==4.1.0
django-import-export==2.8.0
django-ipware==4.0.2
django-qr-code==3.1.1
django-storages==1.12.3
django-taggit==3.0.0
django-widget-tweaks==1.4.12
@ -31,7 +32,6 @@ python-dateutil==2.8.2
python-dotenv==0.20.0
pytz==2022.1
pyyaml==6.0
qrcode==7.3.1
s3transfer==0.6.0
setuptools==63.1.0
six==1.16.0