483c68bf5f
Envoltorio de sync_audio_to_prod.py para lotes de posts: carga los IDs con un array (mapfile/--ids/--file) antes de cualquier ssh y redirige el stdin del proceso hijo a /dev/null, evitando el bug de un while-read compartiendo stdin con ssh (ssh se come el resto del fichero de IDs y el bucle termina sin error tras procesar solo el primero — visto en real el 2026-08-24, lote de 184 que solo sincronizó 1). Para en el primer fallo real, sin reintentos ciegos, y da un resumen ok/skip al cierre. Documentado en README con ejemplo de uso y variables de entorno.
103 lines
3.2 KiB
Bash
Executable File
103 lines
3.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# sync_audio_bulk.sh — Sincroniza a producción, uno por uno, un lote de posts con
|
|
# audio TTS ya generado en local. Envoltorio de sync_audio_to_prod.py que añade
|
|
# "parar en el primer fallo" (el script Python no lo hace: recorre toda la
|
|
# lista y acumula errores, ver #212/#213).
|
|
#
|
|
# Motivo del wrapper en bash con mapfile: un `while read id; do ...; done <
|
|
# fichero` normal comparte el file descriptor de stdin con cualquier `ssh`
|
|
# lanzado dentro del bucle. sync_audio_to_prod.py llama a ssh internamente; si
|
|
# el bucle no está protegido, ssh se come el resto del fichero de IDs y el
|
|
# bucle termina "sin error" tras procesar solo el primero. Detectado y
|
|
# documentado en memoria (feedback-bash-while-read-ssh-stdin) el 2026-08-24
|
|
# tras un lote real que solo sincronizó 1 de 184 posts sin ningún error visible.
|
|
#
|
|
# Uso:
|
|
# scripts/sync_audio_bulk.sh --ids 55519,55520,822
|
|
# scripts/sync_audio_bulk.sh --file /tmp/ids.txt # un ID por línea
|
|
# scripts/sync_audio_bulk.sh --carta 54254 # cola completa de la carta
|
|
# scripts/sync_audio_bulk.sh --ids 55519,55520 --dry-run # solo plan, no toca prod
|
|
#
|
|
# Requiere las mismas variables de entorno que sync_audio_to_prod.py para
|
|
# apuntar a producción (ver ese script): FEA_PROD_SSH_HOST,
|
|
# FEA_PROD_DOCKER_CONTAINER. Ejemplo:
|
|
# export FEA_PROD_SSH_HOST="rafa@188.40.120.157"
|
|
# export FEA_PROD_DOCKER_CONTAINER="wordpress-r2ssjifwj0r0ghyoqd528uaa"
|
|
|
|
set -u
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
SYNC_PY="$SCRIPT_DIR/sync_audio_to_prod.py"
|
|
|
|
usage() {
|
|
echo "Uso: $0 (--ids id1,id2,... | --file ruta | --carta post_id) [--dry-run]" >&2
|
|
exit 2
|
|
}
|
|
|
|
ids_csv=""
|
|
ids_file=""
|
|
carta=""
|
|
dry_run=""
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--ids) ids_csv="$2"; shift 2 ;;
|
|
--file) ids_file="$2"; shift 2 ;;
|
|
--carta) carta="$2"; shift 2 ;;
|
|
--dry-run) dry_run="--dry-run"; shift ;;
|
|
*) usage ;;
|
|
esac
|
|
done
|
|
|
|
# Carga explícita de IDs en un array ANTES de cualquier llamada a ssh — es la
|
|
# parte que evita el bug de stdin. No usar `while read ... < fichero`.
|
|
ids=()
|
|
if [ -n "$ids_csv" ]; then
|
|
IFS=',' read -r -a ids <<< "$ids_csv"
|
|
elif [ -n "$ids_file" ]; then
|
|
mapfile -t ids < "$ids_file"
|
|
elif [ -n "$carta" ]; then
|
|
mapfile -t ids < <(
|
|
python3 - "$carta" <<'PYEOF'
|
|
import subprocess, sys
|
|
sys.path.insert(0, "scripts")
|
|
from sync_audio_to_prod import carta_article_ids
|
|
for pid in carta_article_ids(int(sys.argv[1])):
|
|
print(pid)
|
|
PYEOF
|
|
)
|
|
else
|
|
usage
|
|
fi
|
|
|
|
total=${#ids[@]}
|
|
if [ "$total" -eq 0 ]; then
|
|
echo "Nada que sincronizar (lista de IDs vacía)." >&2
|
|
exit 0
|
|
fi
|
|
|
|
ok=0
|
|
skip=0
|
|
n=0
|
|
for id in "${ids[@]}"; do
|
|
id="$(echo "$id" | tr -d '[:space:]')"
|
|
[ -z "$id" ] && continue
|
|
n=$((n + 1))
|
|
# stdin del hijo explícitamente en /dev/null: cinturón y tirantes además del
|
|
# array en memoria, por si algún día se cambia el bucle.
|
|
out="$(python3 "$SYNC_PY" --ids "$id" $dry_run < /dev/null)"
|
|
rc=$?
|
|
echo "$out"
|
|
if [ $rc -ne 0 ]; then
|
|
echo "=== ABORT: fallo en #$id ($n/$total procesados, $ok ok). Deteniendo lote, sin reintentar. ==="
|
|
exit 1
|
|
fi
|
|
if echo "$out" | grep -q "PLAN: subiría\|#$id: ok"; then
|
|
ok=$((ok + 1))
|
|
else
|
|
skip=$((skip + 1))
|
|
fi
|
|
done
|
|
|
|
echo "=== FIN LOTE. ok=$ok skip=$skip de $total candidatos. ==="
|