""" 🛰️ Spy Satellite Simulator — Globe via base64 iframe """ import gradio as gr import time, threading, logging, json, os, base64 from datetime import datetime from data_fetcher import DataManager logging.basicConfig(level=logging.INFO) log = logging.getLogger("app") CESIUM_TOKEN = os.environ.get("CESIUM_TOKEN", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmMzQ3OTJjZi01NmI0LTQ2MDItOWM1MC05ZWJjNWFlMDNiZTciLCJpZCI6MTkzMzUwLCJpYXQiOjE3NzQ4ODQ1OTR9.9AvXB2qj1fxNQzll4GVfKsqQtFBtpkGV9zUAedZe_fs") dm = DataManager() # ═══ Initial fetch at startup ═══ log.info("🚀 Starting initial data fetch...") dm.fetch_all() log.info("🚀 Initial fetch complete!") # ═══ Background auto-refresh ═══ def bg_fetch(): while True: time.sleep(300) # Wait 5 min before next try: dm.fetch_all() except Exception as e: log.error(f"BG: {e}") threading.Thread(target=bg_fetch, daemon=True).start() # ═══ Globe HTML ═══ def make_globe_html(data_json): return '''
✈️ 0🚢 0⚔️ 0📰 0
LIVE
⏳ جارٍ التحميل...
✈️
🛩️
🚢
⚔️
📷
🎯
⚔️ أحداث
✈️ طيران
📰 أخبار
📡 مصادر
🛰️ Spy Satellite — Real Data
'''.replace('TOKEN_PLACEHOLDER', CESIUM_TOKEN).replace('DATA_PLACEHOLDER', data_json) # ═══ Globe as base64 iframe (GUARANTEED to work) ═══ def get_globe(): data_json = dm.to_json() html = make_globe_html(data_json) b64 = base64.b64encode(html.encode('utf-8')).decode('utf-8') return f'' def build_stats(): ss = dm.status now = datetime.now().strftime("%H:%M:%S") src_list = [ ("OpenSky Network", "✈️", ss.get("OpenSky",{}).get("c",0), ss.get("OpenSky",{}).get("s","offline")), ("AIS/DigiTraffic", "🚢", ss.get("Ships",{}).get("c",0), ss.get("Ships",{}).get("s","offline")), ("GDELT", "⚔️", ss.get("GDELT",{}).get("c",0), ss.get("GDELT",{}).get("s","offline")), ("RSS (13 مصدر)", "📰", ss.get("RSS",{}).get("c",0), ss.get("RSS",{}).get("s","offline")), ("Insecam", "📷", ss.get("Cameras",{}).get("c",0), ss.get("Cameras",{}).get("s","offline")), ] items = "" for name, icon, count, status in src_list: color = "#22c55e" if status == "online" else "#ef4444" label = "متصل ✅" if status == "online" else "خطأ ❌" items += f'''
{count}
{icon} {name}
{label}
''' return f'
{items}
🕐 {now}
' def build_log(): return "\n".join(list(dm.logs)[-30:]) or "⏳ لم يبدأ بعد" def manual_refresh(): dm.fetch_all() return get_globe(), build_stats(), build_log() CSS = """ @import url('https://fonts.googleapis.com/css2?family=Cairo:wght@400;600;700;800&display=swap'); * {font-family:'Cairo',sans-serif!important} .gradio-container {max-width:100%!important;background:#0a0e17!important;color:#e2e8f0!important;padding:8px!important} .dark {background:#0a0e17!important} .tab-nav button {background:#1a2332!important;color:#94a3b8!important;border:1px solid #2a3a4e!important;border-radius:8px!important;font-weight:700!important} .tab-nav button.selected {background:rgba(14,165,233,0.15)!important;color:#0ea5e9!important;border-color:#0ea5e9!important} .block {background:transparent!important;border:none!important} label {color:#94a3b8!important} textarea {background:#0f172a!important;color:#94a3b8!important;border:1px solid #2a3a4e!important;border-radius:8px!important;font-size:11px!important} button.primary {background:linear-gradient(135deg,#0ea5e9,#06b6d4)!important;border:none!important;font-weight:700!important;border-radius:8px!important;color:white!important} footer {display:none!important} """ with gr.Blocks(css=CSS, title="🛰️ نظام المراقبة الفضائية", theme=gr.themes.Base(primary_hue="sky", neutral_hue="slate")) as app: gr.HTML("""
🛰️

مركز رصد النزاعات — محاكي الأقمار الاصطناعية

CesiumJS 3D · OpenSky Network · AISStream · GDELT · 16 RSS · Insecam — Real APIs

LIVE
Real Data
""") stats_display = gr.HTML(value=build_stats()) refresh_btn = gr.Button("📡 تحديث من المصادر", variant="primary", size="lg") with gr.Tabs(): with gr.Tab("🌍 الكرة الأرضية ثلاثية الأبعاد"): globe_display = gr.HTML(value=get_globe()) with gr.Tab("📋 سجل التحديث"): log_display = gr.Textbox(value=build_log(), label="سجل جمع البيانات", lines=25, interactive=False) refresh_btn.click(fn=manual_refresh, outputs=[globe_display, stats_display, log_display]) if __name__ == "__main__": app.launch(server_name="0.0.0.0", server_port=7860, show_error=True)