UNIPipe.py 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. from loguru import logger
  2. from magic_pdf.dict2md.mkcontent import mk_universal_format
  3. from magic_pdf.dict2md.ocr_mkcontent import make_standard_format_with_para
  4. from magic_pdf.filter.pdf_classify_by_type import classify
  5. from magic_pdf.filter.pdf_meta_scan import pdf_meta_scan
  6. from magic_pdf.libs.drop_reason import DropReason
  7. from magic_pdf.libs.json_compressor import JsonCompressor
  8. from magic_pdf.spark.spark_api import parse_union_pdf, parse_ocr_pdf
  9. class UNIPipe:
  10. def __init__(self):
  11. pass
  12. def classify(self, pdf_bytes: bytes) -> str:
  13. """
  14. 根据pdf的元数据,判断是否是文本pdf,还是ocr pdf
  15. """
  16. pdf_meta = pdf_meta_scan(pdf_bytes)
  17. if pdf_meta.get("_need_drop", False): # 如果返回了需要丢弃的标志,则抛出异常
  18. raise Exception(f"pdf meta_scan need_drop,reason is {pdf_meta['_drop_reason']}")
  19. else:
  20. is_encrypted = pdf_meta["is_encrypted"]
  21. is_needs_password = pdf_meta["is_needs_password"]
  22. if is_encrypted or is_needs_password: # 加密的,需要密码的,没有页面的,都不处理
  23. raise Exception(f"pdf meta_scan need_drop,reason is {DropReason.ENCRYPTED}")
  24. else:
  25. is_text_pdf, results = classify(
  26. pdf_meta["total_page"],
  27. pdf_meta["page_width_pts"],
  28. pdf_meta["page_height_pts"],
  29. pdf_meta["image_info_per_page"],
  30. pdf_meta["text_len_per_page"],
  31. pdf_meta["imgs_per_page"],
  32. pdf_meta["text_layout_per_page"],
  33. )
  34. if is_text_pdf:
  35. allow_language = ["zh", "en"] # 允许的语言,目前只允许简中和英文的
  36. text_language = pdf_meta["text_language"]
  37. logger.info(f"pdf meta_scan text_language is {text_language}")
  38. if text_language not in allow_language: # 如果语言不在允许的语言中,则drop
  39. if text_language == "un": # unknow的话可能是中文乱码,可以尝试用ocr识别
  40. return "ocr"
  41. else:
  42. raise Exception(f"pdf meta_scan need_drop,reason is {DropReason.NOT_ALLOW_LANGUAGE}")
  43. else:
  44. return "txt"
  45. else:
  46. return "ocr"
  47. def parse(self, pdf_bytes: bytes, image_writer, jso_useful_key) -> dict:
  48. """
  49. 根据pdf类型,解析pdf
  50. """
  51. if jso_useful_key['_pdf_type'] == "txt":
  52. pdf_mid_data = parse_union_pdf(pdf_bytes, jso_useful_key['model_list'], image_writer)
  53. elif jso_useful_key['_pdf_type'] == "ocr":
  54. pdf_mid_data = parse_ocr_pdf(pdf_bytes, jso_useful_key['model_list'], image_writer)
  55. else:
  56. raise Exception(f"pdf type is not txt or ocr")
  57. return JsonCompressor.compress(pdf_mid_data)
  58. def mk_uni_format(self, pdf_mid_data: str, img_buket_path: str) -> list:
  59. """
  60. 根据pdf类型,生成统一格式content_list
  61. """
  62. pdf_mid_data = JsonCompressor.decompress_json(pdf_mid_data)
  63. parse_type = pdf_mid_data["_parse_type"]
  64. if parse_type == "txt":
  65. content_list = mk_universal_format(pdf_mid_data, img_buket_path)
  66. elif parse_type == "ocr":
  67. content_list = make_standard_format_with_para(pdf_mid_data, img_buket_path)
  68. return content_list
  69. if __name__ == '__main__':
  70. # 测试
  71. pipe = UNIPipe()
  72. pdf_bytes = open(r"D:\project\20231108code-clean\magic_pdf\tmp\unittest\download-pdfs\数学新星网\edu_00001544.pdf",
  73. "rb").read()
  74. pdf_type = pipe.classify(pdf_bytes)
  75. logger.info(f"pdf_type is {pdf_type}")