scan_garbage.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import re
  2. import os.path
  3. from PIL import Image, ImageDraw, ImageFont
  4. from conf import Config
  5. from core.garbage import GarbageBag
  6. from sql.db import DB
  7. from sql.garbage import find_garbage
  8. from tool.typing import *
  9. from .scan import QRCode
  10. qr_user_pattern = re.compile(r'HGSSystem-QR-GARBAGE:([a-z0-9]+)-END', re.I)
  11. qr_img_title_font = ImageFont.truetype(font=Config.font_d["noto-bold"], size=35, encoding="unic")
  12. qr_img_title_b_font = ImageFont.truetype(font=Config.font_d["noto-medium"], size=30, encoding="unic")
  13. qr_img_info_font = ImageFont.truetype(font=Config.font_d["noto"], size=30, encoding="unic")
  14. qr_Watermark = ImageFont.truetype(font=Config.font_d["noto-black"], size=55, encoding="unic")
  15. def scan_gid(code: QRCode) -> gid_t:
  16. data = code.get_data()
  17. res = re.match(qr_user_pattern, data)
  18. if res is None:
  19. return ""
  20. else:
  21. return res.group(1)
  22. def scan_garbage(code: QRCode, db: DB) -> Optional[GarbageBag]:
  23. gid = scan_gid(code)
  24. if len(gid) == 0:
  25. return None
  26. return find_garbage(gid, db)
  27. def __get_gid_qr_file_name(gid: gid_t, path: str):
  28. path = os.path.join(path, f"gar-{gid}.png")
  29. dir_ = os.path.split(path)[0]
  30. if len(dir_) > 0:
  31. os.makedirs(dir_, exist_ok=True) # 生成输出目录
  32. return path
  33. def make_gid_image(gid: gid_t, path: str):
  34. qr = QRCode(f"HGSSystem-QR-GARBAGE:{gid}-END")
  35. qr_img = qr.make_img().convert("RGB").resize((500, 500))
  36. if not qr_img:
  37. return False
  38. title = f"HGSSystem 垃圾袋ID"
  39. loc = f"垃圾站: {Config.base_location}"
  40. title_width, title_height = qr_img_title_font.getsize(title)
  41. loc_width, loc_height = qr_img_title_b_font.getsize(loc)
  42. if len(str(gid)) > Config.show_gid_len:
  43. gid = gid[-Config.show_gid_len:]
  44. gid_width, gid_height = qr_img_info_font.getsize(gid)
  45. if loc_width > 510:
  46. loc_width = 510
  47. image = Image.new('RGB', (510, 500 + title_height + loc_height + 110), (255, 255, 255))
  48. logo_image = Image.open(Config.picture_d['logo']).resize((64, 64))
  49. draw = ImageDraw.Draw(image)
  50. draw.text((((510 - title_width) / 2), 5), title, (0, 0, 0), font=qr_img_title_font)
  51. draw.text((((510 - loc_width) / 2), title_height + 5), loc, (0, 0, 0), font=qr_img_title_b_font)
  52. qr_img.paste(logo_image, (int((500 - 64) / 2), int((500 - 64) / 2)))
  53. image.paste(qr_img, (5, title_height + loc_height + 10))
  54. draw.text((((510 - gid_width) / 2), 500 + title_height + loc_height + 10), gid, (0, 0, 0), font=qr_img_info_font)
  55. image.save(path)
  56. return True
  57. def write_gid_qr(gid: gid_t, path: str, db: DB) -> Tuple[str, Optional[GarbageBag]]:
  58. garbage = find_garbage(gid, db)
  59. if garbage is None:
  60. return "", None
  61. path = __get_gid_qr_file_name(gid, path)
  62. if make_gid_image(gid, path):
  63. return path, garbage
  64. return "", None
  65. def write_all_gid_qr(path: str, db: DB, where: str = "") -> List[Tuple[str]]:
  66. cur = db.search(columns=["GarbageID"], table="garbage", where=where)
  67. if cur is None:
  68. return []
  69. re_list = []
  70. for _ in range(cur.rowcount):
  71. res = cur.fetchone()
  72. assert len(res) == 1
  73. path_ = __get_gid_qr_file_name(res[0], path)
  74. if make_gid_image(str(res[0]), path_):
  75. re_list.append((path_,))
  76. return re_list