mirror of https://github.com/snachodog/mybuddy.git
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:
parent
9723bccc40
commit
be4f987d35
2
Pipfile
2
Pipfile
|
@ -23,7 +23,7 @@ pyyaml = "*"
|
||||||
uritemplate = "*"
|
uritemplate = "*"
|
||||||
whitenoise = "*"
|
whitenoise = "*"
|
||||||
django-taggit = "*"
|
django-taggit = "*"
|
||||||
qrcode = "*"
|
django-qr-code = "*"
|
||||||
|
|
||||||
[dev-packages]
|
[dev-packages]
|
||||||
coveralls = "*"
|
coveralls = "*"
|
||||||
|
|
|
@ -36,6 +36,7 @@ INSTALLED_APPS = [
|
||||||
"imagekit",
|
"imagekit",
|
||||||
"storages",
|
"storages",
|
||||||
"import_export",
|
"import_export",
|
||||||
|
"qr_code",
|
||||||
"django.contrib.admin",
|
"django.contrib.admin",
|
||||||
"django.contrib.auth",
|
"django.contrib.auth",
|
||||||
"django.contrib.contenttypes",
|
"django.contrib.contenttypes",
|
||||||
|
|
|
@ -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 }}"}
|
|
@ -1,5 +1,5 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load i18n widget_tweaks babybuddy_tags %}
|
{% load i18n widget_tweaks babybuddy_tags qr_code %}
|
||||||
|
|
||||||
{% block title %}{% trans "User Settings" %}{% endblock %}
|
{% block title %}{% trans "User Settings" %}{% endblock %}
|
||||||
|
|
||||||
|
@ -87,12 +87,9 @@
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-2 col-form-label">{% trans "Login QR code" %}</label>
|
<label class="col-sm-2 col-form-label">{% trans "Login QR code" %}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
{% url 'babybuddy:root-router' as relative_root_url %}
|
<div style="display:inline-block;background-color:white;">
|
||||||
{% make_absolute_url relative_root_url as absolute_root_url %}
|
{% qr_from_text qr_code_data size="s" %}
|
||||||
|
</div>
|
||||||
<img src="{% qrcodepng stripwhitespace %}
|
|
||||||
BABYBUDDY-LOGIN:{"url":"{{ absolute_root_url }}","api_key":"{{ user.settings.api_key }}"}
|
|
||||||
{% endqrcodepng %}">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
|
@ -67,103 +67,3 @@ def make_absolute_url(context, url):
|
||||||
request = context["request"]
|
request = context["request"]
|
||||||
abs_url = request.build_absolute_uri(url)
|
abs_url = request.build_absolute_uri(url)
|
||||||
return abs_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)
|
|
||||||
|
|
|
@ -160,16 +160,21 @@ class UserSettings(LoginRequiredMixin, View):
|
||||||
form_user_class = forms.UserForm
|
form_user_class = forms.UserForm
|
||||||
form_settings_class = forms.UserSettingsForm
|
form_settings_class = forms.UserSettingsForm
|
||||||
template_name = "babybuddy/user_settings_form.html"
|
template_name = "babybuddy/user_settings_form.html"
|
||||||
|
qr_code_template = "babybuddy/login_qr_code.txt"
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
settings = request.user.settings
|
settings = request.user.settings
|
||||||
|
|
||||||
|
qr_code_response = render(request, self.qr_code_template)
|
||||||
|
qr_code_data = qr_code_response.content.decode().strip()
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
self.template_name,
|
self.template_name,
|
||||||
{
|
{
|
||||||
"form_user": self.form_user_class(instance=request.user),
|
"form_user": self.form_user_class(instance=request.user),
|
||||||
"form_settings": self.form_settings_class(instance=settings),
|
"form_settings": self.form_settings_class(instance=settings),
|
||||||
|
"qr_code_data": qr_code_data,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ django-filter==22.1
|
||||||
django-imagekit==4.1.0
|
django-imagekit==4.1.0
|
||||||
django-import-export==2.8.0
|
django-import-export==2.8.0
|
||||||
django-ipware==4.0.2
|
django-ipware==4.0.2
|
||||||
|
django-qr-code==3.1.1
|
||||||
django-storages==1.12.3
|
django-storages==1.12.3
|
||||||
django-taggit==3.0.0
|
django-taggit==3.0.0
|
||||||
django-widget-tweaks==1.4.12
|
django-widget-tweaks==1.4.12
|
||||||
|
@ -31,7 +32,6 @@ python-dateutil==2.8.2
|
||||||
python-dotenv==0.20.0
|
python-dotenv==0.20.0
|
||||||
pytz==2022.1
|
pytz==2022.1
|
||||||
pyyaml==6.0
|
pyyaml==6.0
|
||||||
qrcode==7.3.1
|
|
||||||
s3transfer==0.6.0
|
s3transfer==0.6.0
|
||||||
setuptools==63.1.0
|
setuptools==63.1.0
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
|
|
Loading…
Reference in New Issue