# 导入requests库,用于发送HTTP请求
import requests
# 导入FastAPI库,用于构建高性能的Web应用程序
from fastapi import FastAPI
# 导入PaddleOCR及其draw_ocr方法,PaddleOCR是一个使用PaddlePaddle深度学习框架的OCR工具
from paddleocr import PaddleOCR, draw_ocr
# 导入BytesIO,用于在内存中处理二进制流
from io import BytesIO
# 导入PIL库中的Image模块,用于处理图像
from PIL import Image
import os
import re

from enum import Enum


class contractType(Enum):
    Display = 0
    Contract = 1
    Idcard = 3
    IdcardSide = 4
    Signature = 5
    Lisense = 6


# 0 宣传照 1合同 3身份证正面 4 身份证反面 5签名

# 初始化PaddleOCR实例,配置使用方向分类器、不使用GPU、识别中文
ocr = PaddleOCR(use_angle_cls=True, use_gpu=False, lang="ch")
# 创建一个FastAPI应用实例
app = FastAPI()


def carvin():
    pass


def carnumber():
    pass


def display():
    pass


def contract():
    pass


def idcard(a):
    # 定义正则表达式模式来匹配性别和民族
    gender_ethnicity_pattern = re.compile(r'性别(\w+)民族(\w+)')

    # 定义正则表达式模式来匹配身份证号
    id_card_pattern = re.compile(r'(\d{17}[\dXx])')

    # 使用正则表达式搜索字符串来提取性别和民族
    gender_ethnicity_match = gender_ethnicity_pattern.search(a)

    # 使用正则表达式搜索字符串来提取身份证号
    id_card_match = id_card_pattern.search(a)
    gender = ''
    ethnicity = ''
    id_card = ''
    # 提取匹配结果
    if gender_ethnicity_match:
        gender = gender_ethnicity_match.group(1)  # 性别
        ethnicity = gender_ethnicity_match.group(2)  # 民族
        print("性别:", gender)
        print("民族:", ethnicity)

        # 提取匹配结果
    if id_card_match:
        id_card = id_card_match.group(1)  # 身份证号
        print("身份证号:", id_card)
    return [gender, ethnicity, id_card]


def licenseside(a):
    # 定义正则表达式
    pattern_company_name = re.compile(r'名\s+称\s+(\S.+?)\s+类')
    pattern_credit_code = re.compile(r'统一社会信用代码\s+(\S+)\(')
    pattern_business_address = re.compile(r'经营场所\s+(\S.+?)\s+组成')
    pattern_operator_name = re.compile(r'经\s+营\s+者\s+(\S+)')

    # 使用正则表达式查找匹配项
    company_name_match = pattern_company_name.search(a)
    credit_code_match = pattern_credit_code.search(a)
    business_address_match = pattern_business_address.search(a)
    operator_name_match = pattern_operator_name.search(a)
    company_name = ''
    credit_code = ''
    business_address = ''
    operator_name = ''
    # 提取匹配结果
    if company_name_match:
        company_name = company_name_match.group(1)

    if credit_code_match:
        credit_code = credit_code_match.group(1)

    if business_address_match:
        business_address = business_address_match.group(1)

    if operator_name_match:
        operator_name = operator_name_match.group(1)

    return [company_name, credit_code, business_address, operator_name]


def signature():
    pass


# 定义一个异步的GET请求处理函数,路径为"/",接收一个名为url的查询参数
@app.get("/")
async def root(url: str, type: int):
    try:

        # 使用requests库发送GET请求,获取指定URL的图片,stream=True表示以流的形式下载大文件
        response = requests.get(url, stream=True)
        # 如果HTTP请求返回的状态码不是200,则引发HTTPError异常
        response.raise_for_status()
        # 检查响应头中的content-type是否包含'image',以确认返回的内容是图片
        if 'image' not in response.headers.get('content-type', ''):
            # 如果不是图片,返回错误信息,HTTP状态码为400(Bad Request)
            return {"error": "The provided URL does not point to an image."}, 400
            # 使用BytesIO将响应内容转换为二进制流
        image_bytes = BytesIO(response.content)
        # 使用PIL库打开二进制流中的图像
        image = Image.open(image_bytes)

        # 将图像保存到临时文件中(这里是为了适应PaddleOCR可能需要文件路径的API)
        # 注意:这里的代码实际上有一个逻辑错误,因为image.save()应该放在with语句块内以确保文件正确关闭
        temp_image_path = "temp_image.jpg"
        with open(temp_image_path, "wb") as image_file:
            image.save(image_file, format='JPEG')
            # 调用PaddleOCR的ocr方法进行OCR处理,cls=True表示使用分类器
        result = ocr.ocr(temp_image_path, cls=True)
        if os.path.exists(temp_image_path):
            os.remove(temp_image_path)
        results = ""
        # 遍历最外层的列表
        for item in result:
            # 遍历内层的列表
            for sub_item in item:
                # 提取文本和可能性
                text = sub_item[1][0]  # 文本位于第二个子列表的第一个位置
                probability = sub_item[1][1]  # 可能性位于第二个子列表的第二个位置
                # 将提取的文本和可能性作为一个元组添加到结果列表中
                # results.append(text)
                results = results + ' ' + text
        # 返回OCR处理结果,封装在message字段中(注意:这里没有删除临时文件,可能会导致磁盘空间被占用)

        if type == contractType.Idcard.value:
            return {"error": 0, "message": idcard(results), "type": type}
        if type == contractType.Lisense.value:
            return {"error": 0, "message": licenseside(results), "type": type}
        return {"error": 0, "message": results, "type": type}

    except requests.exceptions.RequestException as e:
        # 如果在发送HTTP请求过程中发生异常,捕获异常并返回错误信息,HTTP状态码为500(Internal Server Error)
        return {"error": f"An error occurred while downloading the image: {str(e)}"}, 500
    except Exception as e:
        # 如果在处理过程中发生其他类型的异常,同样捕获异常并返回错误信息,HTTP状态码为500
        return {"error": f"An error occurred during OCR processing: {str(e)}"}, 500

02-17 07:17