if (!defined('ABSPATH')) exit; if (!defined('TN_ADMIN_PANEL_BUDGET')) define('TN_ADMIN_PANEL_BUDGET', 0.50); if (!function_exists('tn_admin_panel_can')) { function tn_admin_panel_can() { return current_user_can('manage_options'); } } if (!function_exists('tn_admin_panel_backup')) { function tn_admin_panel_backup($post) { update_post_meta($post->ID, '_tn_admin_prev', base64_encode(wp_json_encode(array( 'content' => $post->post_content, 'excerpt' => $post->post_excerpt, 'status' => $post->post_status, 'time' => current_time('mysql'), )))); $force = function () { return 5; }; add_filter('wp_revisions_to_keep', $force, 99); wp_save_post_revision($post->ID); remove_filter('wp_revisions_to_keep', $force, 99); } } if (!function_exists('tn_admin_source_name')) { function tn_admin_source_name($pid) { $map = array( 'lapatilla.com' => 'Lapatilla', 'ambito.com' => 'Ámbito', 'albertonews.com' => 'AlbertoNews', 'dw.com' => 'DW', 'diarioavance.com' => 'Diario Avance', 'elnacional.com' => 'El Nacional', 'elpais.com' => 'El País', 'vidaextra.com' => 'VidaExtra', 'bbc.com' => 'BBC', 'infobae.com' => 'Infobae', 'primicia.com.ve' => 'Primicia', 'esconusted.com' => 'Es Con Usted', 'okdiario.com' => 'OkDiario', 'elpitazo.net' => 'El Pitazo', 'runrun.es' => 'Runrun.es', 'efe.com' => 'EFE', 'clarin.com' => 'Clarín', 'cnn.com' => 'CNN', 'elmundo.es' => 'El Mundo', 'rt.com' => 'RT', 'eltiempo.com' => 'El Tiempo', 'noticiasaldiayalahora.co' => 'Noticias Al Día y a la Hora', ); $link = get_post_meta($pid, 'original_link', true); if (!$link) return ''; $host = preg_replace('/^www\./', '', strtolower((string) parse_url($link, PHP_URL_HOST))); if ($host === '') return ''; foreach ($map as $d => $n) { if ($host === $d || substr($host, -strlen('.' . $d)) === '.' . $d) return $n; } $p = explode('.', $host); $i = max(0, count($p) - 2); $label = $p[$i]; if (in_array($label, array('com','co','net','org','gob','edu'), true) && count($p) >= 3) $label = $p[count($p) - 3]; return ucwords(str_replace('-', ' ', $label)); } } if (!function_exists('tn_admin_img_identity')) { function tn_admin_img_identity(DOMElement $img) { $cand = ''; foreach (array('data-src','data-lazy-src','data-lazyload','data-original','src') as $a) { $v = trim($img->getAttribute($a)); if ($v !== '' && stripos($v, 'data:image') !== 0) { $cand = $v; break; } } if ($cand === '') { $ss = trim($img->getAttribute('srcset')); if ($ss !== '') { $first = explode(',', $ss); $cand = trim(explode(' ', trim($first[0]))[0]); } } if ($cand === '') return ''; $u = html_entity_decode($cand, ENT_QUOTES); $u = preg_replace('/[?#].*$/', '', $u); $u = preg_replace('#^[a-z]+://#i', '', $u); $u = preg_replace('#^//#', '', $u); $u = preg_replace('/^www\./i', '', $u); return strtolower(rawurldecode($u)); } } if (!function_exists('tn_admin_dedupe_images')) { function tn_admin_dedupe_images(DOMDocument $doc, DOMXPath $xp) { $root = $doc->getElementById('__tnroot'); if (!$root) return 0; $tokens = array(); $walk = function ($node) use (&$walk, &$tokens) { foreach ($node->childNodes as $c) { if ($c->nodeType === XML_TEXT_NODE) { if (trim(preg_replace('/[\s\x{00a0}]+/u', ' ', $c->nodeValue)) !== '') $tokens[] = array('t' => 'text'); continue; } if (!($c instanceof DOMElement)) continue; $tag = strtolower($c->nodeName); if ($tag === 'img') { $tokens[] = array('t' => 'img', 'node' => $c); continue; } if (in_array($tag, array('iframe','video','audio','blockquote','script','embed','object','svg'), true)) { $tokens[] = array('t' => 'media'); continue; } $walk($c); } }; $walk($root); $lastId = null; $broken = true; $uniq = 0; $toRemove = array(); foreach ($tokens as $tk) { if ($tk['t'] !== 'img') { $broken = true; continue; } $idn = tn_admin_img_identity($tk['node']); if ($idn === '') $idn = "\0u" . (++$uniq); if ($lastId !== null && !$broken && $idn === $lastId) { $toRemove[] = $tk['node']; } else { $lastId = $idn; $broken = false; } } foreach ($toRemove as $imgn) { $p = $imgn->parentNode; if ($p) $p->removeChild($imgn); while ($p instanceof DOMElement && $p->getAttribute('id') !== '__tnroot' && $p->parentNode) { $hasMedia = false; foreach (array('img','iframe','video','audio','picture','blockquote','script','embed','object','svg') as $t) { if ($p->getElementsByTagName($t)->length > 0) { $hasMedia = true; break; } } $txt = trim(preg_replace('/[\s\x{00a0}]+/u', '', $p->textContent)); if (!$hasMedia && $txt === '') { $up = $p->parentNode; $up->removeChild($p); $p = $up; } else break; } } return count($toRemove); } } if (!function_exists('tn_admin_curar_safe')) { function tn_admin_curar_safe($pid, $html) { $rep = array('source' => '', 'footer' => 'ya_existe', 'credits' => array(), 'junk' => array(), 'dupes' => 0); if (trim($html) === '') return array($html, $rep); $src = tn_admin_source_name((int) $pid); $rep['source'] = $src; $has_footer = stripos($html, 'Fuente de TenemosNoticias.com:') !== false; $prev = libxml_use_internal_errors(true); libxml_clear_errors(); $doc = new DOMDocument(); $doc->loadHTML('
' . $html . '
', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NONET); libxml_clear_errors(); libxml_use_internal_errors($prev); $xp = new DOMXPath($doc); $rep['dupes'] = tn_admin_dedupe_images($doc, $xp); $prot = function ($n) { if (!($n instanceof DOMElement)) return false; foreach (array('img','iframe','blockquote','script','video','audio','source','picture') as $t) { if ($n->getElementsByTagName($t)->length > 0) return true; } if (preg_match('/lazyload|wp-block-embed|twitter|instagram|tiktok|fb-|embed/i', $n->getAttribute('class') . ' ' . $n->getAttribute('id'))) return true; foreach ($n->attributes as $a) { if (stripos($a->name, 'data-src') !== false) return true; } return false; }; $junk = array( '/^Publicidad( \/ Contenido Patrocinado)?$/iu', '/^Contenido Patrocinado( \/ Recomendado para ti)?$/iu', '/^Recomendado para ti$/iu', '/Para leer la nota completa/iu', '/Sigue en directo/iu', '/Venezuela atraviesa un plan de TRES FASES/iu', ); foreach (iterator_to_array($xp->query('//p|//h2|//h3|//h4')) as $n) { if (!($n instanceof DOMElement) || !$n->parentNode) continue; if ($prot($n)) continue; $t = trim(preg_replace('/\s+/u', ' ', $n->textContent)); if ($t === '') continue; $isj = false; foreach ($junk as $p) { if (preg_match($p, $t)) { $isj = true; break; } } if ($isj) { $rep['junk'][] = mb_substr($t, 0, 45); $n->parentNode->removeChild($n); continue; } if ($n->getElementsByTagName('a')->length > 0) continue; $iscred = false; if ($src !== '' && mb_strtolower($t) === mb_strtolower($src)) $iscred = true; if (!$iscred && preg_match('/^Por:?\s+[a-z0-9.\-]+\.[a-z]{2,}$/iu', $t)) $iscred = true; if ($iscred) { $rep['credits'][] = mb_substr($t, 0, 45); $n->parentNode->removeChild($n); } } foreach (iterator_to_array($xp->query('//*[@id="mc_embed_signup"]')) as $n) { if ($n instanceof DOMElement && !$prot($n) && $n->parentNode) { $rep['junk'][] = '#mc_embed_signup'; $n->parentNode->removeChild($n); } } foreach (iterator_to_array($xp->query('//p')) as $n) { if (!($n instanceof DOMElement) || !$n->parentNode) continue; if ($prot($n)) continue; if ($n->getElementsByTagName('a')->length > 0) continue; $t = trim(preg_replace('/\x{00a0}|\s+/u', '', $n->textContent)); if ($t === '') $n->parentNode->removeChild($n); } foreach (iterator_to_array($xp->query('//*[contains(@style,"padding-bottom") or contains(@style,"padding-top") or contains(@style,"aspect-ratio")]')) as $n) { if (!($n instanceof DOMElement) || !$n->parentNode) continue; $hm = $n->getElementsByTagName('img')->length || $n->getElementsByTagName('iframe')->length || $n->getElementsByTagName('video')->length || $n->getElementsByTagName('picture')->length; if ($hm) { $st = preg_replace('/(?:^|;)\s*(?:padding-bottom|padding-top|aspect-ratio)\s*:[^;]*/i', '', (string) $n->getAttribute('style')); $st = trim($st, " ;"); if ($st === '') { $n->removeAttribute('style'); } else { $n->setAttribute('style', $st); } } elseif (!$prot($n)) { $rep['junk'][] = 'aspect_vacio'; $n->parentNode->removeChild($n); } } for ($pass = 0; $pass < 2; $pass++) { foreach (iterator_to_array($xp->query('//div|//span|//section|//figure|//aside|//ul|//ol')) as $n) { if (!($n instanceof DOMElement) || !$n->parentNode) continue; if ($n->getAttribute('id') === '__tnroot') continue; if ($prot($n)) continue; if ($n->getElementsByTagName('a')->length > 0) continue; $t2 = trim(preg_replace('/\x{00a0}|\s+/u', '', $n->textContent)); if ($t2 === '') $n->parentNode->removeChild($n); } } $root = $doc->getElementById('__tnroot'); $clean = ''; if ($root) { foreach ($root->childNodes as $c) { $clean .= $doc->saveHTML($c); } } $clean = trim($clean); $clean = preg_replace('/^(?:\s*\s*)+/i', '', $clean); $clean = preg_replace('/(?:\s*\s*)+$/i', '', $clean); $clean = preg_replace('/(?:\s*){2,}/i', '
', $clean); if (!$has_footer && $src !== '') { $clean .= "\n

Fuente de TenemosNoticias.com: " . esc_html($src) . "

"; $rep['footer'] = 'anadido'; } return array($clean, $rep); } } add_action('wp_footer', function () { if (!is_singular('post') || !tn_admin_panel_can()) return; $pid = (int) get_queried_object_id(); $status = esc_html(get_post_status($pid)); $nonce = esc_attr(wp_create_nonce('tn_admin_panel_' . $pid)); $ajax = esc_url(admin_url('admin-ajax.php')); $html = << #tn-adm-panel{display:none;margin:14px 0;padding:12px;border:1px solid #e9ecef;border-radius:10px;background:#f8f9fa;box-shadow:0 3px 10px rgba(0,0,0,.06);font-family:inherit} #tn-adm-panel .tn-adm-h{font-size:12px;font-weight:700;color:#868e96;text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px} #tn-adm-panel .tn-adm-row{display:flex;flex-wrap:wrap;gap:8px} #tn-adm-panel button{flex:1 1 auto;min-width:120px;height:40px;border:none;border-radius:6px;color:#fff;font-size:14px;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px} #tn-adm-panel button:disabled{opacity:.5;cursor:default} #tn-adm-b-draft{background:#868e96}#tn-adm-b-pending{background:#f08c00}#tn-adm-b-enrich{background:#1c7ed6}#tn-adm-b-clean{background:#0ca678} #tn-adm-panel .tn-adm-st{font-weight:700;color:#212529} #tn-adm-toast-wrap{position:fixed;z-index:2147483000;right:18px;bottom:18px;display:flex;flex-direction:column;gap:10px;max-width:340px;width:calc(100vw - 36px);font-family:inherit;pointer-events:none} .tn-adm-toast{pointer-events:auto;display:flex;align-items:flex-start;gap:10px;padding:12px 13px;border-radius:10px;background:#fff;color:#212529;font-size:13.5px;line-height:1.45;box-shadow:0 10px 28px rgba(0,0,0,.16);border-left:4px solid #adb5bd;transform:translateX(120%);opacity:0;transition:transform .34s cubic-bezier(.22,1,.36,1),opacity .34s} .tn-adm-toast.tn-show{transform:translateX(0);opacity:1} .tn-adm-toast.tn-ok{border-left-color:#0ca678}.tn-adm-toast.tn-err{border-left-color:#e03131}.tn-adm-toast.tn-info{border-left-color:#1c7ed6} .tn-adm-toast .tn-ic{flex:0 0 auto;width:20px;text-align:center;font-size:15px;margin-top:1px} .tn-adm-toast.tn-ok .tn-ic{color:#0ca678}.tn-adm-toast.tn-err .tn-ic{color:#e03131}.tn-adm-toast.tn-info .tn-ic{color:#1c7ed6} .tn-adm-toast .tn-bd{flex:1 1 auto;word-break:break-word} .tn-adm-toast .tn-cl{flex:0 0 auto;cursor:pointer;color:#adb5bd;font-size:18px;line-height:1;background:none;border:none;padding:0;margin:-1px -2px 0 0;width:auto;min-width:0;height:auto} .tn-adm-toast .tn-cl:hover{color:#495057} @media (max-width:600px){#tn-adm-toast-wrap{right:10px;left:10px;bottom:10px;width:auto;max-width:none}} .tn-adm-ov{position:fixed;inset:0;z-index:2147483600;display:flex;align-items:center;justify-content:center;padding:18px;background:rgba(20,22,28,.55);opacity:0;transition:opacity .2s;font-family:inherit} .tn-adm-ov.tn-show{opacity:1} .tn-adm-ov .tn-adm-modal{width:100%;max-width:380px;background:#fff;border-radius:14px;box-shadow:0 18px 50px rgba(0,0,0,.3);padding:20px;transform:translateY(14px) scale(.97);transition:transform .22s cubic-bezier(.22,1,.36,1)} .tn-adm-ov.tn-show .tn-adm-modal{transform:translateY(0) scale(1)} .tn-adm-ov .tn-adm-mh{display:flex;align-items:center;gap:11px;margin-bottom:12px} .tn-adm-ov .tn-adm-mi{flex:0 0 auto;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff;font-size:17px} .tn-adm-ov .tn-adm-mt{font-size:17px;font-weight:700;color:#212529;line-height:1.2} .tn-adm-ov .tn-adm-mb{font-size:14px;line-height:1.5;color:#495057;margin-bottom:20px} .tn-adm-ov .tn-adm-mf{display:flex;gap:10px;justify-content:flex-end} .tn-adm-ov .tn-adm-mf button{border:none;border-radius:8px;height:42px;padding:0 18px;font-size:14px;font-weight:600;cursor:pointer;font-family:inherit;display:flex;align-items:center} .tn-adm-ov .tn-adm-no{background:#f1f3f5;color:#495057} .tn-adm-ov .tn-adm-no:hover{background:#e9ecef} .tn-adm-ov .tn-adm-yes{color:#fff} .tn-adm-ov .tn-adm-yes:hover{filter:brightness(.94)} @media (max-width:600px){.tn-adm-ov{align-items:flex-end;padding:0}.tn-adm-ov .tn-adm-modal{max-width:none;border-radius:16px 16px 0 0;padding:22px 18px calc(22px + env(safe-area-inset-bottom));transform:translateY(100%)}.tn-adm-ov.tn-show .tn-adm-modal{transform:translateY(0)}}
Admin — estado: {$status}
HTML; echo $html; }, 50); add_action('wp_ajax_tn_admin_article_action', function () { $pid = isset($_POST['pid']) ? (int) $_POST['pid'] : 0; if (!$pid || !tn_admin_panel_can() || !check_ajax_referer('tn_admin_panel_' . $pid, 'nonce', false)) { wp_send_json_error(array('msg' => 'No autorizado'), 403); } $op = isset($_POST['op']) ? sanitize_key($_POST['op']) : ''; $post = get_post($pid); if (!$post || $post->post_type !== 'post') wp_send_json_error(array('msg' => 'Articulo invalido'), 400); if (function_exists('set_time_limit')) @set_time_limit(180); if ($op === 'draft' || $op === 'pending') { $new_status = ($op === 'draft') ? 'draft' : 'pending'; $r = wp_update_post(array('ID' => $pid, 'post_status' => $new_status), true); if (is_wp_error($r)) wp_send_json_error(array('msg' => $r->get_error_message())); wp_send_json_success(array('msg' => 'Estado cambiado a ' . $new_status, 'reload' => true)); } if ($op === 'clean') { if (!function_exists('tn_admin_curar_safe')) wp_send_json_error(array('msg' => 'Limpiador no disponible')); $in = $post->post_content; list($clean, $rep) = tn_admin_curar_safe($pid, $in); if ($clean === $in) wp_send_json_success(array('msg' => 'Nada que limpiar (sin relleno ni firmas redundantes).', 'reload' => false)); foreach (array('twitter-tweet','instagram-media','tiktok-embed','fb-post',' 'Abortado por seguridad: la limpieza habria afectado un embed/imagen (' . $m . '). No se guardo nada.')); } } tn_admin_panel_backup($post); $r = wp_update_post(array('ID' => $pid, 'post_content' => $clean), true); if (is_wp_error($r)) wp_send_json_error(array('msg' => $r->get_error_message())); $parts = array(); if (!empty($rep['credits'])) $parts[] = count($rep['credits']) . ' firma(s) de fuente'; if (!empty($rep['junk'])) $parts[] = count($rep['junk']) . ' bloque(s) de relleno'; if (!empty($rep['dupes'])) $parts[] = $rep['dupes'] . ' imagen(es) duplicada(s)'; if ($rep['footer'] === 'anadido') $parts[] = 'pie de fuente anadido (' . $rep['source'] . ')'; $msg = 'Limpiado: ' . (empty($parts) ? 'ajustes menores' : implode(', ', $parts)) . '. Creditos, imagenes distintas y embeds conservados. Respaldo guardado.'; wp_send_json_success(array('msg' => $msg, 'reload' => true)); } if ($op === 'enrich') { if (!class_exists('TN_AI_Compiler\\Enrichment\\Runner')) wp_send_json_error(array('msg' => 'AI Compiler no disponible')); tn_admin_panel_backup($post); $cleanup = function () use ($pid) { global $wpdb; $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->postmeta} WHERE post_id = %d AND (meta_key LIKE %s OR meta_key LIKE %s)", $pid, $wpdb->esc_like('_tn_enrich_') . '%', $wpdb->esc_like('_tn_autopublish_') . '%')); clean_post_cache($pid); }; try { $budget = new \TN_AI_Compiler\Enrichment\Budget((float) TN_ADMIN_PANEL_BUDGET); $runner = new \TN_AI_Compiler\Enrichment\Runner(array('budget' => $budget)); $run_id = 'manual-' . $pid . '-' . time(); $r = $runner->process_one($pid, 1, $run_id, false); } catch (\Throwable $e) { $cleanup(); wp_send_json_error(array('msg' => 'Error al enriquecer: ' . $e->getMessage())); } if ((isset($r['status']) ? $r['status'] : '') === 'review' && !empty($r['draft_id'])) { $draft = get_post((int) $r['draft_id']); if ($draft instanceof \WP_Post) { wp_update_post(array('ID' => $pid, 'post_content' => $draft->post_content, 'post_excerpt' => $draft->post_excerpt), true); wp_delete_post((int) $r['draft_id'], true); } $cleanup(); wp_send_json_success(array('msg' => 'Enriquecido: modelo ' . (isset($r['model']) ? $r['model'] : '?') . ', ratio ' . round((float) (isset($r['ratio']) ? $r['ratio'] : 0), 2) . ', $' . round((float) (isset($r['cost_usd']) ? $r['cost_usd'] : 0), 3) . '. Respaldo guardado.', 'reload' => true)); } $cleanup(); wp_send_json_error(array('msg' => 'No se completo: ' . (isset($r['reason']) ? $r['reason'] : (isset($r['status']) ? $r['status'] : 'desconocido')))); } wp_send_json_error(array('msg' => 'Operacion desconocida')); }); if (!defined('ABSPATH')) exit; if (!defined('TN_ADMIN_PANEL_BUDGET')) define('TN_ADMIN_PANEL_BUDGET', 0.50); if (!function_exists('tn_admin_panel_can')) { function tn_admin_panel_can() { return current_user_can('manage_options'); } } if (!function_exists('tn_admin_panel_backup')) { function tn_admin_panel_backup($post) { update_post_meta($post->ID, '_tn_admin_prev', base64_encode(wp_json_encode(array( 'content' => $post->post_content, 'excerpt' => $post->post_excerpt, 'status' => $post->post_status, 'time' => current_time('mysql'), )))); $force = function () { return 5; }; add_filter('wp_revisions_to_keep', $force, 99); wp_save_post_revision($post->ID); remove_filter('wp_revisions_to_keep', $force, 99); } } if (!function_exists('tn_admin_source_name')) { function tn_admin_source_name($pid) { $map = array( 'lapatilla.com' => 'Lapatilla', 'ambito.com' => 'Ámbito', 'albertonews.com' => 'AlbertoNews', 'dw.com' => 'DW', 'diarioavance.com' => 'Diario Avance', 'elnacional.com' => 'El Nacional', 'elpais.com' => 'El País', 'vidaextra.com' => 'VidaExtra', 'bbc.com' => 'BBC', 'infobae.com' => 'Infobae', 'primicia.com.ve' => 'Primicia', 'esconusted.com' => 'Es Con Usted', 'okdiario.com' => 'OkDiario', 'elpitazo.net' => 'El Pitazo', 'runrun.es' => 'Runrun.es', 'efe.com' => 'EFE', 'clarin.com' => 'Clarín', 'cnn.com' => 'CNN', 'elmundo.es' => 'El Mundo', 'rt.com' => 'RT', 'eltiempo.com' => 'El Tiempo', 'noticiasaldiayalahora.co' => 'Noticias Al Día y a la Hora', ); $link = get_post_meta($pid, 'original_link', true); if (!$link) return ''; $host = preg_replace('/^www\./', '', strtolower((string) parse_url($link, PHP_URL_HOST))); if ($host === '') return ''; foreach ($map as $d => $n) { if ($host === $d || substr($host, -strlen('.' . $d)) === '.' . $d) return $n; } $p = explode('.', $host); $i = max(0, count($p) - 2); $label = $p[$i]; if (in_array($label, array('com','co','net','org','gob','edu'), true) && count($p) >= 3) $label = $p[count($p) - 3]; return ucwords(str_replace('-', ' ', $label)); } } if (!function_exists('tn_admin_img_identity')) { function tn_admin_img_identity(DOMElement $img) { $cand = ''; foreach (array('data-src','data-lazy-src','data-lazyload','data-original','src') as $a) { $v = trim($img->getAttribute($a)); if ($v !== '' && stripos($v, 'data:image') !== 0) { $cand = $v; break; } } if ($cand === '') { $ss = trim($img->getAttribute('srcset')); if ($ss !== '') { $first = explode(',', $ss); $cand = trim(explode(' ', trim($first[0]))[0]); } } if ($cand === '') return ''; $u = html_entity_decode($cand, ENT_QUOTES); $u = preg_replace('/[?#].*$/', '', $u); $u = preg_replace('#^[a-z]+://#i', '', $u); $u = preg_replace('#^//#', '', $u); $u = preg_replace('/^www\./i', '', $u); return strtolower(rawurldecode($u)); } } if (!function_exists('tn_admin_dedupe_images')) { function tn_admin_dedupe_images(DOMDocument $doc, DOMXPath $xp) { $root = $doc->getElementById('__tnroot'); if (!$root) return 0; $tokens = array(); $walk = function ($node) use (&$walk, &$tokens) { foreach ($node->childNodes as $c) { if ($c->nodeType === XML_TEXT_NODE) { if (trim(preg_replace('/[\s\x{00a0}]+/u', ' ', $c->nodeValue)) !== '') $tokens[] = array('t' => 'text'); continue; } if (!($c instanceof DOMElement)) continue; $tag = strtolower($c->nodeName); if ($tag === 'img') { $tokens[] = array('t' => 'img', 'node' => $c); continue; } if (in_array($tag, array('iframe','video','audio','blockquote','script','embed','object','svg'), true)) { $tokens[] = array('t' => 'media'); continue; } $walk($c); } }; $walk($root); $lastId = null; $broken = true; $uniq = 0; $toRemove = array(); foreach ($tokens as $tk) { if ($tk['t'] !== 'img') { $broken = true; continue; } $idn = tn_admin_img_identity($tk['node']); if ($idn === '') $idn = "\0u" . (++$uniq); if ($lastId !== null && !$broken && $idn === $lastId) { $toRemove[] = $tk['node']; } else { $lastId = $idn; $broken = false; } } foreach ($toRemove as $imgn) { $p = $imgn->parentNode; if ($p) $p->removeChild($imgn); while ($p instanceof DOMElement && $p->getAttribute('id') !== '__tnroot' && $p->parentNode) { $hasMedia = false; foreach (array('img','iframe','video','audio','picture','blockquote','script','embed','object','svg') as $t) { if ($p->getElementsByTagName($t)->length > 0) { $hasMedia = true; break; } } $txt = trim(preg_replace('/[\s\x{00a0}]+/u', '', $p->textContent)); if (!$hasMedia && $txt === '') { $up = $p->parentNode; $up->removeChild($p); $p = $up; } else break; } } return count($toRemove); } } if (!function_exists('tn_admin_curar_safe')) { function tn_admin_curar_safe($pid, $html) { $rep = array('source' => '', 'footer' => 'ya_existe', 'credits' => array(), 'junk' => array(), 'dupes' => 0); if (trim($html) === '') return array($html, $rep); $src = tn_admin_source_name((int) $pid); $rep['source'] = $src; $has_footer = stripos($html, 'Fuente de TenemosNoticias.com:') !== false; $prev = libxml_use_internal_errors(true); libxml_clear_errors(); $doc = new DOMDocument(); $doc->loadHTML('
' . $html . '
', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NONET); libxml_clear_errors(); libxml_use_internal_errors($prev); $xp = new DOMXPath($doc); $rep['dupes'] = tn_admin_dedupe_images($doc, $xp); $prot = function ($n) { if (!($n instanceof DOMElement)) return false; foreach (array('img','iframe','blockquote','script','video','audio','source','picture') as $t) { if ($n->getElementsByTagName($t)->length > 0) return true; } if (preg_match('/lazyload|wp-block-embed|twitter|instagram|tiktok|fb-|embed/i', $n->getAttribute('class') . ' ' . $n->getAttribute('id'))) return true; foreach ($n->attributes as $a) { if (stripos($a->name, 'data-src') !== false) return true; } return false; }; $junk = array( '/^Publicidad( \/ Contenido Patrocinado)?$/iu', '/^Contenido Patrocinado( \/ Recomendado para ti)?$/iu', '/^Recomendado para ti$/iu', '/Para leer la nota completa/iu', '/Sigue en directo/iu', '/Venezuela atraviesa un plan de TRES FASES/iu', ); foreach (iterator_to_array($xp->query('//p|//h2|//h3|//h4')) as $n) { if (!($n instanceof DOMElement) || !$n->parentNode) continue; if ($prot($n)) continue; $t = trim(preg_replace('/\s+/u', ' ', $n->textContent)); if ($t === '') continue; $isj = false; foreach ($junk as $p) { if (preg_match($p, $t)) { $isj = true; break; } } if ($isj) { $rep['junk'][] = mb_substr($t, 0, 45); $n->parentNode->removeChild($n); continue; } if ($n->getElementsByTagName('a')->length > 0) continue; $iscred = false; if ($src !== '' && mb_strtolower($t) === mb_strtolower($src)) $iscred = true; if (!$iscred && preg_match('/^Por:?\s+[a-z0-9.\-]+\.[a-z]{2,}$/iu', $t)) $iscred = true; if ($iscred) { $rep['credits'][] = mb_substr($t, 0, 45); $n->parentNode->removeChild($n); } } foreach (iterator_to_array($xp->query('//*[@id="mc_embed_signup"]')) as $n) { if ($n instanceof DOMElement && !$prot($n) && $n->parentNode) { $rep['junk'][] = '#mc_embed_signup'; $n->parentNode->removeChild($n); } } foreach (iterator_to_array($xp->query('//p')) as $n) { if (!($n instanceof DOMElement) || !$n->parentNode) continue; if ($prot($n)) continue; if ($n->getElementsByTagName('a')->length > 0) continue; $t = trim(preg_replace('/\x{00a0}|\s+/u', '', $n->textContent)); if ($t === '') $n->parentNode->removeChild($n); } foreach (iterator_to_array($xp->query('//*[contains(@style,"padding-bottom") or contains(@style,"padding-top") or contains(@style,"aspect-ratio")]')) as $n) { if (!($n instanceof DOMElement) || !$n->parentNode) continue; $hm = $n->getElementsByTagName('img')->length || $n->getElementsByTagName('iframe')->length || $n->getElementsByTagName('video')->length || $n->getElementsByTagName('picture')->length; if ($hm) { $st = preg_replace('/(?:^|;)\s*(?:padding-bottom|padding-top|aspect-ratio)\s*:[^;]*/i', '', (string) $n->getAttribute('style')); $st = trim($st, " ;"); if ($st === '') { $n->removeAttribute('style'); } else { $n->setAttribute('style', $st); } } elseif (!$prot($n)) { $rep['junk'][] = 'aspect_vacio'; $n->parentNode->removeChild($n); } } for ($pass = 0; $pass < 2; $pass++) { foreach (iterator_to_array($xp->query('//div|//span|//section|//figure|//aside|//ul|//ol')) as $n) { if (!($n instanceof DOMElement) || !$n->parentNode) continue; if ($n->getAttribute('id') === '__tnroot') continue; if ($prot($n)) continue; if ($n->getElementsByTagName('a')->length > 0) continue; $t2 = trim(preg_replace('/\x{00a0}|\s+/u', '', $n->textContent)); if ($t2 === '') $n->parentNode->removeChild($n); } } $root = $doc->getElementById('__tnroot'); $clean = ''; if ($root) { foreach ($root->childNodes as $c) { $clean .= $doc->saveHTML($c); } } $clean = trim($clean); $clean = preg_replace('/^(?:\s*\s*)+/i', '', $clean); $clean = preg_replace('/(?:\s*\s*)+$/i', '', $clean); $clean = preg_replace('/(?:\s*){2,}/i', '
', $clean); if (!$has_footer && $src !== '') { $clean .= "\n

Fuente de TenemosNoticias.com: " . esc_html($src) . "

"; $rep['footer'] = 'anadido'; } return array($clean, $rep); } } add_action('wp_footer', function () { if (!is_singular('post') || !tn_admin_panel_can()) return; $pid = (int) get_queried_object_id(); $status = esc_html(get_post_status($pid)); $nonce = esc_attr(wp_create_nonce('tn_admin_panel_' . $pid)); $ajax = esc_url(admin_url('admin-ajax.php')); $html = << #tn-adm-panel{display:none;margin:14px 0;padding:12px;border:1px solid #e9ecef;border-radius:10px;background:#f8f9fa;box-shadow:0 3px 10px rgba(0,0,0,.06);font-family:inherit} #tn-adm-panel .tn-adm-h{font-size:12px;font-weight:700;color:#868e96;text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px} #tn-adm-panel .tn-adm-row{display:flex;flex-wrap:wrap;gap:8px} #tn-adm-panel button{flex:1 1 auto;min-width:120px;height:40px;border:none;border-radius:6px;color:#fff;font-size:14px;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px} #tn-adm-panel button:disabled{opacity:.5;cursor:default} #tn-adm-b-draft{background:#868e96}#tn-adm-b-pending{background:#f08c00}#tn-adm-b-enrich{background:#1c7ed6}#tn-adm-b-clean{background:#0ca678}#tn-adm-b-headline{background:#9c36b5} #tn-adm-panel .tn-adm-st{font-weight:700;color:#212529} #tn-adm-toast-wrap{position:fixed;z-index:2147483000;right:18px;bottom:18px;display:flex;flex-direction:column;gap:10px;max-width:340px;width:calc(100vw - 36px);font-family:inherit;pointer-events:none} .tn-adm-toast{pointer-events:auto;display:flex;align-items:flex-start;gap:10px;padding:12px 13px;border-radius:10px;background:#fff;color:#212529;font-size:13.5px;line-height:1.45;box-shadow:0 10px 28px rgba(0,0,0,.16);border-left:4px solid #adb5bd;transform:translateX(120%);opacity:0;transition:transform .34s cubic-bezier(.22,1,.36,1),opacity .34s} .tn-adm-toast.tn-show{transform:translateX(0);opacity:1} .tn-adm-toast.tn-ok{border-left-color:#0ca678}.tn-adm-toast.tn-err{border-left-color:#e03131}.tn-adm-toast.tn-info{border-left-color:#1c7ed6} .tn-adm-toast .tn-ic{flex:0 0 auto;width:20px;text-align:center;font-size:15px;margin-top:1px} .tn-adm-toast.tn-ok .tn-ic{color:#0ca678}.tn-adm-toast.tn-err .tn-ic{color:#e03131}.tn-adm-toast.tn-info .tn-ic{color:#1c7ed6} .tn-adm-toast .tn-bd{flex:1 1 auto;word-break:break-word} .tn-adm-toast .tn-cl{flex:0 0 auto;cursor:pointer;color:#adb5bd;font-size:18px;line-height:1;background:none;border:none;padding:0;margin:-1px -2px 0 0;width:auto;min-width:0;height:auto} .tn-adm-toast .tn-cl:hover{color:#495057} @media (max-width:600px){#tn-adm-toast-wrap{right:10px;left:10px;bottom:10px;width:auto;max-width:none}} .tn-adm-ov{position:fixed;inset:0;z-index:2147483600;display:flex;align-items:center;justify-content:center;padding:18px;background:rgba(20,22,28,.55);opacity:0;transition:opacity .2s;font-family:inherit} .tn-adm-ov.tn-show{opacity:1} .tn-adm-ov .tn-adm-modal{width:100%;max-width:380px;background:#fff;border-radius:14px;box-shadow:0 18px 50px rgba(0,0,0,.3);padding:20px;transform:translateY(14px) scale(.97);transition:transform .22s cubic-bezier(.22,1,.36,1)} .tn-adm-ov.tn-show .tn-adm-modal{transform:translateY(0) scale(1)} .tn-adm-ov .tn-adm-mh{display:flex;align-items:center;gap:11px;margin-bottom:12px} .tn-adm-ov .tn-adm-mi{flex:0 0 auto;width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff;font-size:17px} .tn-adm-ov .tn-adm-mt{font-size:17px;font-weight:700;color:#212529;line-height:1.2} .tn-adm-ov .tn-adm-mb{font-size:14px;line-height:1.5;color:#495057;margin-bottom:20px} .tn-adm-ov .tn-adm-mf{display:flex;gap:10px;justify-content:flex-end} .tn-adm-ov .tn-adm-mf button{border:none;border-radius:8px;height:42px;padding:0 18px;font-size:14px;font-weight:600;cursor:pointer;font-family:inherit;display:flex;align-items:center} .tn-adm-ov .tn-adm-no{background:#f1f3f5;color:#495057} .tn-adm-ov .tn-adm-no:hover{background:#e9ecef} .tn-adm-ov .tn-adm-yes{color:#fff} .tn-adm-ov .tn-adm-yes:hover{filter:brightness(.94)} @media (max-width:600px){.tn-adm-ov{align-items:flex-end;padding:0}.tn-adm-ov .tn-adm-modal{max-width:none;border-radius:16px 16px 0 0;padding:22px 18px calc(22px + env(safe-area-inset-bottom));transform:translateY(100%)}.tn-adm-ov.tn-show .tn-adm-modal{transform:translateY(0)}}
Admin — estado: {$status}
HTML; echo $html; }, 50); add_action('wp_ajax_tn_admin_article_action', function () { $pid = isset($_POST['pid']) ? (int) $_POST['pid'] : 0; if (!$pid || !tn_admin_panel_can() || !check_ajax_referer('tn_admin_panel_' . $pid, 'nonce', false)) { wp_send_json_error(array('msg' => 'No autorizado'), 403); } $op = isset($_POST['op']) ? sanitize_key($_POST['op']) : ''; $post = get_post($pid); if (!$post || $post->post_type !== 'post') wp_send_json_error(array('msg' => 'Articulo invalido'), 400); if (function_exists('set_time_limit')) @set_time_limit(180); if ($op === 'draft' || $op === 'pending') { $new_status = ($op === 'draft') ? 'draft' : 'pending'; $r = wp_update_post(array('ID' => $pid, 'post_status' => $new_status), true); if (is_wp_error($r)) wp_send_json_error(array('msg' => $r->get_error_message())); wp_send_json_success(array('msg' => 'Estado cambiado a ' . $new_status, 'reload' => true)); } if ($op === 'clean') { if (!function_exists('tn_admin_curar_safe')) wp_send_json_error(array('msg' => 'Limpiador no disponible')); $in = $post->post_content; list($clean, $rep) = tn_admin_curar_safe($pid, $in); if ($clean === $in) wp_send_json_success(array('msg' => 'Nada que limpiar (sin relleno ni firmas redundantes).', 'reload' => false)); foreach (array('twitter-tweet','instagram-media','tiktok-embed','fb-post',' 'Abortado por seguridad: la limpieza habria afectado un embed/imagen (' . $m . '). No se guardo nada.')); } } tn_admin_panel_backup($post); $r = wp_update_post(array('ID' => $pid, 'post_content' => $clean), true); if (is_wp_error($r)) wp_send_json_error(array('msg' => $r->get_error_message())); $parts = array(); if (!empty($rep['credits'])) $parts[] = count($rep['credits']) . ' firma(s) de fuente'; if (!empty($rep['junk'])) $parts[] = count($rep['junk']) . ' bloque(s) de relleno'; if (!empty($rep['dupes'])) $parts[] = $rep['dupes'] . ' imagen(es) duplicada(s)'; if ($rep['footer'] === 'anadido') $parts[] = 'pie de fuente anadido (' . $rep['source'] . ')'; $msg = 'Limpiado: ' . (empty($parts) ? 'ajustes menores' : implode(', ', $parts)) . '. Creditos, imagenes distintas y embeds conservados. Respaldo guardado.'; wp_send_json_success(array('msg' => $msg, 'reload' => true)); } if ($op === 'enrich') { if (!class_exists('TN_AI_Compiler\\Enrichment\\Runner')) wp_send_json_error(array('msg' => 'AI Compiler no disponible')); tn_admin_panel_backup($post); $cleanup = function () use ($pid) { global $wpdb; $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->postmeta} WHERE post_id = %d AND (meta_key LIKE %s OR meta_key LIKE %s)", $pid, $wpdb->esc_like('_tn_enrich_') . '%', $wpdb->esc_like('_tn_autopublish_') . '%')); clean_post_cache($pid); }; try { $budget = new \TN_AI_Compiler\Enrichment\Budget((float) TN_ADMIN_PANEL_BUDGET); $runner = new \TN_AI_Compiler\Enrichment\Runner(array('budget' => $budget)); $run_id = 'manual-' . $pid . '-' . time(); $r = $runner->process_one($pid, 1, $run_id, false); } catch (\Throwable $e) { $cleanup(); wp_send_json_error(array('msg' => 'Error al enriquecer: ' . $e->getMessage())); } if ((isset($r['status']) ? $r['status'] : '') === 'review' && !empty($r['draft_id'])) { $draft = get_post((int) $r['draft_id']); if ($draft instanceof \WP_Post) { wp_update_post(array('ID' => $pid, 'post_content' => $draft->post_content, 'post_excerpt' => $draft->post_excerpt), true); wp_delete_post((int) $r['draft_id'], true); } $cleanup(); wp_send_json_success(array('msg' => 'Enriquecido: modelo ' . (isset($r['model']) ? $r['model'] : '?') . ', ratio ' . round((float) (isset($r['ratio']) ? $r['ratio'] : 0), 2) . ', $' . round((float) (isset($r['cost_usd']) ? $r['cost_usd'] : 0), 3) . '. Respaldo guardado.', 'reload' => true)); } $cleanup(); wp_send_json_error(array('msg' => 'No se completo: ' . (isset($r['reason']) ? $r['reason'] : (isset($r['status']) ? $r['status'] : 'desconocido')))); } if ($op === 'headline') { if (!class_exists('TN_AI_Compiler\Gemini_Provider')) wp_send_json_error(array('msg' => 'Proveedor de IA no disponible')); $old_title = (string) $post->post_title; $old_slug = (string) $post->post_name; if (mb_strlen($old_title) <= 70 && strlen($old_slug) <= 70) { wp_send_json_success(array('msg' => 'El titulo y el slug ya tienen una longitud adecuada. Nada que curar.', 'reload' => false)); } $body_txt = trim(preg_replace('/\s+/u', ' ', (string) wp_strip_all_tags($post->post_content))); $ctx_title = mb_substr($old_title, 0, 400); $ctx_body = mb_substr($body_txt, 0, 800); $system = 'Eres editor de titulares de un portal de noticias venezolano (espanol, es_VE). Redactas titulares claros, naturales y concisos. Devuelve EXCLUSIVAMENTE un objeto JSON valido, sin texto adicional.'; $user = "El campo titulo viene contaminado con el cuerpo del articulo. A partir del material, redacta:\n1) \"title\": un titular de noticia en espanol, natural, de 45 a 70 caracteres, sin punto final, sin el nombre del medio ni del sitio, conservando hechos y entidades clave (personas, lugares, cifras).\n2) \"slug\": version corta del titular en minusculas con guiones (kebab-case), sin tildes, maximo 60 caracteres.\n\nTITULO CRUDO:\n" . $ctx_title . "\n\nCUERPO (extracto):\n" . $ctx_body . "\n\nResponde solo: {\"title\":\"...\",\"slug\":\"...\"}"; try { $provider = new \TN_AI_Compiler\Gemini_Provider(); if (!$provider->is_configured()) wp_send_json_error(array('msg' => 'IA no configurada (falta API key)')); $resp = $provider->generate_with_options(array( 'model' => 'gemini-2.5-flash-lite', 'system_instruction' => $system, 'user_content' => $user, 'temperature' => 0.4, 'max_output_tokens' => 256, 'thinking_budget' => 0, 'response_mime_type' => 'application/json', )); } catch (\Throwable $e) { wp_send_json_error(array('msg' => 'Error de IA: ' . $e->getMessage())); } $data = \TN_AI_Compiler\Gemini_Provider::decode_json((string) (isset($resp['text']) ? $resp['text'] : '')); $new_title = isset($data['title']) ? sanitize_text_field((string) $data['title']) : ''; $new_title = rtrim(trim(preg_replace('/\s+/u', ' ', $new_title)), " \t."); if ($new_title === '' || mb_strlen($new_title) < 12 || mb_strlen($new_title) > 140) { wp_send_json_error(array('msg' => 'La IA no devolvio un titular valido. No se cambio nada.')); } $base = sanitize_title($new_title); if (strlen($base) > 75) { $base = preg_replace('/-[^-]*$/', '', substr($base, 0, 75)); } if ($base === '') $base = sanitize_title($old_slug); $new_slug = wp_unique_post_slug($base, $pid, $post->post_status, $post->post_type, $post->post_parent); tn_admin_panel_backup($post); update_post_meta($pid, '_tn_admin_prev_headline', base64_encode(wp_json_encode(array( 'title' => $old_title, 'slug' => $old_slug, 'time' => current_time('mysql'), )))); $changed_slug = ($new_slug !== $old_slug); $r = wp_update_post(array('ID' => $pid, 'post_title' => $new_title, 'post_name' => $new_slug), true); if (is_wp_error($r)) wp_send_json_error(array('msg' => $r->get_error_message())); $msg = 'Titulo actualizado: ' . esc_html($new_title); if ($changed_slug && $old_slug !== '') $msg .= '. Slug nuevo: la URL anterior redirige 301 a la nueva.'; $msg .= ' Respaldo guardado.'; wp_send_json_success(array('msg' => $msg, 'reload' => true)); } wp_send_json_error(array('msg' => 'Operacion desconocida')); }); Colombianos en Venezuela votan con la esperanza de que mejoren las relaciones binacionales – Efecto Cocuyo - Tenemos Noticias de Latinoamérica y el Mundo
Ir al contenido
Internacionales

Colombianos en Venezuela votan con la esperanza de que mejoren las relaciones binacionales – Efecto Cocuyo

📅 🕐 hace 3 min🔗 Fuente: efectococuyo.com🕑 3 min de lectura
Colombianos en Venezuela votan con la esperanza de que mejoren las relaciones binacionales – Efecto Cocuyo
Compartir:

Los colombianos residentes en Venezuela acudieron este domingo a las urnas para escoger al próximo presidente de Colombia, con el foco puesto en la mejoría de las relaciones bilaterales, un factor que los electores consideran determinante para la estabilidad e integración regional.

Los votantes acudieron a centros de Caracas y del estado Zulia -región fronteriza con Colombia-, y tomaron en cuenta la crisis venezolana y los futuros acercamientos con EEUU para escoger entre Abelardo De la Espriella e Iván Cepeda, los candidatos que compiten por asumir la Presidencia colombiana para el período 2026-2030.

Ciudadanos colombianos asisten a votar para elegir el nuevo presidente de Colombia este domingo, en el consulado de Colombia en Caracas. EFE

En el estado Zulia, donde el padrón es de 45.000 votantes, se instalaron 64 mesas: 37 en la ciudad de Maracaibo, 15 en San Carlos del Zulia y 12 en Machiques, según confirmó a EFE una persona relacionada con el proceso electoral.

Personas asisten a un puesto de votación durante la segunda vuelta de las elecciones presidenciales de Colombia este domingo, en el consulado de Colombia en Caracas (Venezuela). EFE

Gabriel Piñero, miembro de mesa en Maracaibo, subrayó a EFE que la elección del futuro presidente de Colombia incidirá en Venezuela debido a factores como la “cercanía comercial y diplomática, y toda la tradición” entre ambos países.

“Uno busca la integración, otro quizá otros intereses hacia el norte”, apuntó Piñero sobre los candidatos.

Por su parte, Boris Parra dijo a EFE que acudió a votar para evitar que se repitan en Colombia situaciones similares a las de Venezuela.

“Pienso que puede haber una nueva relación, más fresca, de cero, que permita que haya mejoría tanto en Venezuela como en Colombia”, apuntó Parra.

A las afueras del consulado de Colombia en Caracas, Álvaro La Torre consideró que Colombia tiene dos opciones y una de ellas, prosiguió, “representa el continuismo de la tragedia de Venezuela”.

“Me siento contento de haber cumplido con el sagrado deber y contribuir a que Colombia no viva la tragedia de Venezuela”, remató La Torre, en entrevista con EFE.

Sobre el candidato De la Espriella, quien fue abogado del empresario colombo-venezolano Alex Saab -hoy preso en EE.UU. y señalado como presunto “testaferro” del presidente depuesto Nicolás Maduro-, La Torre defendió que todo profesional presta un servicio y que eso “no tiene ninguna vinculación con su manera de pensar”.

“Los abogados están en su derecho de ejercer la profesión y ellos pueden llevar adelante cualquiera de las causas, independientemente de cuál sea la conducta de su defendido en un futuro”, concluyó.

En Colombia, las urnas comenzaron a recibir votos a las 8:00 hora local (13:00 GMT) y permanecerán abiertas ocho horas, hasta las 16:00 hora local (21:00 GMT).

Las encuestas de intención de voto para esta segunda vuelta dan en primer lugar al ultraderechista De la Espriella, que tiene el apoyo del presidente estadounidense, Donald Trump, por delante del izquierdista Iván Cepeda, aliado de Gustavo Petro en el partido Pacto Histórico.

En la primera vuelta, el pasado 31 de mayo, que tuvo una participación del 57,88 %, De la Espriella, llamado ‘el Tigre’ por sus seguidores, obtuvo 10,3 millones de votos (43,78 %), mientras que Cepeda recibió 9,7 millones (40,98 %).

Con información de EFE

Fuente de TenemosNoticias.com: efectococuyo.com

En la sección: Internacionales Archives – Efecto Cocuyo

🔂 ¿Te gustó la noticia? Compártela:
Compartir:
🔗 Fuente original: efectococuyo.com ·

También te puede interesar

¡Copiado al portapapeles!

Mi resumen de noticias

WhatsApp