""" 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/', 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/', 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