Mejoras: NER, embeddings, dashboard, docker-compose y limpieza
This commit is contained in:
parent
6c5aff9936
commit
d508dc2058
19 changed files with 2218 additions and 1185 deletions
111
templates/noticia.html
Normal file
111
templates/noticia.html
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}
|
||||
{% set d = dato if dato is defined else (r if r is defined else None) %}
|
||||
{% if d %}
|
||||
{{ d.titulo_trad or d.titulo_orig or d.titulo_traducido or d.titulo_original or 'Detalle de Noticia' }}
|
||||
{% else %}
|
||||
Detalle de Noticia
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% set d = dato if dato is defined else (r if r is defined else None) %}
|
||||
|
||||
{% if not d %}
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<p>No se encontró la noticia solicitada.</p>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="card">
|
||||
<div class="feed-header">
|
||||
<h2 style="margin:0;">
|
||||
{{ d.titulo_trad or d.titulo_orig or d.titulo_traducido or d.titulo_original }}
|
||||
{% if d.lang_to %}<span class="badge" title="Traducción">{{ d.lang_to|upper }}</span>{% endif %}
|
||||
</h2>
|
||||
{% if d.fuente_url or d.url %}
|
||||
<div>
|
||||
<a class="btn btn-small" href="{{ d.fuente_url or d.url }}" target="_blank" rel="noopener">Ver fuente</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="feed-body">
|
||||
<div class="noticia-meta" style="margin-bottom:12px;">
|
||||
{% set fecha_ = d.fecha %}
|
||||
{% if fecha_ %}
|
||||
<i class="far fa-calendar-alt"></i>
|
||||
{% if fecha_ is string %}{{ fecha_ }}{% else %}{{ fecha_.strftime('%d-%m-%Y %H:%M') }}{% endif %}
|
||||
{% endif %}
|
||||
{% if d.fuente_nombre %} | <i class="fas fa-newspaper"></i> {{ d.fuente_nombre }}{% endif %}
|
||||
{% if d.categoria %} | <i class="fas fa-tag"></i> {{ d.categoria }}{% endif %}
|
||||
{% if d.pais %} | <i class="fas fa-globe-americas"></i> {{ d.pais }}{% endif %}
|
||||
</div>
|
||||
|
||||
{% if d.resumen_trad or d.cuerpo_traducido %}
|
||||
<h3>Resumen (traducido)</h3>
|
||||
<div>{{ (d.resumen_trad or d.cuerpo_traducido)|safe_html }}</div>
|
||||
<hr>
|
||||
{% endif %}
|
||||
|
||||
{% if d.resumen_orig or d.cuerpo_original or d.resumen or d.titulo_original %}
|
||||
<h3>Resumen (original)</h3>
|
||||
<div>{{ (d.resumen_orig or d.cuerpo_original or d.resumen)|safe_html }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% if tags is defined and tags and tags|length %}
|
||||
<div style="margin-top:16px;">
|
||||
{% for t in tags %}
|
||||
{# t puede ser DictRow (t['valor']) o tupla (t.0) #}
|
||||
{% set valor = t.valor if t.valor is defined else (t[0] if t[0] is defined else '') %}
|
||||
{% set tipo = t.tipo if t.tipo is defined else (t[1] if t[1] is defined else '') %}
|
||||
<span class="badge" title="{{ (tipo or '')|capitalize }}">{{ valor }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% set rels = relacionadas if relacionadas is defined else None %}
|
||||
{% if rels and rels|length %}
|
||||
<div class="card" style="margin-top:18px;">
|
||||
<div class="card-header">
|
||||
<h3 style="margin:0;">Noticias relacionadas</h3>
|
||||
</div>
|
||||
<div class="feed-body">
|
||||
<ul class="noticias-list">
|
||||
{% for r in rels %}
|
||||
<li class="noticia-item">
|
||||
{% if r.imagen_url %}
|
||||
<div class="noticia-imagen">
|
||||
<a href="{{ r.url }}" target="_blank" rel="noopener">
|
||||
<img src="{{ r.imagen_url }}" alt="Imagen relacionada" loading="lazy">
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="noticia-texto">
|
||||
<h3 class="m0">
|
||||
<a href="{{ r.url }}" target="_blank" rel="noopener">{{ r.titulo }}</a>
|
||||
</h3>
|
||||
<div class="noticia-meta">
|
||||
{% if r.fecha %}
|
||||
<i class="far fa-calendar-alt"></i>
|
||||
{% if r.fecha is string %}{{ r.fecha }}{% else %}{{ r.fecha.strftime('%d-%m-%Y %H:%M') }}{% endif %}
|
||||
{% endif %}
|
||||
{% if r.fuente_nombre %} | <i class="fas fa-newspaper"></i> {{ r.fuente_nombre }}{% endif %}
|
||||
{% if r.score is defined %} | <span title="Similitud coseno">score: {{ "%.3f"|format(r.score) }}</span>{% endif %}
|
||||
</div>
|
||||
{% if r.resumen %}
|
||||
<div class="clamp">{{ r.resumen }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
|
@ -88,10 +88,16 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
const form = document.getElementById('filter-form');
|
||||
const continenteSelect = document.getElementById('continente_id');
|
||||
const paisSelect = document.getElementById('pais_id');
|
||||
const categoriaSelect = document.getElementById('categoria_id');
|
||||
const fechaInput = document.getElementById('fecha');
|
||||
const qInput = document.getElementById('q');
|
||||
|
||||
const pageInput = document.getElementById('page');
|
||||
const origInput = document.getElementById('orig');
|
||||
const langInput = document.getElementById('lang');
|
||||
|
||||
function setPage1() { pageInput.value = 1; }
|
||||
|
||||
function filtrarPaises() {
|
||||
const continenteId = continenteSelect.value;
|
||||
for (let i = 1; i < paisSelect.options.length; i++) {
|
||||
|
|
@ -105,22 +111,14 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
}
|
||||
}
|
||||
|
||||
async function cargarNoticias(keepPage) {
|
||||
if (!keepPage) pageInput.value = 1;
|
||||
|
||||
const formData = new FormData(form);
|
||||
const params = new URLSearchParams(formData);
|
||||
const newUrl = `${form.action}?${params.toString()}`;
|
||||
|
||||
async function cargarNoticiasFromURL(url) {
|
||||
const container = document.getElementById('noticias-container');
|
||||
container.style.opacity = '0.5';
|
||||
container.innerHTML = '<div style="text-align:center; padding: 40px;"><i class="fas fa-spinner fa-spin fa-2x"></i></div>';
|
||||
|
||||
try {
|
||||
const response = await fetch(newUrl, { headers: { 'X-Requested-With': 'XMLHttpRequest' } });
|
||||
const response = await fetch(url, { headers: { 'X-Requested-With': 'XMLHttpRequest' } });
|
||||
const html = await response.text();
|
||||
container.innerHTML = html;
|
||||
window.history.pushState({path: newUrl}, '', newUrl);
|
||||
} catch (error) {
|
||||
console.error('Error al filtrar noticias:', error);
|
||||
container.innerHTML = '<p style="color:var(--error-color); text-align:center;">Error al cargar las noticias.</p>';
|
||||
|
|
@ -129,11 +127,25 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
}
|
||||
}
|
||||
|
||||
async function cargarNoticias(keepPage) {
|
||||
if (!keepPage) setPage1();
|
||||
|
||||
const formData = new FormData(form);
|
||||
const params = new URLSearchParams(formData);
|
||||
const newUrl = `${form.action}?${params.toString()}`;
|
||||
|
||||
await cargarNoticiasFromURL(newUrl);
|
||||
// Actualizar historial
|
||||
window.history.pushState({ path: newUrl }, '', newUrl);
|
||||
}
|
||||
|
||||
// Submit manual
|
||||
form.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
cargarNoticias(false);
|
||||
});
|
||||
|
||||
// Toggle traducción/original
|
||||
const toggleOrig = document.getElementById('toggle-orig');
|
||||
const toggleTr = document.getElementById('toggle-tr');
|
||||
|
||||
|
|
@ -153,12 +165,38 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
});
|
||||
}
|
||||
|
||||
// Cambios en selects/fecha -> recarga automática
|
||||
continenteSelect.addEventListener('change', function() {
|
||||
filtrarPaises();
|
||||
cargarNoticias(false);
|
||||
});
|
||||
paisSelect.addEventListener('change', function() {
|
||||
cargarNoticias(false);
|
||||
});
|
||||
categoriaSelect.addEventListener('change', function() {
|
||||
cargarNoticias(false);
|
||||
});
|
||||
fechaInput.addEventListener('change', function() {
|
||||
cargarNoticias(false);
|
||||
});
|
||||
|
||||
// Debounce búsqueda
|
||||
let qTimer = null;
|
||||
qInput.addEventListener('input', function() {
|
||||
if (qTimer) clearTimeout(qTimer);
|
||||
qTimer = setTimeout(() => {
|
||||
cargarNoticias(false);
|
||||
}, 450);
|
||||
});
|
||||
|
||||
// Cargar países al inicio
|
||||
filtrarPaises();
|
||||
|
||||
// Soporte de navegación del historial
|
||||
window.addEventListener('popstate', function(e) {
|
||||
const url = (e.state && e.state.path) ? e.state.path : window.location.href;
|
||||
cargarNoticiasFromURL(url);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue