cargando primer proyecto a gitea
This commit is contained in:
commit
533105e7c3
16 files changed
+1327
No files matched your search
+188
@@ -0,0 +1,188 @@
|
||||
import os
|
||||
|
||||
########################################################
|
||||
def calcular_puntuacion(nombre_archivo, ruc, tipo, serie_numero):
|
||||
"""
|
||||
Calcula una puntuación de 0 a 4 según cuántos elementos coinciden en el nombre del archivo.
|
||||
serie_numero se descompone en serie y número.
|
||||
"""
|
||||
puntos = 0
|
||||
nombre_archivo = nombre_archivo.upper()
|
||||
|
||||
# 1. RUC
|
||||
if ruc and ruc != "N/A" and ruc in nombre_archivo:
|
||||
puntos += 1
|
||||
|
||||
# 2. Tipo
|
||||
if tipo and tipo != "99" and tipo in nombre_archivo:
|
||||
puntos += 1
|
||||
|
||||
# 3. Serie y 4. Número
|
||||
if "-" in serie_numero:
|
||||
partes = serie_numero.split("-")
|
||||
serie = partes[0].upper()
|
||||
numero = partes[1]
|
||||
|
||||
if serie in nombre_archivo:
|
||||
puntos += 1
|
||||
if numero in nombre_archivo:
|
||||
puntos += 1
|
||||
|
||||
return puntos
|
||||
|
||||
########################################################
|
||||
def procesar_renombrado_agrupado(email_obj, ruta_base):
|
||||
"""
|
||||
Lógica de agrupación y renombrado de archivos según puntuación y tipo.
|
||||
"""
|
||||
metadatos = email_obj.get('metadatos_adjuntos', [])
|
||||
tipos_permitidos = ["01", "03", "07", "08", "02", "09", "14"]
|
||||
|
||||
# 1. Identificar "Pivotes" (pivotes para agrupar)
|
||||
# Preferencia: XML Maestros. Fallback: PDFs con metadata válida si no hay XMLs.
|
||||
xml_maestros = [m for m in metadatos if m['extension'] == ".xml" and m['tipo'] in tipos_permitidos]
|
||||
|
||||
if xml_maestros:
|
||||
pivotes = xml_maestros
|
||||
else:
|
||||
# En correos solo PDF, tratamos a cada PDF con nombre propuesto como un pivote
|
||||
pivotes = [m for m in metadatos if m['extension'] == ".pdf" and m['archivo_propuesto'] is not None]
|
||||
|
||||
if not pivotes:
|
||||
return {} # Nada que agrupar
|
||||
|
||||
nuevos_archivos = []
|
||||
mapeo_renombrado = {} # original -> nuevo
|
||||
agrupacion = {} # archivo_propuesto -> [lista de nombres nuevos]
|
||||
|
||||
# Inicializar el diccionario de agrupación con los nombres de los pivotes
|
||||
for p in pivotes:
|
||||
agrupacion[p['archivo_propuesto']] = []
|
||||
|
||||
# 2. Agrupar cada archivo con su mejor pivote
|
||||
for m in metadatos:
|
||||
nombre_original = m['archivo']
|
||||
extension = m['extension'].lower()
|
||||
|
||||
# Si es un pivote, su nombre es directo y ya está inicializado
|
||||
if m in pivotes:
|
||||
nombre_nuevo = f"{m['archivo_propuesto']}{extension}"
|
||||
mapeo_renombrado[nombre_original] = nombre_nuevo
|
||||
agrupacion[m['archivo_propuesto']].append(nombre_nuevo)
|
||||
else:
|
||||
# Buscar el mejor match entre los pivotes que aún acepten este tipo de archivo
|
||||
mejor_pivote = None
|
||||
max_puntos = -1
|
||||
|
||||
is_cdr = m['tipo'] == "CDR" or "R-" in nombre_original or "R_" in nombre_original or "CDR" in nombre_original.upper()
|
||||
is_pdf = extension == ".pdf"
|
||||
is_xml = extension == ".xml" and not is_cdr
|
||||
|
||||
for p in pivotes:
|
||||
p_prop = p['archivo_propuesto']
|
||||
grupo_actual = agrupacion[p_prop]
|
||||
|
||||
ya_tiene_pdf = any(f.lower().endswith('.pdf') for f in grupo_actual)
|
||||
ya_tiene_cdr = any(f.startswith('CDR-') for f in grupo_actual)
|
||||
|
||||
if (is_pdf and ya_tiene_pdf) or (is_cdr and ya_tiene_cdr) or is_xml:
|
||||
continue
|
||||
|
||||
puntos = calcular_puntuacion(
|
||||
nombre_original,
|
||||
p['ruc'],
|
||||
p['tipo'],
|
||||
p['serie_numero']
|
||||
)
|
||||
|
||||
if puntos > max_puntos:
|
||||
max_puntos = puntos
|
||||
mejor_pivote = p
|
||||
|
||||
if mejor_pivote and max_puntos > 0:
|
||||
prefix = "CDR-" if is_cdr else ""
|
||||
nombre_nuevo = f"{prefix}{mejor_pivote['archivo_propuesto']}{extension}"
|
||||
|
||||
mapeo_renombrado[nombre_original] = nombre_nuevo
|
||||
agrupacion[mejor_pivote['archivo_propuesto']].append(nombre_nuevo)
|
||||
else:
|
||||
# Si no hay match, va a OTROS
|
||||
mapeo_renombrado[nombre_original] = nombre_original
|
||||
if "OTROS" not in agrupacion: agrupacion["OTROS"] = []
|
||||
agrupacion["OTROS"].append(nombre_original)
|
||||
|
||||
# 3. Ejecutar el renombrado físico y actualizar metadatos
|
||||
for m in metadatos:
|
||||
nombre_original = m['archivo']
|
||||
nombre_nuevo = mapeo_renombrado.get(nombre_original)
|
||||
|
||||
if nombre_nuevo and nombre_nuevo != nombre_original:
|
||||
ruta_old = os.path.join(ruta_base, nombre_original)
|
||||
ruta_new = os.path.join(ruta_base, nombre_nuevo)
|
||||
|
||||
try:
|
||||
if os.path.exists(ruta_old):
|
||||
# Si el destino ya existe, borramos para sobreescribir (o podrías manejarlo de otra forma)
|
||||
if os.path.exists(ruta_new) and ruta_old != ruta_new:
|
||||
os.remove(ruta_new)
|
||||
os.rename(ruta_old, ruta_new)
|
||||
m['archivo'] = nombre_nuevo
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Error renombrando {nombre_original}: {e}")
|
||||
|
||||
# 4. Actualizar la lista de archivos en el email_obj
|
||||
email_obj['archivos'] = [m['archivo'] for m in metadatos]
|
||||
return agrupacion
|
||||
|
||||
########################################################
|
||||
def mover_archivos_a_resultado(email_obj, ruta_origen, ruta_destino):
|
||||
"""
|
||||
Mueve los archivos procesados de la carpeta temporal a la carpeta final de resultados.
|
||||
Solo mueve archivos que pertenecen a un grupo válido (basado en archivo_propuesto).
|
||||
Excluye los archivos en la categoría 'OTROS'.
|
||||
"""
|
||||
agrupacion = email_obj.get('agrupacion_archivos', {})
|
||||
if not agrupacion:
|
||||
return
|
||||
|
||||
if not os.path.exists(ruta_destino):
|
||||
os.makedirs(ruta_destino)
|
||||
print(f" 📁 Carpeta de destino creada: {ruta_destino}")
|
||||
|
||||
for key, archivos in agrupacion.items():
|
||||
if key == "OTROS":
|
||||
continue # No mover archivos no identificados
|
||||
|
||||
for archivo in archivos:
|
||||
ruta_old = os.path.join(ruta_origen, archivo)
|
||||
ruta_new = os.path.join(ruta_destino, archivo)
|
||||
|
||||
try:
|
||||
if os.path.exists(ruta_old):
|
||||
if os.path.exists(ruta_new) and ruta_old != ruta_new:
|
||||
os.remove(ruta_new)
|
||||
os.rename(ruta_old, ruta_new)
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Error trasladando {archivo} a resultado: {e}")
|
||||
|
||||
########################################################
|
||||
def limpiar_carpeta_descarga(ruta):
|
||||
"""
|
||||
Elimina todos los archivos dentro de la carpeta de descarga para dejarla limpia.
|
||||
"""
|
||||
if not os.path.exists(ruta):
|
||||
return
|
||||
|
||||
print(f" 🧹 Limpiando carpeta de descarga: {ruta}")
|
||||
for archivo in os.listdir(ruta):
|
||||
ruta_archivo = os.path.join(ruta, archivo)
|
||||
try:
|
||||
if os.path.isfile(ruta_archivo):
|
||||
os.remove(ruta_archivo)
|
||||
elif os.path.isdir(ruta_archivo):
|
||||
import shutil
|
||||
shutil.rmtree(ruta_archivo)
|
||||
except Exception as e:
|
||||
print(f" ⚠️ No se pudo eliminar {archivo}: {e}")
|
||||
|
||||
########################################################
|
||||
Reference in new issue
Block a user