Sincronizar mu-plugins/ y scripts/ con el estado real del sitio (2026-07-16)
Este repo llevaba desde el 28-jun sin actualizarse (salvo sync_carta_from_prod.py).
Se pone al dia con 3 semanas de trabajo que solo vivian en el checkout local
completo del proyecto:
- Fix del buscador (issue #178): AND obligatorio en FULLTEXT (antes devolvia
practicamente todo el sitio con cualquier busqueda), exclusion de paginas
indice residuales de la migracion K2, soporte de frase exacta entre comillas.
- Nuevos mu-plugins ya desplegados a prod: fea-carta-id-api, fea-cloudflare-realip,
fea-crear-autor-api, fea-gsc-verification, fea-legacy-redirect (cutover
Joomla->WP, ver issue #162).
- TTS multi-voz por autor, scripts de traduccion, sync de audio a prod,
homenajes Mardones/Galarreta.
Se mantiene la estructura plana del repo (mu-plugins/ + scripts/, sin el
wordpress/wp-content/ del checkout completo) tal y como documenta el README:
es la convencion establecida para este repo, mas limpia para quien solo
necesita leer el codigo. Anadido .gitignore (cache de Python que no debia
commitearse).
Fuente: checkout local completo del proyecto, rama main (commit 69e849d).
This commit is contained in:
+31
-7
@@ -45,6 +45,22 @@ def creds():
|
||||
KEY, GID = creds()
|
||||
H_JSON = {"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"}
|
||||
|
||||
# Voz clonada por autor (WP user_id -> voice_id). Issue #152: solo se aplica a
|
||||
# los artículos de ese autor; el resto sigue con la voz por defecto (Nico).
|
||||
AUTHOR_VOICES = {
|
||||
382: "FrayMarcosFeadulta2026", # Fray Marcos
|
||||
383: "PagolaFeadulta2026", # José Antonio Pagola
|
||||
774: "SicreFeadulta2026", # José Luis Sicre
|
||||
386: "ArregiFeadulta2026", # José Arregi
|
||||
}
|
||||
|
||||
|
||||
def voice_for_author(author_id, default_voice):
|
||||
try:
|
||||
return AUTHOR_VOICES.get(int(author_id), default_voice)
|
||||
except (TypeError, ValueError):
|
||||
return default_voice
|
||||
|
||||
|
||||
def _q(url):
|
||||
return f"{url}?GroupId={GID}" if GID else url
|
||||
@@ -83,7 +99,7 @@ def get_post_text(pid):
|
||||
raw = html.unescape(raw)
|
||||
paras = [re.sub(r"\s+", " ", p).strip() for p in raw.split("\n") if len(p.strip()) > 1]
|
||||
paras = trim_after_author_signature(paras)
|
||||
return d["title"], "\n\n".join(paras)
|
||||
return d["title"], "\n\n".join(paras), d.get("author")
|
||||
|
||||
|
||||
def is_author_signature(text):
|
||||
@@ -114,12 +130,20 @@ def is_author_signature(text):
|
||||
|
||||
|
||||
def trim_after_author_signature(paras):
|
||||
out = []
|
||||
"""Corta tras la firma final del autor, buscando desde el final hacia
|
||||
atrás para no confundirla con encabezados iniciales (p.ej. "CORPUS (A)",
|
||||
"DOMINGO XI (A)") que también matchean la heurística de is_author_signature
|
||||
pero aparecen como primer párrafo, no como firma. Solo cuenta como firma
|
||||
si hay al menos 200 caracteres de contenido real antes de ella."""
|
||||
prefix_len = 0
|
||||
prefix_lens = []
|
||||
for p in paras:
|
||||
out.append(p)
|
||||
if is_author_signature(p):
|
||||
break
|
||||
return out
|
||||
prefix_lens.append(prefix_len)
|
||||
prefix_len += len(p)
|
||||
for i in range(len(paras) - 1, -1, -1):
|
||||
if prefix_lens[i] > 200 and is_author_signature(paras[i]):
|
||||
return paras[: i + 1]
|
||||
return paras
|
||||
|
||||
|
||||
def _sent_pause(n_words, short, long_):
|
||||
@@ -413,7 +437,7 @@ def main():
|
||||
elif cmd == "carta":
|
||||
pid, voice_id = sys.argv[2], sys.argv[3]
|
||||
model = sys.argv[4] if len(sys.argv) > 4 else "speech-2.8-turbo"
|
||||
title, text = get_post_text(int(pid))
|
||||
title, text, _author = get_post_text(int(pid))
|
||||
name = sys.argv[5] if len(sys.argv) > 5 else f"carta-minimax-{pid}-{model.split('-')[-1]}"
|
||||
text = add_pauses(text)
|
||||
print(f"Post #{pid}: «{title}» ({len(text)} car con pausas)")
|
||||
|
||||
Reference in New Issue
Block a user