import gradio as gr import sys import os import importlib.util from pathlib import Path from huggingface_hub import hf_hub_download print("===== Application Startup =====") MODEL_REPO = "fcu52005505/X281-weights" MODEL_FILE = "core_logic.so" CACHE_DIR = Path("./model_cache") CACHE_DIR.mkdir(exist_ok=True) core_logic = None # 檢查 HF Token HF_TOKEN = os.getenv("HF_TOKEN") if HF_TOKEN is None: raise RuntimeError( "❌ 缺少 HF_TOKEN!請在 Space 的 Settings → Variables and secrets 設定。" ) print(f"HF_TOKEN loaded: {HF_TOKEN is not None}") # 下載 .so(使用快取) so_path = CACHE_DIR / MODEL_FILE if not so_path.exists(): print(f"📥 正在從 {MODEL_REPO} 下載 {MODEL_FILE} ...") downloaded_path = hf_hub_download( repo_id=MODEL_REPO, filename=MODEL_FILE, repo_type="model", token=HF_TOKEN, local_dir=str(CACHE_DIR), local_dir_use_symlinks=False ) print(f"✅ .so 下載完成: {downloaded_path}") else: print(f"✅ 使用快取 .so: {so_path}") # 動態載入 core_logic.so try: spec = importlib.util.spec_from_file_location( "core_logic", str(so_path) ) if spec and spec.loader: core_logic = importlib.util.module_from_spec(spec) sys.modules["core_logic"] = core_logic spec.loader.exec_module(core_logic) print("✅ core_logic.so 載入成功") else: raise RuntimeError("❌ 無法建立模組規格 (Spec creation failed)") except Exception as e: print(f"❌ core_logic.so 載入發生錯誤: {e}") import traceback traceback.print_exc() core_logic = None # ========================================== def bridge_function(file_obj, zoom_level, preserve_details, progress=gr.Progress()): if core_logic is None: yield "❌ 嚴重錯誤:核心模組載入失敗 (No module named 'core_logic'),請檢查 Logs。", None return if file_obj is None: yield "❌ 請先上傳檔案", None return def update_progress(p, msg): progress(p, desc=msg) yield "🚀 檔案接收成功,處理中...", None try: result_msg, output_path = core_logic.run_conversion( file_obj.name, zoom_level, preserve_details, progress_callback=update_progress ) if "Success" in result_msg: yield f"✅ 轉換成功! ({result_msg})", output_path else: yield f"❌ {result_msg}", None except Exception as e: yield f"❌ 執行錯誤: {e}", None # ========================================== with gr.Blocks(title="GeoJSON 轉 PMTiles") as demo: gr.Markdown("## 🗺️ GeoJSON to PMTiles") with gr.Row(): with gr.Column(): input_file = gr.File(label="上傳 GeoJSON (自動開始)") with gr.Group(): zoom_slider = gr.Slider(0, 20, value=14, step=1, label="Max Zoom") preserve_checkbox = gr.Checkbox(label="強制保留細節", value=True) btn = gr.Button("開始轉換") with gr.Column(): status_box = gr.Textbox(label="狀態", value="等待中...", interactive=False) output_file = gr.File(label="下載") input_file.upload( bridge_function, [input_file, zoom_slider, preserve_checkbox], [status_box, output_file] ) btn.click( bridge_function, [input_file, zoom_slider, preserve_checkbox], [status_box, output_file] ) # ========================================== if __name__ == "__main__": demo.queue(default_concurrency_limit=10).launch(show_api=False)