Spaces:
Running
Running
| """ | |
| viewer_server.py β Application Entrypoint | |
| This file was refactored from a 2800-line monolith into a clean entrypoint. | |
| All business logic has been moved to the `backend/` package: | |
| backend/ | |
| βββ __init__.py β App Factory (create_app) | |
| βββ config.py β All config & environment variables | |
| βββ api/ β Flask Blueprints (routes/controllers) | |
| β βββ auth.py | |
| β βββ books.py | |
| β βββ payment.py | |
| β βββ translate.py | |
| β βββ epub.py | |
| β βββ developer.py | |
| βββ services/ β Business logic layer | |
| β βββ auth_service.py | |
| β βββ book_service.py | |
| β βββ payment_service.py | |
| β βββ email_service.py | |
| β βββ epub_service.py | |
| β βββ translation.py | |
| βββ database/ | |
| β βββ db_manager.py β DB connections, circuit breaker, caches | |
| βββ core/ | |
| β βββ security.py β JWT, bcrypt helpers | |
| β βββ decorators.py β @jwt_required, @require_api_key_auth | |
| β βββ rate_limit.py β IP rate limiters | |
| βββ workers/ | |
| βββ email_worker.py β Background IMAP/Gmail email polling | |
| To run the server: | |
| python viewer_server.py | |
| Or with gunicorn: | |
| gunicorn -w 4 -b 0.0.0.0:5051 "viewer_server:app" | |
| """ | |
| import logging | |
| import sys | |
| import traceback | |
| from flask import jsonify | |
| from backend.core.logger import setup_logger | |
| logger = setup_logger("server") | |
| from backend import create_app | |
| app = create_app() | |
| def handle_exception(e): | |
| """Global unhandled exception handler to output clean JSON in production.""" | |
| # Log the complete stack trace | |
| error_msg = f"Unhandled exception encountered: {str(e)}" | |
| stack_trace = traceback.format_exc() | |
| logger.error(error_msg) | |
| logger.error(stack_trace) | |
| # Trigger asynchronous alert email to Admin | |
| try: | |
| from backend.services.alert_service import send_alert_to_admin | |
| subject = f"Lα»i nghiΓͺm trα»ng (500 Internal Error): {str(e)[:50]}" | |
| body = f"ΔΓ£ xαΊ£y ra lα»i chΖ°a xα» lΓ½ trΓͺn server:<br><strong>Lα»i:</strong> {str(e)}<br><br><strong>Stack Trace:</strong><br>{stack_trace.replace(chr(10), '<br>')}" | |
| send_alert_to_admin("critical_error", subject, body) | |
| except Exception as alert_err: | |
| logger.error(f"Failed to trigger alert email for exception: {alert_err}") | |
| # Return JSON response instead of HTML traceback page | |
| return jsonify({ | |
| "error": "Internal Server Error. Please contact administrator.", | |
| "success": False | |
| }), 500 | |
| def temp_db_fix(): | |
| from flask import request | |
| secret = request.args.get("secret") | |
| if secret != "super_secret_db_fix_2026": | |
| return "Unauthorized", 403 | |
| import os | |
| import psycopg2 | |
| url = os.environ.get("DATABASE_URL") | |
| if not url: | |
| return "DATABASE_URL environment variable is missing", 500 | |
| logs = [] | |
| try: | |
| conn = psycopg2.connect(url) | |
| cursor = conn.cursor() | |
| # 1. Clean up user 75 | |
| tables_to_clean = [ | |
| "refresh_tokens", "bookshelf", "reading_history", "password_reset_tokens", | |
| "api_keys", "api_usage", "translation_history", "vocabulary", | |
| "user_settings", "usage_tracking", "personal_notifications", "login_history" | |
| ] | |
| for tbl in tables_to_clean: | |
| try: | |
| cursor.execute(f"DELETE FROM {tbl} WHERE user_id = 75") | |
| logs.append(f"β Cleaned {tbl} for user_id = 75") | |
| except Exception as e: | |
| logs.append(f"βΉ Could not clean {tbl} for user_id = 75: {e}") | |
| try: | |
| cursor.execute("DELETE FROM users WHERE id = 75") | |
| logs.append("β Deleted user 75 from users table") | |
| except Exception as e: | |
| logs.append(f"β Failed to delete user 75: {e}") | |
| # 2. Link VIP user congkx123789 to Gmail | |
| cursor.execute("SELECT id, username, email, vip_status FROM users WHERE username = %s OR id = 100", ("congkx123789",)) | |
| vip_user = cursor.fetchone() | |
| if vip_user: | |
| vip_id = vip_user[0] | |
| cursor.execute(""" | |
| UPDATE users | |
| SET email = %s, | |
| google_id = NULL, | |
| email_verified = 1 | |
| WHERE id = %s | |
| """, ("havucong25@gmail.com", vip_id)) | |
| logs.append(f"β Linked VIP user {vip_user[1]} (ID {vip_id}) to havucong25@gmail.com") | |
| else: | |
| logs.append("β VIP user congkx123789 not found in database") | |
| conn.commit() | |
| conn.close() | |
| return jsonify({"success": True, "logs": logs}) | |
| except Exception as e: | |
| return jsonify({"success": False, "error": str(e), "logs": logs}) | |
| if __name__ == "__main__": | |
| logger.info("π Server Δang khα»i Δα»ng tαΊ‘i: http://localhost:5051") | |
| app.run(host="0.0.0.0", port=5051, debug=False, threaded=True) | |