From 248591020256aa4444e22417079a7b2d0b5579ee Mon Sep 17 00:00:00 2001 From: Benjamin Bertrand <benjamin.bertrand@esss.se> Date: Sat, 30 Dec 2017 21:35:47 +0100 Subject: [PATCH] Cache QR codes image generation The generation of the QR code image is quite slow and makes the page displaying them take a long time to load when it includes more a few. The data never changes and can easily be cached (the repr() of the class is used in the cache key, so if the name or id changes, the cache will be recomputed - there is no need for a timeout). --- app/inventory/views.py | 2 +- app/models.py | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/inventory/views.py b/app/inventory/views.py index 20a9a36..70746c3 100644 --- a/app/inventory/views.py +++ b/app/inventory/views.py @@ -146,7 +146,7 @@ def qrcodes(kind='Action'): raise utils.CSEntryError(f"Unknown model '{kind}'", status_code=422) items = db.session.query(model).order_by(model.name) images = [{'name': item.name, - 'data': utils.image_to_base64(item.image())} + 'data': item.base64_image()} for item in items] return render_template('inventory/qrcodes.html', kind=kind, images=images) diff --git a/app/models.py b/app/models.py index 2d0d7b9..4788849 100644 --- a/app/models.py +++ b/app/models.py @@ -22,7 +22,7 @@ from citext import CIText from flask import current_app from flask_login import UserMixin from wtforms import ValidationError -from .extensions import db, login_manager, ldap_manager +from .extensions import db, login_manager, ldap_manager, cache from .plugins import FlaskUserPlugin from .validators import ICS_ID_RE, HOST_NAME_RE, VLAN_NAME_RE from . import utils @@ -209,14 +209,25 @@ class QRCodeMixin: data = ':'.join(['CSE', self.__tablename__, self.name]) return qrcode.make(data, version=1, box_size=5) + @cache.memoize(timeout=0) + def base64_image(self): + """Return the QRCode image as base64 string""" + return utils.image_to_base64(self.image()) + def __str__(self): return self.name + def __repr__(self): + # The cache.memoize decorator performs a repr() on the passed in arguments + # __repr__ is used as part of the cache key and shall be a uniquely identifying string + # See https://flask-caching.readthedocs.io/en/latest/#memoization + return f'{self.__class__.__name__}(id={self.id}, name={self.name})' + def to_dict(self): return { 'id': self.id, 'name': self.name, - 'qrcode': utils.image_to_base64(self.image()), + 'qrcode': self.base64_image(), } -- GitLab