from django.core.exceptions import ValidationError, ObjectDoesNotExist from django.urls import reverse as url_reverse import re from .models import Storage, Component 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 = { 'stor_uuid': QrCode('stor_uuid', 'parts-stocks-detail', Storage), 'comp_uuid': QrCode('comp_uuid', 'parts-components-detail', Component), } def __init__(self): self.qr_regex = re.compile(r'^\[(?P[a-zA-Z_]+)\](?P[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)