pythonany / app.py
nopoh22's picture
Update app.py
0472279 verified
Raw History Blame Contribute Delete
3.85 kB
import os
import threading
import time
import logging
from datetime import datetime
from fastapi import FastAPI
from fastapi.responses import HTMLResponse, JSONResponse
import uvicorn
from keep_alive import start_ping_server
from renewer import load_accounts, save_accounts, renew_account, run_renewals
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s')
logger = logging.getLogger(__name__)
app = FastAPI()
SCHEDULER_RUNNING = False
SCHEDULER_THREAD = None
LOG_LINES = []
def add_log(msg):
ts = datetime.utcnow().strftime("%H:%M:%S")
LOG_LINES.append(f"[{ts}] {msg}")
if len(LOG_LINES) > 200:
LOG_LINES.pop(0)
logger.info(msg)
HTML = open("index.html", encoding="utf-8").read()
@app.get("/", response_class=HTMLResponse)
async def index():
return HTML
@app.get("/api/accounts")
async def get_accounts():
accounts = load_accounts()
# لا نُرجع كلمة المرور أبداً
safe = []
for a in accounts:
safe.append({
"username": a["username"],
"host": a.get("host", "—"),
"last_renewed": a.get("last_renewed"),
"next_renewal": a.get("next_renewal"),
"last_results": a.get("last_results", []),
})
return safe
@app.post("/api/renew")
async def renew_all():
add_log("🚀 بدء تجديد جميع الحسابات...")
def do():
accs = run_renewals()
if accs:
for a in accs:
for r in (a.get("last_results") or []):
add_log(f" [{a['username']}] {r['domain']} → {r['status']}")
add_log("✅ انتهى التجديد.")
threading.Thread(target=do, daemon=True).start()
return {"ok": True}
@app.post("/api/renew/{username}")
async def renew_one(username: str):
accounts = load_accounts()
account = next((a for a in accounts if a["username"] == username), None)
if not account:
return JSONResponse({"ok": False, "message": f"⚠️ لم يُعثر على {username} في الـ Secrets"})
account["next_renewal"] = None
def do():
add_log(f"🔄 تجديد {username}...")
success, results = renew_account(account)
save_accounts(accounts)
for r in results:
add_log(f" [{username}] {r['domain']} → {r['status']}")
add_log(f"{'✅' if success else '❌'} {'تم' if success else 'فشل'} تجديد {username}")
threading.Thread(target=do, daemon=True).start()
return {"ok": True}
@app.post("/api/scheduler")
async def toggle_scheduler():
global SCHEDULER_RUNNING, SCHEDULER_THREAD
if not SCHEDULER_RUNNING:
SCHEDULER_RUNNING = True
def loop():
while SCHEDULER_RUNNING:
run_renewals()
time.sleep(3600)
SCHEDULER_THREAD = threading.Thread(target=loop, daemon=True)
SCHEDULER_THREAD.start()
add_log("⏰ المجدول التلقائي شغّال — يجدد كل 10 أيام")
else:
SCHEDULER_RUNNING = False
add_log("⏹ تم إيقاف المجدول التلقائي")
return {"running": SCHEDULER_RUNNING}
@app.get("/api/log")
async def get_log():
return {"lines": LOG_LINES[-100:]}
@app.get("/health")
async def health():
return {"status": "alive"}
if __name__ == "__main__":
start_ping_server(port=8080)
add_log("🚀 PythonAnywhere Manager started")
# عرض الحسابات المحملة عند البدء
accounts = load_accounts()
if accounts:
add_log(f"📋 تم تحميل {len(accounts)} حساب من Secrets: {[a['username'] for a in accounts]}")
else:
add_log("⚠️ لم يتم العثور على حسابات — أضف ACCOUNTS في Secrets")
uvicorn.run(app, host="0.0.0.0", port=7860)