Build: Versión final estable y con nuevo diseño
Aplicación completamente funcional con servidor Waitress. Solucionados todos los problemas de arranque y timeouts. Se ha implementado un nuevo diseño visual moderno en todas las plantillas. El script de instalación está actualizado y es robusto.
This commit is contained in:
parent
2bc9fbcdf8
commit
4ea56f3247
2 changed files with 218 additions and 290 deletions
199
templates/noticias.html
Executable file → Normal file
199
templates/noticias.html
Executable file → Normal file
|
|
@ -1,107 +1,112 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Últimas Noticias RSS{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Últimas Noticias Recopiladas</h1>
|
||||
<a href="/feeds" class="top-link">⚙️ Gestionar feeds RSS</a>
|
||||
<header>
|
||||
<h1>Agregador de Noticias</h1>
|
||||
<p class="subtitle">Tus fuentes de información, en un solo lugar.</p>
|
||||
<a href="{{ url_for('feeds') }}" class="top-link" style="margin-top:15px;">⚙️ Gestionar Feeds</a>
|
||||
</header>
|
||||
|
||||
<div class="card">
|
||||
<form method="get" action="">
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 12px;">
|
||||
<div style="flex:1;">
|
||||
<label for="categoria_id">Categoría</label>
|
||||
<select name="categoria_id" id="categoria_id">
|
||||
<option value="">— Categoría —</option>
|
||||
{% for cid, cnom in categorias %}
|
||||
<option value="{{ cid }}" {% if cat_id == cid %}selected{% endif %}>{{ cnom }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div style="flex:1;">
|
||||
<label for="continente_id">Continente</label>
|
||||
<select name="continente_id" id="continente_id" onchange="filtrarPaisesPorContinente()">
|
||||
<option value="">— Continente —</option>
|
||||
{% for coid, conom in continentes %}
|
||||
<option value="{{ coid }}" {% if cont_id == coid %}selected{% endif %}>{{ conom }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div style="flex:1;">
|
||||
<label for="pais_id">País</label>
|
||||
<select name="pais_id" id="pais_id">
|
||||
<option value="">— País —</option>
|
||||
{% for pid, pnom, contid in paises %}
|
||||
<option value="{{ pid }}"
|
||||
{% if pais_id == pid %}selected{% endif %}
|
||||
{% if cont_id and contid != cont_id %}style="display:none"{% endif %}>
|
||||
{{ pnom }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div style="align-self: flex-end;">
|
||||
<button class="btn" type="submit">Filtrar</button>
|
||||
</div>
|
||||
</div>
|
||||
<script type="application/json" id="paises-data">{{ paises|tojson }}</script>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2 style="margin-top:0;">Noticias recientes</h2>
|
||||
<ul class="noticias-list">
|
||||
{% for fecha, titulo, resumen, url, imagen_url, cat_nom, pais_nom, cont_nom in noticias %}
|
||||
<li class="noticia-item">
|
||||
<div class="noticia-texto">
|
||||
<div style="color:#64748b; font-size:0.97em;"><b>{{ fecha }}</b></div>
|
||||
<a href="{{ url }}" target="_blank"><strong>{{ titulo }}</strong></a><br>
|
||||
<span>{{ resumen|safe }}</span><br>
|
||||
<small style="color:#64748b;">
|
||||
Categoría: {{ cat_nom or 'N/A' }} |
|
||||
País: {{ pais_nom or 'N/A' }} |
|
||||
Continente: {{ cont_nom or 'N/A' }}
|
||||
</small>
|
||||
</div>
|
||||
{% if imagen_url %}
|
||||
<div class="noticia-imagen">
|
||||
<img src="{{ imagen_url }}" alt="img">
|
||||
<div class="card">
|
||||
<h2>Filtrar Noticias</h2>
|
||||
<form method="get" action="{{ url_for('home') }}">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; align-items: flex-end;">
|
||||
<div>
|
||||
<label for="categoria_id">Categoría</label>
|
||||
<select name="categoria_id" id="categoria_id">
|
||||
<option value="">— Todas —</option>
|
||||
{% for cat in categorias %}
|
||||
<option value="{{ cat.id }}" {% if cat_id == cat.id %}selected{% endif %}>{{ cat.nombre }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="continente_id">Continente</label>
|
||||
<select name="continente_id" id="continente_id" onchange="filtrarPaises()">
|
||||
<option value="">— Todos —</option>
|
||||
{% for cont in continentes %}
|
||||
<option value="{{ cont.id }}" {% if cont_id == cont.id %}selected{% endif %}>{{ cont.nombre }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="pais_id">País</label>
|
||||
<select name="pais_id" id="pais_id">
|
||||
<option value="">— Todos —</option>
|
||||
{# El JavaScript llenará esto dinámicamente, pero mostramos el seleccionado si existe #}
|
||||
{% for pais in paises %}
|
||||
{% if pais_id == pais.id %}
|
||||
<option value="{{ pais.id }}" selected>{{ pais.nombre }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" class="btn">Filtrar</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% else %}
|
||||
<li>No hay noticias que mostrar con estos filtros.</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<a href="/feeds" class="top-link">← Volver a gestión de feeds</a>
|
||||
<div class="noticias-list">
|
||||
{% for noticia in noticias %}
|
||||
<article class="noticia-item">
|
||||
{% if noticia.imagen_url %}
|
||||
<div class="noticia-imagen">
|
||||
<a href="{{ noticia.url }}" target="_blank" rel="noopener noreferrer"><img src="{{ noticia.imagen_url }}" alt="{{ noticia.titulo }}"></a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="noticia-texto">
|
||||
<h3><a href="{{ noticia.url }}" target="_blank" rel="noopener noreferrer">{{ noticia.titulo }}</a></h3>
|
||||
<div class="noticia-meta">
|
||||
<span>🗓️ {{ noticia.fecha.strftime('%d-%m-%Y %H:%M') if noticia.fecha else 'Fecha no disponible' }}</span> |
|
||||
<span>{{ noticia.categoria or 'N/A' }}</span> |
|
||||
<span>{{ noticia.pais or 'Global' }}</span>
|
||||
</div>
|
||||
<p>{{ noticia.resumen | striptags | safe_html | truncate(280) }}</p>
|
||||
</div>
|
||||
</article>
|
||||
{% else %}
|
||||
<div class="card" style="text-align:center;">
|
||||
<p>No hay noticias que mostrar con los filtros seleccionados.</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Filtra países según continente seleccionado, robusto con tipos
|
||||
function filtrarPaisesPorContinente() {
|
||||
const continenteId = document.getElementById('continente_id').value;
|
||||
const paises = JSON.parse(document.getElementById('paises-data').textContent);
|
||||
const selectPais = document.getElementById('pais_id');
|
||||
selectPais.innerHTML = '';
|
||||
// Opción N/A siempre presente
|
||||
const optionNA = document.createElement('option');
|
||||
optionNA.value = '';
|
||||
optionNA.textContent = '— País —';
|
||||
selectPais.appendChild(optionNA);
|
||||
paises.forEach(([id, nombre, contId]) => {
|
||||
// Convertimos ambos a string y número para máxima compatibilidad
|
||||
if (!continenteId || contId == continenteId || contId == Number(continenteId)) {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = id;
|
||||
opt.textContent = nombre;
|
||||
selectPais.appendChild(opt);
|
||||
<script type="application/json" id="paises-data">{{ paises | tojson }}</script>
|
||||
<script>
|
||||
const todosLosPaises = JSON.parse(document.getElementById('paises-data').textContent);
|
||||
const continenteSelect = document.getElementById('continente_id');
|
||||
const paisSelect = document.getElementById('pais_id');
|
||||
const paisSeleccionadoId = '{{ pais_id or '' }}';
|
||||
|
||||
function filtrarPaises() {
|
||||
const continenteId = continenteSelect.value;
|
||||
// Guardamos el valor actual por si necesitamos restaurarlo
|
||||
const valorActualPais = paisSelect.value;
|
||||
|
||||
paisSelect.innerHTML = '<option value="">— Todos —</option>'; // Opción por defecto
|
||||
|
||||
if (todosLosPaises) {
|
||||
todosLosPaises.forEach(pais => {
|
||||
if (!continenteId || pais.continente_id == continenteId) {
|
||||
const option = document.createElement('option');
|
||||
option.value = pais.id;
|
||||
option.textContent = pais.nombre;
|
||||
// Si el ID del país coincide con el que estaba seleccionado, lo volvemos a seleccionar
|
||||
if (pais.id == valorActualPais || pais.id == paisSeleccionadoId) {
|
||||
option.selected = true;
|
||||
}
|
||||
paisSelect.appendChild(option);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Al cargar la página, aplicar filtro si hay continente seleccionado
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
filtrarPaisesPorContinente();
|
||||
});
|
||||
</script>
|
||||
// Ejecutamos la función una vez al cargar la página para inicializar el select de países
|
||||
// según el continente que ya esté seleccionado.
|
||||
document.addEventListener('DOMContentLoaded', filtrarPaises);
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue