backup / app.py
Dooratre's picture
Update app.py
c5de7ac verified
Raw
History Blame Contribute Delete
6.64 kB
from flask import Flask, jsonify
import requests
import schedule
import time
from datetime import datetime
import logging
import threading
import os
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[logging.StreamHandler()]
)
app = Flask(__name__)
# Global state
scheduler_thread = None
scheduler_running = False
last_run_status = {
"last_run": None,
"last_status": "never",
"results": {}
}
# ==================== BACKUP FUNCTIONS ====================
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
# ==================== SCHEDULER ====================
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.")
# ==================== ROUTES ====================
@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
# ==================== MAIN ====================
if __name__ == "__main__":
# Auto-start scheduler
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)