-> escribe /tmp/fea_es.json {title, content, status} * update -> actualiza post_title/post_content desde ficheros * listpending ... -> cola de backlog TTS pendiente (ver abajo) * Carga wp-load; portable (local docker o prod via FEA_WP_LOAD). */ $WP = getenv('FEA_WP_LOAD') ?: '/var/www/html/wp-load.php'; require $WP; // Por debajo de esto el post_content no da para locutar (prefiltro barato en SQL; // tts_produce.py vuelve a medir el texto ya extraído y marca fea_audio_skip). const FEA_TTS_MIN_CONTENT = 400; $action = $argv[1] ?? ''; if ($action === 'get') { $id = (int)$argv[2]; $p = get_post($id); if (!$p) { fwrite(STDERR, "no existe $id\n"); exit(1); } file_put_contents('/tmp/fea_es.json', json_encode([ 'id' => $id, 'title' => $p->post_title, 'content' => $p->post_content, 'status' => $p->post_status, 'post_type' => $p->post_type, 'post_name' => $p->post_name, 'author' => (int)$p->post_author, ], JSON_UNESCAPED_UNICODE)); exit(0); } if ($action === 'update') { $id = (int)$argv[2]; $title = rtrim(file_get_contents($argv[3]), "\r\n"); $body = file_get_contents($argv[4]); if (!get_post($id)) { fwrite(STDERR, "no existe $id\n"); exit(1); } $r = wp_update_post([ 'ID' => $id, 'post_title' => $title, 'post_content' => $body, ], true); if (is_wp_error($r)) { fwrite(STDERR, "error: " . $r->get_error_message() . "\n"); exit(1); } fwrite(STDOUT, "ok actualizado $id\n"); exit(0); } if ($action === 'getmeta') { echo get_post_meta((int)$argv[2], $argv[3], true); exit(0); } if ($action === 'setaudio') { // setaudio [voice_id] $id = (int)$argv[2]; $voice = $argv[4] ?? 'NicoFeadulta2026'; update_post_meta($id, 'fea_audio_url', home_url($argv[3])); update_post_meta($id, 'fea_audio_voice', $voice); update_post_meta($id, 'fea_audio_done', '1'); delete_post_meta($id, 'fea_audio_error'); fwrite(STDOUT, "ok " . home_url($argv[3]) . "\n"); exit(0); } if ($action === 'setflag') { // setflag update_post_meta((int)$argv[2], $argv[3], $argv[4]); exit(0); } if ($action === 'unsetaudio') { // unsetaudio (rollback: despublica el audio) $id = (int)$argv[2]; delete_post_meta($id, 'fea_audio_url'); delete_post_meta($id, 'fea_audio_voice'); delete_post_meta($id, 'fea_audio_done'); delete_post_meta($id, 'fea_audio_error'); fwrite(STDOUT, "ok despublicado $id\n"); exit(0); } if ($action === 'listpending') { // listpending [voz_esperada] // Cola del backlog de TTS: posts ES publicados de un autor que todavía no tienen // audio. La consulta ES la idempotencia — no hay fichero de estado que mantener: // lo ya locutado deja de salir solo. Si se pasa la voz clonada del autor, también // salen los que se locutaron en su día con otra voz (p. ej. Nico), para rehacerlos. $autor = (int)($argv[2] ?? 0); $desde = (int)($argv[3] ?? 0); $hasta = (int)($argv[4] ?? 9999); $limite = (int)($argv[5] ?? 50); $voz = (string)($argv[6] ?? ''); if (!$autor) { fwrite(STDERR, "uso: listpending [voz_esperada]\n"); exit(2); } if ($limite <= 0) { $limite = 100000; } global $wpdb; $es = (int)$wpdb->get_var(" SELECT tt.term_taxonomy_id FROM {$wpdb->term_taxonomy} tt JOIN {$wpdb->terms} t ON t.term_id = tt.term_id WHERE tt.taxonomy = 'language' AND t.slug = 'es' LIMIT 1"); if (!$es) { fwrite(STDERR, "no encuentro el idioma 'es' de polylang\n"); exit(1); } $ids = $wpdb->get_col($wpdb->prepare(" SELECT p.ID FROM {$wpdb->posts} p JOIN {$wpdb->term_relationships} tr ON tr.object_id = p.ID AND tr.term_taxonomy_id = %d LEFT JOIN {$wpdb->postmeta} done ON done.post_id = p.ID AND done.meta_key = 'fea_audio_done' LEFT JOIN {$wpdb->postmeta} voz ON voz.post_id = p.ID AND voz.meta_key = 'fea_audio_voice' LEFT JOIN {$wpdb->postmeta} skip ON skip.post_id = p.ID AND skip.meta_key = 'fea_audio_skip' WHERE p.post_author = %d AND p.post_type = 'post' AND p.post_status = 'publish' AND YEAR(p.post_date) BETWEEN %d AND %d AND CHAR_LENGTH(p.post_content) >= %d AND (skip.meta_value IS NULL OR skip.meta_value <> '1') AND (done.meta_value IS NULL OR done.meta_value <> '1' OR (%s <> '' AND COALESCE(voz.meta_value, '') <> %s)) ORDER BY p.post_date DESC LIMIT %d", $es, $autor, $desde, $hasta, FEA_TTS_MIN_CONTENT, $voz, $voz, $limite)); foreach ($ids as $id) { echo (int)$id . "\n"; } exit(0); } fwrite(STDERR, "uso: get|update|getmeta|setaudio|setflag|unsetaudio|listpending\n"); exit(2);