idc.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. from flask import Blueprint, views, render_template, request
  2. from utils.util import *
  3. import re
  4. from utils.conf import MAX_CONTENT_LENGTH
  5. idc = Blueprint("idc", __name__, url_prefix="/idc")
  6. __name_ptn = r"姓 *名 *(?P<name>.+) *"
  7. __gender_nation_ptn = r"性 *别 *(?P<gender>男|女) *民 *族 *(?P<nation>.+) *"
  8. __birth_ymd_ptn = r"出 *生 *(?P<year>\d{4}) *年 *(?P<month>\d{2}) *月 *(?P<day>\d{2}) *日 *"
  9. __addr_start_ptn = r"住 *址 *(?P<addr>.+) *"
  10. __idn_ptn = r"公 *民 *身 *份 *号 *码 *(?P<idn>\d{18}) *"
  11. __agent_ptn = r"签 *发 *机 *关 *(?P<agent>.*) *"
  12. __valid_date_ptn = r"有 *效 *期 *限 *(?P<from_year>\d{4})\.(?P<from_month>\d{2})\.(?P<from_day>\d{2})" \
  13. r"[^\d]+(?P<to_year>\d{4})\.(?P<to_month>\d{2})\.(?P<to_day>\d{2}) *"
  14. def get_face_info(data: "list[str]"):
  15. res = {"name": "", "gender": "", "nation": "", "addr": "", "idn": "", "birth": {"year": "", "month": "", "day": ""}}
  16. for item in data:
  17. if name := re.match(__name_ptn, item):
  18. res["name"] = name.group("name")
  19. elif gender_nation := re.match(__gender_nation_ptn, item):
  20. res["gender"] = gender_nation.group("gender")
  21. res["nation"] = gender_nation.group("nation")
  22. elif birth_ymd := re.match(__birth_ymd_ptn, item):
  23. res["birth"]["year"] = birth_ymd.group("year")
  24. res["birth"]["month"] = birth_ymd.group("month")
  25. res["birth"]["day"] = birth_ymd.group("day")
  26. elif addr := re.match(__addr_start_ptn, item):
  27. res["addr"] = addr.group("addr")
  28. elif idn := re.match(__idn_ptn, item):
  29. res["idn"] = idn.group("idn")
  30. else:
  31. res["addr"] += item
  32. return res
  33. def get_icon_info(data: "list[str]"):
  34. res = {"agent": "", "from": {"year": "", "month": "", "day": ""}, "to": {"year": "", "month": "", "day": ""}}
  35. for item in data:
  36. if agent := re.match(__agent_ptn, item):
  37. res["agent"] = agent.group("agent")
  38. elif valid_date := re.match(__valid_date_ptn, item):
  39. res["from"]["year"] = valid_date.group("from_year")
  40. res["from"]["month"] = valid_date.group("from_month")
  41. res["from"]["day"] = valid_date.group("from_day")
  42. res["to"]["year"] = valid_date.group("to_year")
  43. res["to"]["month"] = valid_date.group("to_month")
  44. res["to"]["day"] = valid_date.group("to_day")
  45. return res
  46. class IdcView(views.MethodView):
  47. @staticmethod
  48. def get():
  49. return render_template("idc_index.html")
  50. @staticmethod
  51. def post():
  52. pic = request.files.get("picture")
  53. if pic is None:
  54. return Response("empty body")
  55. ext = get_ext_name(pic.filename)
  56. if not is_image_ext(ext):
  57. return Response("文件类型错误")
  58. content = pic.read()
  59. if len(content) > MAX_CONTENT_LENGTH:
  60. return Response("文件过大,请重新选择")
  61. raw_path = f"static/images/{current_time()}_{rand_str()}.{ext}"
  62. with open(raw_path, "wb") as fp:
  63. fp.write(content)
  64. fp.close()
  65. which = request.form.get("which")
  66. if which is not None:
  67. which = which.lower()
  68. if which not in ["face", "icon"]:
  69. return Response(f"not recognized arg <which>: '{which}'")
  70. ocr_res, _ = recognize(content)
  71. words = [it[1][0] for it in ocr_res]
  72. if which == "face":
  73. info = get_face_info(words)
  74. if json_all(info):
  75. return Response(data=info)
  76. return Response("识别失败,请重新选择", info)
  77. info = get_icon_info(words)
  78. if json_all(info):
  79. return Response(data=info)
  80. return Response("识别失败,请重新选择", info)
  81. class IdcHtmlView(views.MethodView):
  82. @staticmethod
  83. def post():
  84. pic = request.files.get("picture")
  85. if pic is None:
  86. return Response("empty body")
  87. ext = get_ext_name(pic.filename)
  88. if not is_image_ext(ext):
  89. return Response("文件类型错误")
  90. content = pic.read()
  91. if len(content) > MAX_CONTENT_LENGTH:
  92. return Response("文件过大,请重新选择")
  93. cut, rnd = current_time(), rand_str()
  94. raw_path = f"static/images/{cut}_{rnd}.{ext}"
  95. rec_path = f"static/images/{cut}_{rnd}_rec.{ext}"
  96. with open(raw_path, "wb") as fp:
  97. fp.write(content)
  98. fp.close()
  99. which = request.form.get("which")
  100. if which is not None:
  101. which = which.lower()
  102. if which not in ["face", "icon"]:
  103. return Response(f"not recognized arg <which>: '{which}'")
  104. ocr_res, img_shape = recognize(content)
  105. words = [it[1][0] for it in ocr_res]
  106. draw_img(img_shape, [{"pos": it[0], "word": it[1][0], "rate": it[1][1]} for it in ocr_res], rec_path)
  107. if which == "face":
  108. info = get_face_info(words)
  109. else:
  110. info = get_icon_info(words)
  111. info["SUCCESS"] = str(json_all(info)).upper()
  112. return render_template("k-v_result.html", raw=raw_path, rec=rec_path, data=info)
  113. idc.add_url_rule("/", view_func=IdcView.as_view("idc"))
  114. idc.add_url_rule("/html/", view_func=IdcHtmlView.as_view("idc-html"))