Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -39,11 +39,12 @@ def save_data(data):
|
|
| 39 |
|
| 40 |
def format_df(source_list, saved_list):
|
| 41 |
if not source_list:
|
|
|
|
| 42 |
return pd.DataFrame(columns=["狀態", "姓名", "大學", "系所", "標籤"])
|
| 43 |
-
|
| 44 |
-
# 如果 saved_list 是 None,就用 [] 代替
|
| 45 |
if saved_list is None:
|
| 46 |
-
saved_list = []
|
|
|
|
| 47 |
saved_map = {get_key(p): p for p in saved_list}
|
| 48 |
|
| 49 |
data = []
|
|
@@ -81,6 +82,7 @@ def search_professors(query, current_saved):
|
|
| 81 |
|
| 82 |
try:
|
| 83 |
results = gemini_service.search_professors(query)
|
|
|
|
| 84 |
return format_df(results, current_saved), results, gr.update(visible=True)
|
| 85 |
except Exception as e:
|
| 86 |
raise gr.Error(f"搜尋失敗: {e}")
|
|
@@ -117,12 +119,14 @@ def select_professor_from_df(evt: gr.SelectData, search_results, saved_data, vie
|
|
| 117 |
|
| 118 |
details_md = ""
|
| 119 |
|
|
|
|
| 120 |
if current_prof.get('details') and len(current_prof.get('details')) > 10:
|
| 121 |
details_md = current_prof['details']
|
| 122 |
if not saved_prof:
|
| 123 |
saved_data.insert(0, current_prof)
|
| 124 |
save_data(saved_data)
|
| 125 |
else:
|
|
|
|
| 126 |
gr.Info(f"正在調查 {current_prof['name']}...")
|
| 127 |
try:
|
| 128 |
res = gemini_service.get_professor_details(current_prof)
|
|
@@ -262,29 +266,37 @@ def remove_prof(selected_prof, saved_data, view_mode, search_results):
|
|
| 262 |
|
| 263 |
def toggle_view(mode, search_res, saved_data):
|
| 264 |
if mode == "搜尋結果":
|
|
|
|
| 265 |
return format_df(search_res, saved_data), gr.update(visible=True)
|
| 266 |
else:
|
|
|
|
| 267 |
return format_df(saved_data, saved_data), gr.update(visible=False)
|
| 268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 269 |
# --- UI Layout ---
|
| 270 |
|
| 271 |
-
# 🌟 這裡修正了標題,加入 Prof.404
|
| 272 |
with gr.Blocks(title="Prof.404 開箱教授去哪兒?", theme=gr.themes.Soft()) as demo:
|
| 273 |
|
| 274 |
-
#
|
| 275 |
-
|
|
|
|
|
|
|
| 276 |
search_res_state = gr.State([])
|
| 277 |
selected_prof_state = gr.State(None)
|
| 278 |
|
| 279 |
-
#
|
| 280 |
-
gr.Markdown("# Prof.404 🎓 開箱教授去哪兒? (請自行 Fork 使用)")
|
| 281 |
|
| 282 |
with gr.Row():
|
| 283 |
search_input = gr.Textbox(label="搜尋研究領域", placeholder="例如: 大型語言模型, 後量子密碼遷移...", scale=4)
|
| 284 |
search_btn = gr.Button("🔍 搜尋", variant="primary", scale=1)
|
| 285 |
|
|
|
|
| 286 |
with gr.Row():
|
| 287 |
-
view_radio = gr.Radio(["搜尋結果", "追蹤清單"], label="顯示模式", value="
|
| 288 |
|
| 289 |
with gr.Row():
|
| 290 |
# Left: List
|
|
@@ -330,10 +342,16 @@ with gr.Blocks(title="Prof.404 開箱教授去哪兒?", theme=gr.themes.Soft()
|
|
| 330 |
|
| 331 |
# --- Wiring ---
|
| 332 |
|
|
|
|
|
|
|
|
|
|
| 333 |
search_btn.click(
|
| 334 |
search_professors,
|
| 335 |
inputs=[search_input, saved_state],
|
| 336 |
outputs=[prof_df, search_res_state, load_more_btn]
|
|
|
|
|
|
|
|
|
|
| 337 |
)
|
| 338 |
|
| 339 |
load_more_btn.click(
|
|
|
|
| 39 |
|
| 40 |
def format_df(source_list, saved_list):
|
| 41 |
if not source_list:
|
| 42 |
+
# 如果沒有來源資料,回傳空表格
|
| 43 |
return pd.DataFrame(columns=["狀態", "姓名", "大學", "系所", "標籤"])
|
| 44 |
+
|
|
|
|
| 45 |
if saved_list is None:
|
| 46 |
+
saved_list = []
|
| 47 |
+
|
| 48 |
saved_map = {get_key(p): p for p in saved_list}
|
| 49 |
|
| 50 |
data = []
|
|
|
|
| 82 |
|
| 83 |
try:
|
| 84 |
results = gemini_service.search_professors(query)
|
| 85 |
+
# 搜尋時,顯示搜尋結果
|
| 86 |
return format_df(results, current_saved), results, gr.update(visible=True)
|
| 87 |
except Exception as e:
|
| 88 |
raise gr.Error(f"搜尋失敗: {e}")
|
|
|
|
| 119 |
|
| 120 |
details_md = ""
|
| 121 |
|
| 122 |
+
# Check if details are cached
|
| 123 |
if current_prof.get('details') and len(current_prof.get('details')) > 10:
|
| 124 |
details_md = current_prof['details']
|
| 125 |
if not saved_prof:
|
| 126 |
saved_data.insert(0, current_prof)
|
| 127 |
save_data(saved_data)
|
| 128 |
else:
|
| 129 |
+
# Call API
|
| 130 |
gr.Info(f"正在調查 {current_prof['name']}...")
|
| 131 |
try:
|
| 132 |
res = gemini_service.get_professor_details(current_prof)
|
|
|
|
| 266 |
|
| 267 |
def toggle_view(mode, search_res, saved_data):
|
| 268 |
if mode == "搜尋結果":
|
| 269 |
+
# 如果是搜尋結果,傳入搜尋結果清單
|
| 270 |
return format_df(search_res, saved_data), gr.update(visible=True)
|
| 271 |
else:
|
| 272 |
+
# 如果是追蹤清單,傳入追蹤清單
|
| 273 |
return format_df(saved_data, saved_data), gr.update(visible=False)
|
| 274 |
|
| 275 |
+
# 新增這個函式,用來在網頁載入時初始化畫面
|
| 276 |
+
def init_on_load(saved_data):
|
| 277 |
+
# 預設顯示追蹤清單,這樣使用者一重新整理就能看到資料
|
| 278 |
+
return format_df(saved_data, saved_data)
|
| 279 |
+
|
| 280 |
# --- UI Layout ---
|
| 281 |
|
|
|
|
| 282 |
with gr.Blocks(title="Prof.404 開箱教授去哪兒?", theme=gr.themes.Soft()) as demo:
|
| 283 |
|
| 284 |
+
# 🌟 修正點1: 把 load_data() 的括號拿掉,傳入函式本身
|
| 285 |
+
# 這樣每次重新整理網頁時,都會重新執行 load_data,讀取最新的檔案
|
| 286 |
+
saved_state = gr.State(load_data)
|
| 287 |
+
|
| 288 |
search_res_state = gr.State([])
|
| 289 |
selected_prof_state = gr.State(None)
|
| 290 |
|
| 291 |
+
gr.Markdown("# Prof.404 🎓 開箱教授去哪兒? (Gradio Edition)")
|
|
|
|
| 292 |
|
| 293 |
with gr.Row():
|
| 294 |
search_input = gr.Textbox(label="搜尋研究領域", placeholder="例如: 大型語言模型, 後量子密碼遷移...", scale=4)
|
| 295 |
search_btn = gr.Button("🔍 搜尋", variant="primary", scale=1)
|
| 296 |
|
| 297 |
+
# 🌟 修正點2: 預設選取 "追蹤清單",讓使用者一進來就看到存檔
|
| 298 |
with gr.Row():
|
| 299 |
+
view_radio = gr.Radio(["搜尋結果", "追蹤清單"], label="顯示模式", value="追蹤清單")
|
| 300 |
|
| 301 |
with gr.Row():
|
| 302 |
# Left: List
|
|
|
|
| 342 |
|
| 343 |
# --- Wiring ---
|
| 344 |
|
| 345 |
+
# 🌟 修正點3: 網頁載入時(Load),自動把 saved_state 的內容顯示到 prof_df 上
|
| 346 |
+
demo.load(init_on_load, inputs=[saved_state], outputs=[prof_df])
|
| 347 |
+
|
| 348 |
search_btn.click(
|
| 349 |
search_professors,
|
| 350 |
inputs=[search_input, saved_state],
|
| 351 |
outputs=[prof_df, search_res_state, load_more_btn]
|
| 352 |
+
).then(
|
| 353 |
+
# 搜尋後自動切換到 "搜尋結果" tab
|
| 354 |
+
lambda: gr.update(value="搜尋結果"), outputs=[view_radio]
|
| 355 |
)
|
| 356 |
|
| 357 |
load_more_btn.click(
|