qr-verify: Accept multiple images

This commit is contained in:
Fam Zheng 2025-05-10 22:00:39 +01:00
parent 42652eb221
commit 9f0a24e4d9

View File

@ -630,18 +630,27 @@ class LoginView(BaseView):
return JsonResponse({"token": token.token, 'role': 'tenant', 'id': tenant.pk}) return JsonResponse({"token": token.token, 'role': 'tenant', 'id': tenant.pk})
return http401() return http401()
def get_image_from_data_url(data_url):
pref = "data:image/jpeg;base64,"
if data_url and data_url.startswith(pref):
return base64.b64decode(data_url[len(pref):]), "image.jpg"
pref = "data:image/png;base64,"
if data_url and data_url.startswith(pref):
return base64.b64decode(data_url[len(pref):]), "image.png"
def get_images(request):
f = request.data.get("image_data_urls")
if f:
return [get_image_from_data_url(d) for d in f]
return [get_image(request)]
def get_image(request): def get_image(request):
f = request.FILES.get('photo') or request.FILES.get('file') f = request.FILES.get('photo') or request.FILES.get('file')
if f: if f:
return f.read(), f.name return f.read(), f.name
f = request.data.get("image_data_url") f = request.data.get("image_data_url")
pref = "data:image/jpeg;base64," if f:
if f and f.startswith(pref): return get_image_from_data_url(f)
return base64.b64decode(f[len(pref):]), "image.jpg"
pref = "data:image/png;base64,"
if f and f.startswith(pref):
return base64.b64decode(f[len(pref):]), "image.png"
return None, None return None, None
def get_code_from_url(url): def get_code_from_url(url):
@ -659,12 +668,13 @@ def get_code_from_url(url):
class QrVerifyView(BaseView): class QrVerifyView(BaseView):
name = 'qr-verify' name = 'qr-verify'
def do_v5_qr_verify(self, img_fn, messages): def do_v5_qr_verify(self, imgs, messages):
files = {}
for i, img in enumerate(imgs):
files[f'frame_{i}_{img[1]}'] = img[0]
resp = requests.post( resp = requests.post(
"https://themblem.com/api/v5/qr_verify", "https://themblem.com/api/v5/qr_verify",
files={ files=files,
'frame': open(img_fn, 'rb'),
},
) )
rd = resp.json() rd = resp.json()
messages.append(f"v5 qr_verify response: {rd}") messages.append(f"v5 qr_verify response: {rd}")
@ -681,22 +691,6 @@ class QrVerifyView(BaseView):
sd.client_log = request.data.get("log") sd.client_log = request.data.get("log")
messages = [] messages = []
try: try:
filebody, filename = get_image(request)
if not filebody:
return http400("image is missing")
tf = tempfile.NamedTemporaryFile(dir="/tmp/", suffix=filename)
tf.write(filebody)
tf.flush()
image_name = 'scandata_v1/' + str(uuid.uuid4()) + '-' + filename
if settings.ENV != "DEBUG" or os.environ.get("EMBLEM_ENABLE_OSS"):
f = open(tf.name, 'rb')
t = threading.Thread(target=oss_put, args=(image_name, f))
t.run()
sd.image = image_name
sd.ip = get_ip(request)
sd.consumer = get_consumer(request.data.get('username'), sd.ip)
sd.location = ip_to_region(sd.ip)
qrcode = request.data.get("qrcode") qrcode = request.data.get("qrcode")
if not qrcode: if not qrcode:
return http400("qrcode is missing") return http400("qrcode is missing")
@ -704,35 +698,48 @@ class QrVerifyView(BaseView):
if not code: if not code:
raise Exception("Unknown URL pattern: %s" % qrcode) raise Exception("Unknown URL pattern: %s" % qrcode)
sd.code = code sd.code = code
sd.ip = get_ip(request)
sd.consumer = get_consumer(request.data.get('username'), sd.ip)
sd.location = ip_to_region(sd.ip)
sc = SerialCode.objects.filter(code=code).first() sc = SerialCode.objects.filter(code=code).first()
if sc and sc.product: if not sc or not sc.product:
product = sc.product
if not sc.batch.is_active or not sc.is_active:
raise Exception("Inactive code")
sd.product = product
tenant = product.tenant
sd.tenant = tenant
sd.batch = sc.batch
if sc.batch.feature_comparison_threshold > 0.01:
self.do_v5_qr_verify(tf.name, messages)
else:
messages.append("skip v5 qr verify")
sd.succeeded = True
article_id = None
if product.article:
article_id = product.article.pk
count(product.tenant,
"qr-verify-ok", {
'image': image_name,
'product': product.pk,
})
resp = {
'id': product.pk,
'link': article_id,
'serial_code': code,
}
else:
raise Exception('No matching product found with code: %s' % code) raise Exception('No matching product found with code: %s' % code)
product = sc.product
if not sc.batch.is_active or not sc.is_active:
raise Exception("Inactive code")
sd.product = product
tenant = product.tenant
sd.tenant = tenant
sd.batch = sc.batch
imgs = get_images(request)
if not imgs:
return http400("image is missing")
img_data, filename = imgs[0]
image_name = 'scandata_v2/' + str(uuid.uuid4()) + '-' + filename
sd.image = image_name
if settings.ENV != "DEBUG" or os.environ.get("EMBLEM_ENABLE_OSS"):
t = threading.Thread(target=oss_put, args=(image_name, img_data))
t.run()
if sc.batch.feature_comparison_threshold > 0.01:
self.do_v5_qr_verify(imgs, messages)
else:
messages.append("skip v5 qr verify")
sd.succeeded = True
article_id = None
if product.article:
article_id = product.article.pk
count(product.tenant,
"qr-verify-ok", {
'image': image_name,
'product': product.pk,
})
resp = {
'id': product.pk,
'link': article_id,
'serial_code': code,
}
except Exception as e: except Exception as e:
messages.append(str(e)) messages.append(str(e))
sd.save() sd.save()