2021-08-07 17:37:36 +02:00
|
|
|
from django.core.exceptions import ValidationError, ObjectDoesNotExist
|
|
|
|
from django.urls import reverse as url_reverse
|
|
|
|
import re
|
|
|
|
|
2021-11-09 18:44:28 +01:00
|
|
|
from .models import Storage, Component
|
2021-08-07 17:37:36 +02:00
|
|
|
|
|
|
|
class QrCode:
|
|
|
|
prefix = ''
|
|
|
|
detail_view = ''
|
|
|
|
model = None
|
|
|
|
|
|
|
|
def __init__(self, prefix, detail_view, model):
|
|
|
|
self.prefix = prefix
|
|
|
|
self.detail_view = detail_view
|
|
|
|
self.model = model
|
|
|
|
|
|
|
|
class QrCodeValidator:
|
|
|
|
|
|
|
|
qr_patterns = {
|
2021-11-09 18:44:28 +01:00
|
|
|
'stor_uuid': QrCode('stor_uuid', 'parts-stocks-detail', Storage),
|
|
|
|
'comp_uuid': QrCode('comp_uuid', 'parts-components-detail', Component),
|
2021-08-07 17:37:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
self.qr_regex = re.compile(r'^\[(?P<prefix>[a-zA-Z_]+)\](?P<uuid>[a-fA-F0-9\-]+)')
|
|
|
|
self.redirect_url = None
|
|
|
|
|
|
|
|
def _get_model_from_qr(self, qr):
|
|
|
|
matches = self.qr_regex.match(qr)
|
|
|
|
if matches is None:
|
|
|
|
raise ValidationError("QR Code does not match expected pattern")
|
|
|
|
|
|
|
|
qr_type = matches.group('prefix')
|
|
|
|
qr_uuid = matches.group('uuid')
|
|
|
|
url_name = self.qr_patterns[qr_type].detail_view
|
|
|
|
|
|
|
|
model = None
|
|
|
|
try:
|
|
|
|
model = self.qr_patterns[qr_type].model
|
|
|
|
except:
|
|
|
|
model = None
|
|
|
|
if model is None:
|
|
|
|
raise ValidationError('QR Pattern not registered')
|
|
|
|
return (model,qr_uuid, url_name)
|
|
|
|
|
|
|
|
def get_redirect_url(self, data):
|
|
|
|
model, uuid, url_name = self._get_model_from_qr(data)
|
|
|
|
|
|
|
|
_ = model.objects.get(id=uuid)
|
|
|
|
return url_reverse(url_name, kwargs={'uuid':uuid})
|
|
|
|
|
|
|
|
def validate(self, data, *args, **kwargs):
|
|
|
|
try:
|
|
|
|
_ = self.get_redirect_url(data)
|
|
|
|
except ObjectDoesNotExist as err:
|
|
|
|
raise ValidationError('Object with given UUID could not be found')
|
|
|
|
|
|
|
|
def __call__(self, *args, **kwargs):
|
|
|
|
self.validate(*args, **kwargs)
|