11import requests
22import os
33import base64
4+ import logging
5+ from http .client import IncompleteRead
46
57
68def build_qr_code_image_string (uuid , raw : bool = False ):
79 backend_domain = os .environ ["BACKEND_DOMAIN" ]
810 clear_url = f"{ backend_domain } /gpx/{ uuid } .gpx"
911 b64_url = base64 .b64encode (clear_url .encode ("ascii" )).decode ("ascii" )
1012 final_url = "https://swisstopo.app/u/" + b64_url
11- r = requests .post (
12- "https://backend.qr.cevi.tools/png" ,
13- json = {"text" : final_url },
14- )
13+ try :
14+ r = requests .post (
15+ "https://backend.qr.cevi.tools/png" ,
16+ json = {"text" : final_url },
17+ )
18+ except requests .exceptions .RequestException :
19+ logging .exception ("Failed to request QR backend for UUID=%s URL=%s" , uuid , "https://backend.qr.cevi.tools/png" )
20+ return ""
21+ except IncompleteRead :
22+ logging .exception ("IncompleteRead while requesting QR backend for UUID=%s" , uuid )
23+ return ""
24+
25+ def _is_image (content : bytes , content_type : str | None ) -> bool :
26+ if not content :
27+ return False
28+ if content_type and content_type .startswith ("image/" ):
29+ return True
30+ # Check common magic bytes for PNG, JPEG, GIF
31+ if content .startswith (b"\x89 PNG\r \n \x1a \n " ):
32+ return True
33+ if content .startswith (b"\xff \xd8 \xff " ):
34+ return True
35+ if content [:6 ] in (b"GIF87a" , b"GIF89a" ):
36+ return True
37+ return False
38+
1539 if r .status_code == 200 :
1640 qr_code_bytes = r .content
1741
42+ content_type = r .headers .get ("Content-Type" ) if hasattr (r , "headers" ) else None
43+
44+ if not _is_image (qr_code_bytes , content_type ):
45+ logging .debug (
46+ "QR backend returned non-image content for UUID=%s content_type=%s content_len=%s" ,
47+ uuid ,
48+ content_type ,
49+ len (qr_code_bytes ) if qr_code_bytes is not None else 0 ,
50+ )
51+ return ""
52+
1853 if raw :
1954 # if raw, only return the qr code image bytes
2055 return qr_code_bytes
@@ -30,4 +65,5 @@ def build_qr_code_image_string(uuid, raw: bool = False):
3065 return data_url
3166
3267 else :
33- return "" # TODO: does this work?
68+ logging .debug ("QR backend returned status %s for UUID=%s" , r .status_code , uuid )
69+ return "" # no QR code
0 commit comments