Spaces:
Runtime error
Runtime error
| from flask import Flask, render_template, request, jsonify, redirect, url_for | |
| from dataclasses import dataclass, asdict, is_dataclass | |
| from typing import List, Optional, Tuple, Any | |
| import os | |
| import uuid | |
| import base64 | |
| import io | |
| from datetime import datetime | |
| from PIL import Image | |
| # Import configuration | |
| from config import general_config | |
| # ----------------------------- | |
| # Configuration and Setup | |
| # ----------------------------- | |
| # Initialize Flask app with configuration | |
| app = Flask(__name__) | |
| app.config['UPLOAD_FOLDER'] = general_config.flask.UPLOAD_FOLDER | |
| app.config['MAX_CONTENT_LENGTH'] = general_config.flask.MAX_CONTENT_LENGTH | |
| # ----------------------------- | |
| # Data models (matching your schema) | |
| # ----------------------------- | |
| from schemas.fact_search_schemas import FactCheckEntry, FactCheckResult | |
| from schemas.text_schemas import EmotionResult | |
| from schemas.vision_schemas import FaceMainPoints | |
| from schemas.fake_manager_schemas import ImageAnalysis, AggregatedNewsAnalysis | |
| from core.fake_manager import FakeNewsManager | |
| from schemas.fake_manager_schemas import News | |
| from services.ai_text_service import NBAITextDetector | |
| from services.fake_text_news_service import FakeTextNewsDetector | |
| from services.search_quries_service import TransformersSearchQueryExtractor | |
| from services.text_emotion_service import TransformersEmotionDetector | |
| from services.fact_search_service import FactCheckService | |
| from services.ai_image_service import ENetAIImageDetector | |
| from services.face_detection_service import SCRFDFaceDetector | |
| from services.deepfake_service import Meso4FakeFaceDetector | |
| from models.models import LSTMClassifier | |
| # In-memory store: analysis_id -> JSON dict | |
| STORE: dict[str, dict] = {} | |
| # ----------------------------- | |
| # Helpers | |
| # ----------------------------- | |
| def save_image(image_data: str, filename: str | None = None) -> Optional[str]: | |
| try: | |
| if image_data.startswith('data:image'): | |
| header, b64 = image_data.split(',', 1) | |
| mime = header.split(';')[0].split(':')[1] # e.g. image/png | |
| ext = {'image/jpeg': 'jpg', 'image/png': 'png', 'image/webp': 'webp'}.get(mime, 'jpg') | |
| else: | |
| b64 = image_data | |
| ext = 'jpg' | |
| raw = base64.b64decode(b64) | |
| img = Image.open(io.BytesIO(raw)) | |
| img.verify() # validate | |
| img = Image.open(io.BytesIO(raw)) | |
| if img.mode not in ('RGB', 'L'): | |
| img = img.convert('RGB') | |
| if not filename: | |
| filename = f"{uuid.uuid4().hex}.{ext}" | |
| path = os.path.join(app.config['UPLOAD_FOLDER'], filename) | |
| img.save(path, quality=92) | |
| return path | |
| except Exception as e: | |
| print(f"Error saving image: {e}") | |
| import traceback | |
| traceback.print_exc() | |
| return None | |
| def initialize_services(): | |
| """Initialize and configure all ML services.""" | |
| return FakeNewsManager( | |
| ai_text_detector=NBAITextDetector(general_config.service.models.AI_TEXT_DETECTOR), | |
| news_detector=FakeTextNewsDetector( | |
| model_path=general_config.service.models.FAKE_NEWS_DETECTOR, | |
| vocab_path=general_config.service.models.VOCAB_PATH, | |
| ), | |
| query_extractor=TransformersSearchQueryExtractor(), | |
| emotion_detector=TransformersEmotionDetector(), | |
| fact_checker=FactCheckService(api_key=general_config.service.FACT_API_KEY), | |
| ai_image_detector=ENetAIImageDetector(general_config.service.models.EFFICIENTNET_AI_IMAGE), | |
| face_detector=SCRFDFaceDetector( | |
| model_path=general_config.service.models.FACE_DETECTION, | |
| threshold_probability=general_config.service.FACE_DETECTION_THRESHOLD, | |
| nms=general_config.service.FACE_DETECTION_NMS, | |
| ), | |
| fake_face_detector=Meso4FakeFaceDetector( | |
| df_model_path=general_config.service.models.MESO4_DF, | |
| f2f_model_path=general_config.service.models.MESO4_F2F, | |
| ), | |
| ) | |
| # Initialize services | |
| fake_news_manager = initialize_services() | |
| # ----------------------------- | |
| # Routes | |
| # ----------------------------- | |
| def index(): | |
| return render_template('index.html') | |
| def analyze(): | |
| try: | |
| data = request.get_json() | |
| if not data or 'text' not in data or 'images' not in data: | |
| return jsonify({'success': False, 'error': 'Invalid request data'}), 400 | |
| text = (data.get('text') or '').strip() | |
| if not text: | |
| return jsonify({'success': False, 'error': 'News text is required'}), 400 | |
| images_in = data.get('images') or [] | |
| if not images_in: | |
| return jsonify({'success': False, 'error': 'At least one image is required'}), 400 | |
| saved_fs_paths_disk = [] | |
| saved_fs_paths_web = [] | |
| for img in images_in: | |
| path = save_image(img.get('data', '')) | |
| if path: | |
| saved_fs_paths_disk.append(path) | |
| saved_fs_paths_web.append('/' + path.replace('\\', '/')) | |
| news = News(text=text, images=saved_fs_paths_disk) | |
| analysis = fake_news_manager.analyze(news, fakeness_score_threshold=general_config.service.FAKENESS_SCORE_THRESHOLD) | |
| analysis_json = analysis.to_json() | |
| # Overwrite image paths in the JSON to web paths for frontend rendering | |
| for i, img_entry in enumerate(analysis_json.get("images", [])): | |
| if i < len(saved_fs_paths_web): | |
| img_entry["image_path"] = saved_fs_paths_web[i] | |
| STORE[analysis_json["analysis_id"]] = analysis_json | |
| return jsonify({'success': True, 'analysis_id': analysis_json["analysis_id"]}) | |
| except Exception as e: | |
| print("Analysis error:", e) | |
| import traceback | |
| traceback.print_exc() | |
| return jsonify({'success': False, 'error': str(e)}), 500 | |
| def analysis_page(analysis_id): | |
| analysis = STORE.get(analysis_id) | |
| if not analysis: | |
| return redirect(url_for('index')) | |
| return render_template('analysis.html', analysis=analysis) | |
| def health(): | |
| return jsonify({'status': 'healthy', 'timestamp': datetime.now().isoformat()}) | |
| if __name__ == '__main__': | |
| print("Starting News Analyzer Server...") | |
| print("Server running on http://localhost:5000") | |
| app.run(debug=True, host='0.0.0.0', port=5000) | |