|
|
@@ -176,7 +176,7 @@ def _system_prompt(lang: str) -> str:
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def translate_text(text: str, lang: str, *, is_title: bool = False, context: str = "") -> str:
|
|
|
|
def translate_text(text: str, lang: str, *, is_title: bool = False) -> str:
|
|
|
|
text = text.strip()
|
|
|
|
text = text.strip()
|
|
|
|
if not text:
|
|
|
|
if not text:
|
|
|
|
return ""
|
|
|
|
return ""
|
|
|
@@ -185,13 +185,6 @@ def translate_text(text: str, lang: str, *, is_title: bool = False, context: str
|
|
|
|
return out
|
|
|
|
return out
|
|
|
|
user = f"<<<INI>>>{text}<<<FIN>>>"
|
|
|
|
user = f"<<<INI>>>{text}<<<FIN>>>"
|
|
|
|
if is_title:
|
|
|
|
if is_title:
|
|
|
|
context_block = ""
|
|
|
|
|
|
|
|
if context:
|
|
|
|
|
|
|
|
context_block = (
|
|
|
|
|
|
|
|
"\nBODY CONTEXT (for meaning only; do not translate or include it):\n"
|
|
|
|
|
|
|
|
f"<<<CONTEXT>>>{context}<<<ENDCONTEXT>>>\n"
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
user = context_block + user
|
|
|
|
|
|
|
|
kind = "el TÍTULO"
|
|
|
|
kind = "el TÍTULO"
|
|
|
|
task = (
|
|
|
|
task = (
|
|
|
|
f"Traduce {kind} que va entre las marcas.\n"
|
|
|
|
f"Traduce {kind} que va entre las marcas.\n"
|
|
|
@@ -199,7 +192,6 @@ def translate_text(text: str, lang: str, *, is_title: bool = False, context: str
|
|
|
|
f"No lo dejes en inglés salvo que el original ya sea un nombre propio o una marca.\n"
|
|
|
|
f"No lo dejes en inglés salvo que el original ya sea un nombre propio o una marca.\n"
|
|
|
|
f"Responde solo con el título traducido entre las marcas:\n{user}"
|
|
|
|
f"Responde solo con el título traducido entre las marcas:\n{user}"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
task += "\nSi es un modismo, interpreta su sentido segun el contexto, no lo calques."
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
kind = "el texto"
|
|
|
|
kind = "el texto"
|
|
|
|
task = f"Traduce {kind} que va entre las marcas:\n{user}"
|
|
|
|
task = f"Traduce {kind} que va entre las marcas:\n{user}"
|
|
|
@@ -234,13 +226,6 @@ def translate_html(html: str, lang: str) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ── Datos / estado ───────────────────────────────────────────────────────────
|
|
|
|
# ── Datos / estado ───────────────────────────────────────────────────────────
|
|
|
|
def title_context(html: str) -> str:
|
|
|
|
|
|
|
|
"""First paragraph gives title idioms enough meaning without bloating the prompt."""
|
|
|
|
|
|
|
|
first = re.search(r"<p\b[^>]*>.*?</p>", html, flags=re.IGNORECASE | re.DOTALL)
|
|
|
|
|
|
|
|
context = first.group(0) if first else html
|
|
|
|
|
|
|
|
return re.sub(r"\s+", " ", context).strip()[:2000]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def read_post(post_id: int) -> dict:
|
|
|
|
def read_post(post_id: int) -> dict:
|
|
|
|
return json.loads(php_helper("read", str(post_id)))
|
|
|
|
return json.loads(php_helper("read", str(post_id)))
|
|
|
|
|
|
|
|
|
|
|
@@ -305,8 +290,8 @@ def process_post(post_id: int, langs: list[str], status: str, force: bool, state
|
|
|
|
log(f" {lang}: --force, eliminada traducción previa #{existing}")
|
|
|
|
log(f" {lang}: --force, eliminada traducción previa #{existing}")
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
t0 = time.time()
|
|
|
|
t0 = time.time()
|
|
|
|
|
|
|
|
title = translate_text(src["title"], lang, is_title=True)
|
|
|
|
content = translate_html(src["content"], lang)
|
|
|
|
content = translate_html(src["content"], lang)
|
|
|
|
title = translate_text(src["title"], lang, is_title=True, context=title_context(src["content"]))
|
|
|
|
|
|
|
|
new_id = create_translation(post_id, lang, title, content, status)
|
|
|
|
new_id = create_translation(post_id, lang, title, content, status)
|
|
|
|
dt = time.time() - t0
|
|
|
|
dt = time.time() - t0
|
|
|
|
log(f" {lang}: creado #{new_id} ({dt:.0f}s) → «{title[:50]}»")
|
|
|
|
log(f" {lang}: creado #{new_id} ({dt:.0f}s) → «{title[:50]}»")
|
|
|
@@ -339,7 +324,8 @@ def main() -> int:
|
|
|
|
ids = [int(x) for x in Path(args.ids_file).read_text().split() if x.strip().isdigit()]
|
|
|
|
ids = [int(x) for x in Path(args.ids_file).read_text().split() if x.strip().isdigit()]
|
|
|
|
log(f"ids-file {args.ids_file}: {len(ids)} posts")
|
|
|
|
log(f"ids-file {args.ids_file}: {len(ids)} posts")
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
ids = [args.carta] + carta_article_ids(args.carta)
|
|
|
|
# La carta puede llevar _carta_id (p. ej. tras un sync); no la traduzcas dos veces.
|
|
|
|
|
|
|
|
ids = list(dict.fromkeys([args.carta] + carta_article_ids(args.carta)))
|
|
|
|
log(f"Carta {args.carta}: {len(ids)} posts (carta + {len(ids)-1} artículos)")
|
|
|
|
log(f"Carta {args.carta}: {len(ids)} posts (carta + {len(ids)-1} artículos)")
|
|
|
|
|
|
|
|
|
|
|
|
state = load_state()
|
|
|
|
state = load_state()
|
|
|
|