Files
Munich-news/backend/routes/rss_routes.py
2025-11-12 22:33:56 +01:00

218 lines
6.9 KiB
Python

"""
RSS Feed management routes
"""
from flask import Blueprint, request, jsonify
from datetime import datetime
from database import rss_feeds_collection
rss_bp = Blueprint('rss', __name__)
@rss_bp.route('/api/rss-feeds', methods=['GET'])
def get_rss_feeds():
"""Get all RSS feeds"""
try:
feeds = list(rss_feeds_collection.find(
{},
{'_id': 0}
).sort('name', 1))
# Convert datetime to ISO format
for feed in feeds:
if 'created_at' in feed:
feed['created_at'] = feed['created_at'].isoformat()
return jsonify({
'feeds': feeds,
'total': len(feeds)
}), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
@rss_bp.route('/api/rss-feeds', methods=['POST'])
def add_rss_feed():
"""Add a new RSS feed"""
try:
data = request.get_json()
# Validate required fields
if not data.get('name'):
return jsonify({'error': 'Feed name is required'}), 400
if not data.get('url'):
return jsonify({'error': 'Feed URL is required'}), 400
if not data.get('category'):
return jsonify({'error': 'Category is required'}), 400
# Category validation - accept any string, but recommend common ones
category = data['category'].strip().lower()
if not category:
return jsonify({'error': 'Category cannot be empty'}), 400
data['category'] = category # Normalize to lowercase
# Check if feed already exists
existing = rss_feeds_collection.find_one({'url': data['url']})
if existing:
return jsonify({'error': 'Feed URL already exists'}), 400
# Create feed document
feed_doc = {
'name': data['name'].strip(),
'url': data['url'].strip(),
'category': data['category'],
'active': data.get('active', True),
'created_at': datetime.utcnow()
}
rss_feeds_collection.insert_one(feed_doc)
return jsonify({
'message': 'RSS feed added successfully',
'feed': {
'name': feed_doc['name'],
'url': feed_doc['url'],
'category': feed_doc['category'],
'active': feed_doc['active']
}
}), 201
except Exception as e:
return jsonify({'error': str(e)}), 500
@rss_bp.route('/api/rss-feeds/<feed_name>', methods=['PUT'])
def update_rss_feed(feed_name):
"""Update an RSS feed"""
try:
data = request.get_json()
# Build update document
update_doc = {}
if 'url' in data:
update_doc['url'] = data['url'].strip()
if 'category' in data:
category = data['category'].strip().lower()
if not category:
return jsonify({'error': 'Category cannot be empty'}), 400
update_doc['category'] = category
if 'active' in data:
update_doc['active'] = bool(data['active'])
if not update_doc:
return jsonify({'error': 'No fields to update'}), 400
result = rss_feeds_collection.update_one(
{'name': feed_name},
{'$set': update_doc}
)
if result.matched_count > 0:
return jsonify({'message': 'RSS feed updated successfully'}), 200
else:
return jsonify({'error': 'Feed not found'}), 404
except Exception as e:
return jsonify({'error': str(e)}), 500
@rss_bp.route('/api/rss-feeds/<feed_name>', methods=['DELETE'])
def delete_rss_feed(feed_name):
"""Delete an RSS feed"""
try:
result = rss_feeds_collection.delete_one({'name': feed_name})
if result.deleted_count > 0:
return jsonify({'message': f'RSS feed "{feed_name}" deleted successfully'}), 200
else:
return jsonify({'error': 'Feed not found'}), 404
except Exception as e:
return jsonify({'error': str(e)}), 500
@rss_bp.route('/api/rss-feeds/export', methods=['GET'])
def export_rss_feeds():
"""Export all RSS feeds as JSON"""
try:
feeds = list(rss_feeds_collection.find(
{},
{'_id': 0}
).sort('name', 1))
# Convert datetime to ISO format
for feed in feeds:
if 'created_at' in feed:
feed['created_at'] = feed['created_at'].isoformat()
return jsonify({
'feeds': feeds,
'total': len(feeds),
'exported_at': datetime.utcnow().isoformat()
}), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
@rss_bp.route('/api/rss-feeds/import', methods=['POST'])
def import_rss_feeds():
"""Import RSS feeds from JSON"""
try:
data = request.get_json()
if not data or 'feeds' not in data:
return jsonify({'error': 'Invalid import data. Expected {feeds: [...]}'}), 400
feeds = data['feeds']
if not isinstance(feeds, list):
return jsonify({'error': 'feeds must be an array'}), 400
imported = 0
skipped = 0
errors = []
for feed in feeds:
try:
# Validate required fields
if not feed.get('name') or not feed.get('url') or not feed.get('category'):
errors.append(f"Skipped invalid feed: {feed.get('name', 'unknown')}")
skipped += 1
continue
# Check if feed already exists
existing = rss_feeds_collection.find_one({'url': feed['url']})
if existing:
errors.append(f"Skipped duplicate: {feed['name']}")
skipped += 1
continue
# Create feed document
feed_doc = {
'name': feed['name'].strip(),
'url': feed['url'].strip(),
'category': feed['category'].strip().lower(),
'active': feed.get('active', True),
'created_at': datetime.utcnow()
}
rss_feeds_collection.insert_one(feed_doc)
imported += 1
except Exception as e:
errors.append(f"Error importing {feed.get('name', 'unknown')}: {str(e)}")
skipped += 1
return jsonify({
'message': f'Import complete: {imported} imported, {skipped} skipped',
'imported': imported,
'skipped': skipped,
'errors': errors if errors else None
}), 200
except Exception as e:
return jsonify({'error': str(e)}), 500