diff --git a/app.py b/app.py index f62bd61..9d15d20 100644 --- a/app.py +++ b/app.py @@ -27,7 +27,6 @@ def home(): categorias = [] continentes = [] paises = [] - # Lee los filtros enviados por GET cat_id = request.args.get('categoria_id') cont_id = request.args.get('continente_id') pais_id = request.args.get('pais_id') @@ -38,7 +37,6 @@ def home(): categorias = cursor.fetchall() cursor.execute("SELECT id, nombre FROM continentes ORDER BY nombre") continentes = cursor.fetchall() - # Filtra países si hay continente seleccionado, si no trae todos if cont_id: cursor.execute("SELECT id, nombre, continente_id FROM paises WHERE continente_id = %s ORDER BY nombre", (cont_id,)) else: @@ -92,15 +90,14 @@ def feeds(): try: conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() - # Feeds con país/categoría (incluye nombres) + # Feeds con descripción cursor.execute(""" - SELECT f.id, f.nombre, f.url, f.categoria_id, f.pais_id, f.activo, c.nombre, p.nombre + SELECT f.id, f.nombre, f.descripcion, f.url, f.categoria_id, f.pais_id, f.activo, c.nombre, p.nombre FROM feeds f LEFT JOIN categorias_estandar c ON f.categoria_id = c.id LEFT JOIN paises p ON f.pais_id = p.id """) feeds = cursor.fetchall() - # Categorías, continentes y países para los selects cursor.execute("SELECT id, nombre FROM categorias_estandar ORDER BY nombre") categorias = cursor.fetchall() cursor.execute("SELECT id, nombre FROM continentes ORDER BY nombre") @@ -119,6 +116,7 @@ def feeds(): @app.route('/add', methods=['POST']) def add_feed(): nombre = request.form.get('nombre') + descripcion = request.form.get('descripcion') url = request.form.get('url') categoria_id = request.form.get('categoria_id') pais_id = request.form.get('pais_id') @@ -126,8 +124,8 @@ def add_feed(): conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute( - "INSERT INTO feeds (nombre, url, categoria_id, pais_id) VALUES (%s, %s, %s, %s)", - (nombre, url, categoria_id, pais_id) + "INSERT INTO feeds (nombre, descripcion, url, categoria_id, pais_id) VALUES (%s, %s, %s, %s, %s)", + (nombre, descripcion, url, categoria_id, pais_id) ) conn.commit() except mysql.connector.Error as db_err: @@ -146,17 +144,17 @@ def edit_feed(feed_id): cursor = conn.cursor(dictionary=True) if request.method == 'POST': nombre = request.form.get('nombre') + descripcion = request.form.get('descripcion') url_feed = request.form.get('url') categoria_id = request.form.get('categoria_id') pais_id = request.form.get('pais_id') activo = 1 if request.form.get('activo') == 'on' else 0 cursor.execute( - "UPDATE feeds SET nombre=%s, url=%s, categoria_id=%s, pais_id=%s, activo=%s WHERE id=%s", - (nombre, url_feed, categoria_id, pais_id, activo, feed_id) + "UPDATE feeds SET nombre=%s, descripcion=%s, url=%s, categoria_id=%s, pais_id=%s, activo=%s WHERE id=%s", + (nombre, descripcion, url_feed, categoria_id, pais_id, activo, feed_id) ) conn.commit() return redirect(url_for('feeds')) - # GET: Obtener datos actuales del feed cursor.execute("SELECT * FROM feeds WHERE id = %s", (feed_id,)) feed = cursor.fetchone() cursor.execute("SELECT id, nombre FROM categorias_estandar ORDER BY nombre") @@ -195,7 +193,7 @@ def backup_feeds(): conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() cursor.execute(""" - SELECT f.id, f.nombre, f.url, f.categoria_id, c.nombre AS categoria, f.pais_id, p.nombre AS pais, f.activo + SELECT f.id, f.nombre, f.descripcion, f.url, f.categoria_id, c.nombre AS categoria, f.pais_id, p.nombre AS pais, f.activo FROM feeds f LEFT JOIN categorias_estandar c ON f.categoria_id = c.id LEFT JOIN paises p ON f.pais_id = p.id @@ -209,7 +207,6 @@ def backup_feeds(): if conn: conn.close() - # CSV en memoria si = StringIO() cw = csv.writer(si) cw.writerow(header) @@ -222,7 +219,51 @@ def backup_feeds(): headers={"Content-Disposition": "attachment;filename=feeds_backup.csv"} ) -# (Antiguo /noticias, por compatibilidad) +# Restaurar feeds desde CSV +@app.route('/restore_feeds', methods=['GET', 'POST']) +def restore_feeds(): + msg = "" + if request.method == 'POST': + file = request.files.get('file') + if not file or not file.filename.endswith('.csv'): + msg = "Archivo no válido." + else: + file_stream = StringIO(file.read().decode('utf-8')) + reader = csv.DictReader(file_stream) + rows = list(reader) + conn = mysql.connector.connect(**DB_CONFIG) + cursor = conn.cursor() + n_ok = 0 + for row in rows: + try: + # Soporta CSV con o sin columna 'descripcion' + descripcion = row.get('descripcion') or "" + cursor.execute(""" + INSERT INTO feeds (nombre, descripcion, url, categoria_id, pais_id, activo) + VALUES (%s, %s, %s, %s, %s, %s) + ON DUPLICATE KEY UPDATE + nombre=VALUES(nombre), + descripcion=VALUES(descripcion), + url=VALUES(url), + categoria_id=VALUES(categoria_id), + pais_id=VALUES(pais_id), + activo=VALUES(activo) + """, ( + row['nombre'], + descripcion, + row['url'], + row['categoria_id'], + row['pais_id'], + int(row['activo']) + )) + n_ok += 1 + except Exception as e: + app.logger.error(f"Error insertando feed {row}: {e}") + conn.commit() + conn.close() + msg = f"Feeds restaurados correctamente: {n_ok}" + return render_template("restore_feeds.html", msg=msg) + @app.route('/noticias') def show_noticias(): return home() @@ -232,7 +273,6 @@ def fetch_and_store(): try: conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() - # Leer feeds activos con país/categoría cursor.execute("SELECT url, categoria_id, pais_id FROM feeds WHERE activo = TRUE") feeds = cursor.fetchall() except mysql.connector.Error as db_err: diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..fd16237 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,17 @@ + + +
+ +