| from flask import Blueprint, request, jsonify, current_app |
| from flask_jwt_extended import jwt_required, get_jwt_identity |
| from backend.services.content_service import ContentService |
| import pandas as pd |
|
|
| sources_bp = Blueprint('sources', __name__) |
|
|
| @sources_bp.route('/', methods=['OPTIONS']) |
| @sources_bp.route('', methods=['OPTIONS']) |
| def handle_options(): |
| """Handle OPTIONS requests for preflight CORS checks.""" |
| return '', 200 |
|
|
| @sources_bp.route('/', methods=['GET']) |
| @sources_bp.route('', methods=['GET']) |
| @jwt_required() |
| def get_sources(): |
| """ |
| Get all sources for the current user. |
| |
| Returns: |
| JSON: List of sources |
| """ |
| try: |
| user_id = get_jwt_identity() |
| |
| |
| if not hasattr(current_app, 'supabase') or current_app.supabase is None: |
| |
| response_data = jsonify({ |
| 'success': False, |
| 'message': 'Database connection not initialized' |
| }) |
| response_data.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000') |
| response_data.headers.add('Access-Control-Allow-Credentials', 'true') |
| return response_data, 500 |
| |
| |
| response = ( |
| current_app.supabase |
| .table("Source") |
| .select("*") |
| .eq("user_id", user_id) |
| .execute() |
| ) |
| |
| sources = response.data if response.data else [] |
| |
| |
| response_data = jsonify({ |
| 'success': True, |
| 'sources': sources |
| }) |
| response_data.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000') |
| response_data.headers.add('Access-Control-Allow-Credentials', 'true') |
| return response_data, 200 |
| |
| except Exception as e: |
| current_app.logger.error(f"Get sources error: {str(e)}") |
| |
| response_data = jsonify({ |
| 'success': False, |
| 'message': 'An error occurred while fetching sources' |
| }) |
| response_data.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000') |
| response_data.headers.add('Access-Control-Allow-Credentials', 'true') |
| return response_data, 500 |
|
|
| @sources_bp.route('/', methods=['POST']) |
| @sources_bp.route('', methods=['POST']) |
| @jwt_required() |
| def add_source(): |
| """ |
| Add a new source for the current user. |
| |
| Request Body: |
| source (str): Source URL |
| |
| Returns: |
| JSON: Add source result |
| """ |
| try: |
| user_id = get_jwt_identity() |
| data = request.get_json() |
| |
| |
| if not data or 'source' not in data: |
| return jsonify({ |
| 'success': False, |
| 'message': 'Source URL is required' |
| }), 400 |
| |
| source_url = data['source'] |
| |
| |
| try: |
| content_service = ContentService() |
| result = content_service.add_rss_source(source_url, user_id) |
| |
| return jsonify({ |
| 'success': True, |
| 'message': result |
| }), 201 |
| except Exception as e: |
| |
| current_app.logger.warning(f"Content service failed, storing in database directly: {str(e)}") |
| |
| |
| |
| response = ( |
| current_app.supabase |
| .table("Source") |
| .insert({ |
| "source": source_url, |
| "user_id": user_id, |
| "created_at": "now()" |
| }) |
| .execute() |
| ) |
| |
| if response.data: |
| |
| return jsonify({ |
| 'success': True, |
| 'source': response.data[0] |
| }), 201 |
| else: |
| raise Exception("Failed to store source in database") |
| |
| except Exception as e: |
| current_app.logger.error(f"Add source error: {str(e)}") |
| return jsonify({ |
| 'success': False, |
| 'message': f'An error occurred while adding source: {str(e)}' |
| }), 500 |
|
|
| @sources_bp.route('/<source_id>', methods=['OPTIONS']) |
| def handle_source_options(source_id): |
| """Handle OPTIONS requests for preflight CORS checks for specific source.""" |
| return '', 200 |
|
|
| @sources_bp.route('/keyword-analysis', methods=['OPTIONS']) |
| def handle_keyword_analysis_options(): |
| """Handle OPTIONS requests for preflight CORS checks for keyword analysis.""" |
| return '', 200 |
|
|
|
|
| @sources_bp.route('/keyword-analysis', methods=['POST']) |
| @jwt_required() |
| def analyze_keyword(): |
| """ |
| Analyze keyword frequency in RSS feeds and posts. |
| |
| Request Body: |
| keyword (str): The keyword to analyze |
| date_range (str): The date range to analyze ('daily', 'weekly', 'monthly'), default is 'monthly' |
| |
| Returns: |
| JSON: Keyword frequency analysis data |
| """ |
| try: |
| user_id = get_jwt_identity() |
| data = request.get_json() |
| |
| |
| if not data or 'keyword' not in data: |
| return jsonify({ |
| 'success': False, |
| 'message': 'Keyword is required' |
| }), 400 |
| |
| keyword = data['keyword'] |
| date_range = data.get('date_range', 'monthly') |
| |
| |
| valid_date_ranges = ['daily', 'weekly', 'monthly'] |
| if date_range not in valid_date_ranges: |
| return jsonify({ |
| 'success': False, |
| 'message': f'Invalid date_range. Must be one of: {valid_date_ranges}' |
| }), 400 |
| |
| |
| try: |
| content_service = ContentService() |
| analysis_data = content_service.analyze_keyword_frequency(keyword, user_id, date_range) |
| |
| return jsonify({ |
| 'success': True, |
| 'data': analysis_data, |
| 'keyword': keyword, |
| 'date_range': date_range |
| }), 200 |
| except Exception as e: |
| current_app.logger.error(f"Keyword analysis error: {str(e)}") |
| return jsonify({ |
| 'success': False, |
| 'message': f'An error occurred during keyword analysis: {str(e)}' |
| }), 500 |
| |
| except Exception as e: |
| current_app.logger.error(f"Analyze keyword error: {str(e)}") |
| return jsonify({ |
| 'success': False, |
| 'message': f'An error occurred while analyzing keyword: {str(e)}' |
| }), 500 |
|
|
|
|
| @sources_bp.route('/keyword-frequency-pattern', methods=['POST']) |
| @jwt_required() |
| def analyze_keyword_frequency_pattern(): |
| """ |
| Analyze keyword frequency pattern in RSS feeds and posts. |
| Determines if keyword follows a daily, weekly, monthly, or rare pattern based on recency and frequency. |
| |
| Request Body: |
| keyword (str): The keyword to analyze |
| |
| Returns: |
| JSON: Keyword frequency pattern analysis data |
| """ |
| try: |
| user_id = get_jwt_identity() |
| data = request.get_json() |
| |
| |
| if not data or 'keyword' not in data: |
| return jsonify({ |
| 'success': False, |
| 'message': 'Keyword is required' |
| }), 400 |
| |
| keyword = data['keyword'] |
| |
| |
| try: |
| content_service = ContentService() |
| analysis_result = content_service.analyze_keyword_frequency_pattern(keyword, user_id) |
| |
| return jsonify({ |
| 'success': True, |
| 'data': analysis_result, |
| 'keyword': keyword |
| }), 200 |
| except Exception as e: |
| current_app.logger.error(f"Keyword frequency pattern analysis error: {str(e)}") |
| return jsonify({ |
| 'success': False, |
| 'message': f'An error occurred during keyword frequency pattern analysis: {str(e)}' |
| }), 500 |
| |
| except Exception as e: |
| current_app.logger.error(f"Analyze keyword frequency pattern error: {str(e)}") |
| return jsonify({ |
| 'success': False, |
| 'message': f'An error occurred while analyzing keyword frequency pattern: {str(e)}' |
| }), 500 |
|
|
|
|
| @sources_bp.route('/<source_id>', methods=['DELETE']) |
| @jwt_required() |
| def delete_source(source_id): |
| """ |
| Delete a source. |
| |
| Path Parameters: |
| source_id (str): Source ID |
| |
| Returns: |
| JSON: Delete source result |
| """ |
| try: |
| user_id = get_jwt_identity() |
| |
| |
| response = ( |
| current_app.supabase |
| .table("Source") |
| .delete() |
| .eq("id", source_id) |
| .eq("user_id", user_id) |
| .execute() |
| ) |
| |
| if response.data: |
| return jsonify({ |
| 'success': True, |
| 'message': 'Source deleted successfully' |
| }), 200 |
| else: |
| return jsonify({ |
| 'success': False, |
| 'message': 'Source not found or unauthorized' |
| }), 404 |
| |
| except Exception as e: |
| current_app.logger.error(f"Delete source error: {str(e)}") |
| return jsonify({ |
| 'success': False, |
| 'message': 'An error occurred while deleting source' |
| }), 500 |