Spaces:
Paused
Paused
Upload app.py
Browse files
app.py
CHANGED
|
@@ -52,10 +52,11 @@ def _limpiar_entidades(s: str) -> str:
|
|
| 52 |
# Groq traduce DESDE EL HEBREO (fuente segura, siempre presente) a un español
|
| 53 |
# fluido y con sentido tradicional, devolviendo UNA LÍNEA POR VERSÍCULO. Así el
|
| 54 |
# mismo texto con sentido se muestra alineado y se usa EXACTAMENTE en el audio.
|
| 55 |
-
def
|
| 56 |
"""
|
| 57 |
-
|
| 58 |
-
|
|
|
|
| 59 |
"""
|
| 60 |
fallback = {n: (es or he) for (n, he, es) in pares}
|
| 61 |
if not pares:
|
|
@@ -80,7 +81,7 @@ def traducir_capitulo_con_groq(pares):
|
|
| 80 |
"No incluyas el texto hebreo, ni títulos, ni comentarios, ni notas. "
|
| 81 |
"Conserva el mismo número de versículos que recibas."
|
| 82 |
)
|
| 83 |
-
max_tok = min(
|
| 84 |
cuerpo = {
|
| 85 |
"model": MODELO_ESTUDIA,
|
| 86 |
"temperature": 0.3,
|
|
@@ -134,6 +135,49 @@ def traducir_capitulo_con_groq(pares):
|
|
| 134 |
return final, estado
|
| 135 |
|
| 136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
# --- PROCESAMIENTO ACÚSTICO FFMPEG ---
|
| 138 |
def procesar_audio_narrador(ruta):
|
| 139 |
if not shutil.which("ffmpeg"):
|
|
|
|
| 52 |
# Groq traduce DESDE EL HEBREO (fuente segura, siempre presente) a un español
|
| 53 |
# fluido y con sentido tradicional, devolviendo UNA LÍNEA POR VERSÍCULO. Así el
|
| 54 |
# mismo texto con sentido se muestra alineado y se usa EXACTAMENTE en el audio.
|
| 55 |
+
def _traducir_lote_groq(pares):
|
| 56 |
"""
|
| 57 |
+
Traduce UN LOTE pequeño de versículos (para no chocar con el límite de
|
| 58 |
+
tokens por minuto de Groq). pares: lista de (n, hebreo, es_literal).
|
| 59 |
+
Devuelve (dict {n: español_con_sentido}, estado).
|
| 60 |
"""
|
| 61 |
fallback = {n: (es or he) for (n, he, es) in pares}
|
| 62 |
if not pares:
|
|
|
|
| 81 |
"No incluyas el texto hebreo, ni títulos, ni comentarios, ni notas. "
|
| 82 |
"Conserva el mismo número de versículos que recibas."
|
| 83 |
)
|
| 84 |
+
max_tok = min(2000, max(400, len(pares) * 90))
|
| 85 |
cuerpo = {
|
| 86 |
"model": MODELO_ESTUDIA,
|
| 87 |
"temperature": 0.3,
|
|
|
|
| 135 |
return final, estado
|
| 136 |
|
| 137 |
|
| 138 |
+
# Tamaño de lote: capítulos largos (p.ej. Génesis 1, 31 versículos) superan el
|
| 139 |
+
# límite de tokens por minuto de Groq si se mandan de una vez. Se trocea en
|
| 140 |
+
# bloques pequeños y se hacen varias llamadas, uniendo los resultados.
|
| 141 |
+
TAMANO_LOTE_GROQ = 6
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
def traducir_capitulo_con_groq(pares):
|
| 145 |
+
"""
|
| 146 |
+
pares: lista de (n, hebreo, es_literal) de TODO el capítulo.
|
| 147 |
+
Trocea en lotes pequeños, traduce cada uno con Groq y une los resultados.
|
| 148 |
+
Devuelve (dict {n: español_con_sentido}, estado_general).
|
| 149 |
+
"""
|
| 150 |
+
if not pares:
|
| 151 |
+
return {}, "sin_pares"
|
| 152 |
+
|
| 153 |
+
resultado = {}
|
| 154 |
+
lotes_ok = 0
|
| 155 |
+
lotes_total = 0
|
| 156 |
+
motivos_fallo = []
|
| 157 |
+
|
| 158 |
+
for i in range(0, len(pares), TAMANO_LOTE_GROQ):
|
| 159 |
+
lote = pares[i:i + TAMANO_LOTE_GROQ]
|
| 160 |
+
lotes_total += 1
|
| 161 |
+
parcial, estado_lote = _traducir_lote_groq(lote)
|
| 162 |
+
resultado.update(parcial)
|
| 163 |
+
if estado_lote == "ok" or estado_lote.startswith("ok ("):
|
| 164 |
+
lotes_ok += 1
|
| 165 |
+
else:
|
| 166 |
+
motivos_fallo.append(f"versículos {lote[0][0]}-{lote[-1][0]}: {estado_lote}")
|
| 167 |
+
|
| 168 |
+
if lotes_ok == lotes_total:
|
| 169 |
+
estado_general = "ok"
|
| 170 |
+
elif lotes_ok == 0:
|
| 171 |
+
estado_general = "; ".join(motivos_fallo[:3])
|
| 172 |
+
else:
|
| 173 |
+
estado_general = (
|
| 174 |
+
f"parcial ({lotes_ok}/{lotes_total} lotes con Groq, el resto literal) — "
|
| 175 |
+
+ "; ".join(motivos_fallo[:3])
|
| 176 |
+
)
|
| 177 |
+
|
| 178 |
+
return resultado, estado_general
|
| 179 |
+
|
| 180 |
+
|
| 181 |
# --- PROCESAMIENTO ACÚSTICO FFMPEG ---
|
| 182 |
def procesar_audio_narrador(ruta):
|
| 183 |
if not shutil.which("ffmpeg"):
|