| from flask import Flask, jsonify |
| import requests |
| import schedule |
| import time |
| from datetime import datetime |
| import logging |
| import threading |
| import os |
|
|
| |
| logging.basicConfig( |
| level=logging.INFO, |
| format='%(asctime)s - %(levelname)s - %(message)s', |
| handlers=[logging.StreamHandler()] |
| ) |
|
|
| app = Flask(__name__) |
|
|
| |
| scheduler_thread = None |
| scheduler_running = False |
| last_run_status = { |
| "last_run": None, |
| "last_status": "never", |
| "results": {} |
| } |
|
|
| |
|
|
| def backup_main_db(): |
| try: |
| url = "https://dooratre-db.hf.space/admin/backup" |
| headers = {"X-Admin-Secret": "Dbpassword2000$"} |
| response = requests.post(url, headers=headers, timeout=60) |
| logging.info(f"[Main DB] Status: {response.status_code}") |
| return {"status": response.status_code, "ok": response.ok} |
| except Exception as e: |
| logging.error(f"[Main DB] Error: {e}") |
| return {"status": "error", "ok": False, "error": str(e)} |
|
|
| def backup_tele_db(): |
| try: |
| url = "https://dooratre-tele-db.hf.space/api/backup" |
| headers = {"X-API-Key": "Telegrampassword2000$"} |
| response = requests.post(url, headers=headers, timeout=60) |
| logging.info(f"[Tele DB] Status: {response.status_code}") |
| return {"status": response.status_code, "ok": response.ok} |
| except Exception as e: |
| logging.error(f"[Tele DB] Error: {e}") |
| return {"status": "error", "ok": False, "error": str(e)} |
|
|
| def backup_cards_db(): |
| try: |
| url = "https://dooratre-cards.hf.space/admin/backup?secret=Cardspassword2000$" |
| response = requests.post(url, timeout=60) |
| logging.info(f"[Cards DB] Status: {response.status_code}") |
| return {"status": response.status_code, "ok": response.ok} |
| except Exception as e: |
| logging.error(f"[Cards DB] Error: {e}") |
| return {"status": "error", "ok": False, "error": str(e)} |
|
|
| def backup_main_app(server_num): |
| try: |
| url = f"https://serverclass{server_num}-app.hf.space/backup_db" |
| headers = {"X-Admin-Secret": "Adminpassword2000$"} |
| response = requests.post(url, headers=headers, timeout=60) |
| logging.info(f"[Server {server_num}] Status: {response.status_code}") |
| return {"status": response.status_code, "ok": response.ok} |
| except Exception as e: |
| logging.error(f"[Server {server_num}] Error: {e}") |
| return {"status": "error", "ok": False, "error": str(e)} |
|
|
| def backup_all_servers(): |
| results = {} |
| logging.info("Starting backup for all 55 servers...") |
| for i in range(1, 56): |
| results[f"server{i}"] = backup_main_app(i) |
| time.sleep(1) |
| logging.info("Finished backup for all 55 servers.") |
| return results |
|
|
| def run_all_backups(): |
| global last_run_status |
| logging.info("=" * 60) |
| logging.info(f"Starting daily backup at {datetime.now()}") |
| logging.info("=" * 60) |
|
|
| results = { |
| "main_db": backup_main_db(), |
| "tele_db": backup_tele_db(), |
| "cards_db": backup_cards_db(), |
| "servers": backup_all_servers() |
| } |
|
|
| last_run_status["last_run"] = datetime.now().isoformat() |
| last_run_status["last_status"] = "completed" |
| last_run_status["results"] = results |
|
|
| logging.info("=" * 60) |
| logging.info(f"Daily backup completed at {datetime.now()}") |
| logging.info("=" * 60) |
| return results |
|
|
| |
|
|
| def scheduler_loop(): |
| global scheduler_running |
| logging.info("Scheduler loop started.") |
| while scheduler_running: |
| schedule.run_pending() |
| time.sleep(30) |
| logging.info("Scheduler loop stopped.") |
|
|
| |
|
|
| @app.route("/") |
| def home(): |
| return jsonify({ |
| "service": "Backup Scheduler", |
| "version": "1.0", |
| "endpoints": ["/start", "/stop", "/health", "/run-now", "/status"], |
| "scheduler_running": scheduler_running, |
| "schedule": "Every 6 hours" |
| }) |
|
|
| @app.route("/start", methods=["GET", "POST"]) |
| def start(): |
| global scheduler_thread, scheduler_running |
|
|
| if scheduler_running: |
| return jsonify({ |
| "status": "already_running", |
| "message": "Scheduler is already running." |
| }), 200 |
|
|
| schedule.clear() |
| schedule.every(6).hours.do(run_all_backups) |
|
|
| scheduler_running = True |
| scheduler_thread = threading.Thread(target=scheduler_loop, daemon=True) |
| scheduler_thread.start() |
|
|
| logging.info("Scheduler STARTED via API.") |
| return jsonify({ |
| "status": "started", |
| "message": "Scheduler started. Will run every 6 hours.", |
| "interval": "every 6 hours" |
| }), 200 |
|
|
| @app.route("/stop", methods=["GET", "POST"]) |
| def stop(): |
| global scheduler_running |
|
|
| if not scheduler_running: |
| return jsonify({ |
| "status": "not_running", |
| "message": "Scheduler is not running." |
| }), 200 |
|
|
| scheduler_running = False |
| schedule.clear() |
| logging.info("Scheduler STOPPED via API.") |
| return jsonify({ |
| "status": "stopped", |
| "message": "Scheduler has been stopped." |
| }), 200 |
|
|
| @app.route("/health", methods=["GET"]) |
| def health(): |
| next_run = None |
| jobs = schedule.get_jobs() |
| if jobs: |
| next_run = str(jobs[0].next_run) |
|
|
| return jsonify({ |
| "status": "healthy", |
| "scheduler_running": scheduler_running, |
| "current_time": datetime.now().isoformat(), |
| "next_scheduled_run": next_run, |
| "last_run": last_run_status["last_run"], |
| "last_status": last_run_status["last_status"] |
| }), 200 |
|
|
| @app.route("/run-now", methods=["GET", "POST"]) |
| def run_now(): |
| threading.Thread(target=run_all_backups, daemon=True).start() |
| return jsonify({ |
| "status": "triggered", |
| "message": "Backup started in background. Check /health for status." |
| }), 200 |
|
|
| @app.route("/status", methods=["GET"]) |
| def status(): |
| return jsonify({ |
| "scheduler_running": scheduler_running, |
| "last_run": last_run_status["last_run"], |
| "last_status": last_run_status["last_status"], |
| "last_results": last_run_status["results"] |
| }), 200 |
|
|
| |
|
|
| if __name__ == "__main__": |
| |
| schedule.every(6).hours.do(run_all_backups) |
| scheduler_running = True |
| scheduler_thread = threading.Thread(target=scheduler_loop, daemon=True) |
| scheduler_thread.start() |
| logging.info("Scheduler auto-started on app launch.") |
|
|
| port = int(os.environ.get("PORT", 7860)) |
| app.run(host="0.0.0.0", port=port, debug=False) |