| import tempfile |
| import time |
| from gradio_client import Client, handle_file |
| import re |
|
|
| async def imageToTemp(image): |
|
|
| try: |
| with tempfile.NamedTemporaryFile(delete=False, suffix=f"_{image.filename}") as tmp_file: |
| contents = await image.read() |
| tmp_file.write(contents) |
| temp_file_path = tmp_file.name |
| |
| print(f"Archivo temporal guardado en: {temp_file_path}") |
| return temp_file_path |
|
|
| except Exception as e: |
| print(f"Error al procesar el archivo: {e}") |
| return {"error": "Error al procesar la imagen"} |
| |
|
|
| def listaTextosExtraidos(dict_recibido): |
|
|
| result = dict_recibido['data'] |
| print("Datos extraídos (acceso directo):") |
| |
| textos_extraidos = [] |
| |
| for item in result: |
| texto = item[1][0] |
| print(texto) |
| textos_extraidos.append(texto) |
| return textos_extraidos |
|
|
| |
|
|
| def buscaIndexPalabra(arreglo, palabra): |
| palabra_limpia = palabra.lower().replace(" ", "") |
| for i, texto_limpio in enumerate(arreglo): |
| if palabra_limpia in texto_limpio: |
| return i |
| return None |
|
|
| def buscaIndexMultiplesPalabras_Corregida(arreglo, conceptos_requeridos): |
| """ |
| Busca el índice de la primera línea que contiene todas las palabras requeridas (o sus alternativas) |
| y devuelve la línea con las alternativas corregidas a su forma preferida. |
| |
| Args: |
| arreglo (list): Lista de strings de texto extraído (limpios). |
| conceptos_requeridos (list): Lista de diccionarios, donde cada diccionario define un concepto: |
| Ej: {'preferida': 'nacimiento', 'alternativas': ['nacimento', 'nacimuento']} |
| |
| Returns: |
| tuple: (índice, línea_corregida) si se encuentra, o (None, None) si no se encuentra. |
| """ |
| print(f"\n--- Iniciando búsqueda y corrección ---") |
| |
| |
| conceptos_preparados = [] |
| for concepto in conceptos_requeridos: |
| preferida = concepto['preferida'].lower().replace(" ", "") |
| alternativas = [alt.lower().replace(" ", "") for alt in concepto.get('alternativas', [])] |
| |
| |
| todas_las_formas = [preferida] + alternativas |
| |
| conceptos_preparados.append({ |
| 'preferida': preferida, |
| 'todas_las_formas': todas_las_formas, |
| 'alternativas': alternativas |
| }) |
|
|
| for i, texto_linea in enumerate(arreglo): |
| texto_linea_lower = texto_linea.lower() |
| |
| |
| es_coincidencia_completa = True |
| palabras_encontradas_en_linea = {} |
|
|
| |
| for concepto in conceptos_preparados: |
| encontrado_en_esta_linea = False |
| |
| |
| for forma in concepto['todas_las_formas']: |
| if forma in texto_linea_lower: |
| encontrado_en_esta_linea = True |
| |
| |
| palabras_encontradas_en_linea[forma] = concepto['preferida'] |
| |
| |
| break |
| |
| if not encontrado_en_esta_linea: |
| es_coincidencia_completa = False |
| print(f"Fallo en línea {i}: No se encontró el concepto '{concepto['preferida']}' ni sus alternativas.") |
| break |
|
|
| |
| if es_coincidencia_completa: |
| print(f"ÉXITO: Coincidencia completa en el índice {i}.") |
| print(f"Texto linea es: {texto_linea}") |
|
|
| linea_corregida = texto_linea |
| |
| for forma_encontrada, forma_preferida in palabras_encontradas_en_linea.items(): |
| |
| |
| |
|
|
| |
| |
| patron_reemplazo = re.compile(re.escape(forma_encontrada), re.IGNORECASE) |
| |
| |
| linea_corregida = patron_reemplazo.sub(forma_preferida, linea_corregida, count=1) |
|
|
| print(f"Línea corregida: '{linea_corregida}'") |
| |
| |
| arreglo[i] = linea_corregida |
| return i, arreglo |
| |
| print(f"\n--- Búsqueda finalizada ---") |
| print("Ninguna línea contiene todas las palabras requeridas.") |
| return None, None |
|
|
| |
| def buscarPatronCedula(lista_textos): |
| for i, texto in enumerate(lista_textos): |
| if texto and texto[0].isdigit() and '-' in texto: |
| return i |
| return 'error' |
|
|
| async def procesaImagen(image): |
|
|
| try: |
| temp_image = await imageToTemp(image) |
| client = Client("BuzzwordMx/ai_ocr") |
| dict_recibido = client.predict( |
| img=handle_file(temp_image), |
| lang="en", |
| api_name="/predict" |
| ) |
| |
| |
| textos_extraidos = listaTextosExtraidos(dict_recibido) |
| return textos_extraidos |
| except Exception as e: |
| print(f"Error al procesar el archivo: {e}") |
| |
|
|
| def obtener_fecha(texto): |
| |
| |
| |
| |
| |
| patron = r"FECHADENACIMIENTO[^\d]*(\d{1,2}-[A-Za-z0-9]{3}-\d{4})" |
| |
| match = re.search(patron, texto, re.IGNORECASE) |
| |
| fecha_encontrada = None |
| if match: |
| fecha_encontrada = match.group(1) |
| |
| if fecha_encontrada: |
| partes_fecha = fecha_encontrada.split('-') |
| if len(partes_fecha) == 3: |
| dia = partes_fecha[0] |
| mes = partes_fecha[1].lower() |
| año = partes_fecha[2] |
| return f"{dia}-{mes}-{año}" |
| else: |
| |
| return fecha_encontrada |
| |
| return None |
|
|
| def obtener_sexo(texto): |
| |
| |
| |
| |
| patron = r"(Sexo|Seno):?\s*([A-Za-z])" |
| |
| |
| |
| match = re.search(patron, texto, re.IGNORECASE) |
| |
| if match: |
| |
| |
| return match.group(2) |
| else: |
| return None |
| |
| def define_documento(textos_extraidos): |
|
|
| |
| textos_extraidos_simplificados = [texto.lower().replace(" ", "") for texto in textos_extraidos] |
|
|
| |
| conceptos_busqueda_dni = [ |
| {'preferida': 'nombre', 'alternativas': []}, |
| {'preferida': 'usual', 'alternativas': []} |
| ] |
| |
| indice, textos_extraidos_corregidos = buscaIndexMultiplesPalabras_Corregida(textos_extraidos_simplificados, conceptos_busqueda_dni) |
| if indice is not None: |
| print("Si es dni...") |
| return 'dni' |
| else: |
| |
| |
| conceptos_busqueda_pasaporte = [ |
| {'preferida': 'pasaporte', 'alternativas': ['passport']}, |
| |
| ] |
| indice, textos_extraidos_corregidos = buscaIndexMultiplesPalabras_Corregida(textos_extraidos_simplificados, conceptos_busqueda_pasaporte) |
| |
| if indice is not None: |
| print("Si es pasaporte...") |
| return 'pasaporte' |
| else: |
| print("No es pasaporte ni dni.") |
| return None |