Fix JSON key casing mismatch
Browse files
app.py
CHANGED
|
@@ -125,7 +125,7 @@ footer { display: none !important; }
|
|
| 125 |
|
| 126 |
def get_default_data_dir():
|
| 127 |
# 如果在 Space 环境,优先使用当前目录下的 cache_data 文件夹,避免 /root 权限问题
|
| 128 |
-
if os.environ.get("SPACE_ID"):
|
| 129 |
return str(Path.cwd() / "cache_data")
|
| 130 |
|
| 131 |
custom_dir = os.environ.get("HF_NOTES_DATA_DIR")
|
|
@@ -153,16 +153,25 @@ def read_notes():
|
|
| 153 |
valid_notes = []
|
| 154 |
for item in data:
|
| 155 |
if not isinstance(item, dict): continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
valid_notes.append({
|
| 157 |
-
"id": str(
|
| 158 |
-
"title": str(
|
| 159 |
-
"content": str(
|
| 160 |
-
"updated_at": str(
|
| 161 |
-
"is_pinned": bool(
|
| 162 |
-
"is_deleted": bool(
|
| 163 |
})
|
| 164 |
return valid_notes
|
| 165 |
-
except Exception
|
|
|
|
| 166 |
return []
|
| 167 |
|
| 168 |
def write_notes(notes):
|
|
@@ -179,7 +188,8 @@ class CloudSync:
|
|
| 179 |
|
| 180 |
def pull(self):
|
| 181 |
try:
|
| 182 |
-
ensure_local_notes()
|
|
|
|
| 183 |
downloaded_path = hf_hub_download(
|
| 184 |
repo_id=DATASET_REPO_ID,
|
| 185 |
filename=REMOTE_NOTES_PATH,
|
|
@@ -191,7 +201,12 @@ class CloudSync:
|
|
| 191 |
shutil.copy(downloaded_path, LOCAL_NOTES_PATH)
|
| 192 |
return True, f"✅ 云端拉取同步完成"
|
| 193 |
except Exception as e:
|
| 194 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
|
| 196 |
def push(self):
|
| 197 |
ensure_local_notes()
|
|
@@ -301,6 +316,7 @@ def handle_pin(note_id, current_filter):
|
|
| 301 |
n["is_pinned"] = not n.get("is_pinned", False)
|
| 302 |
break
|
| 303 |
write_notes(notes)
|
|
|
|
| 304 |
return load_notes_list(current_filter)
|
| 305 |
|
| 306 |
# --- Gradio UI ---
|
|
@@ -355,6 +371,7 @@ with gr.Blocks(theme=gr.themes.Default(), head=PWA_HEAD) as demo:
|
|
| 355 |
|
| 356 |
search_box.change(load_notes_list, [current_filter_state, search_box], [note_list])
|
| 357 |
|
|
|
|
| 358 |
edit_title.blur(handle_save, [selected_note_id, edit_title, edit_content], [status_text, note_list, selected_note_id])
|
| 359 |
edit_content.blur(handle_save, [selected_note_id, edit_title, edit_content], [status_text, note_list, selected_note_id])
|
| 360 |
|
|
@@ -369,6 +386,7 @@ with gr.Blocks(theme=gr.themes.Default(), head=PWA_HEAD) as demo:
|
|
| 369 |
return f"✨ [AI 润色已模拟完成]\n\n{content}\n\n(请在本地动作中使用完整的 DeepSeek 润色服务)"
|
| 370 |
btn_ai.click(ai_polish, [edit_content], [edit_content])
|
| 371 |
|
|
|
|
| 372 |
demo.load(lambda: (sync_manager.pull()[1], load_notes_list()), None, [status_text, note_list])
|
| 373 |
|
| 374 |
if __name__ == "__main__":
|
|
|
|
| 125 |
|
| 126 |
def get_default_data_dir():
|
| 127 |
# 如果在 Space 环境,优先使用当前目录下的 cache_data 文件夹,避免 /root 权限问题
|
| 128 |
+
if os.environ.get("SPACE_ID") or os.environ.get("HF_SPACE"):
|
| 129 |
return str(Path.cwd() / "cache_data")
|
| 130 |
|
| 131 |
custom_dir = os.environ.get("HF_NOTES_DATA_DIR")
|
|
|
|
| 153 |
valid_notes = []
|
| 154 |
for item in data:
|
| 155 |
if not isinstance(item, dict): continue
|
| 156 |
+
# 关键修复:同时支持 C# 风格 (Uppercase) 和 Python 风格 (Lowercase) 的键名
|
| 157 |
+
n_id = item.get("Id") or item.get("id", "")
|
| 158 |
+
n_title = item.get("Title") or item.get("title", "")
|
| 159 |
+
n_content = item.get("Content") or item.get("content", "")
|
| 160 |
+
n_updated = item.get("UpdatedAt") or item.get("updated_at", "")
|
| 161 |
+
n_pinned = item.get("IsPinned") if "IsPinned" in item else item.get("is_pinned", False)
|
| 162 |
+
n_deleted = item.get("IsDeleted") if "IsDeleted" in item else item.get("is_deleted", False)
|
| 163 |
+
|
| 164 |
valid_notes.append({
|
| 165 |
+
"id": str(n_id),
|
| 166 |
+
"title": str(n_title),
|
| 167 |
+
"content": str(n_content),
|
| 168 |
+
"updated_at": str(n_updated),
|
| 169 |
+
"is_pinned": bool(n_pinned),
|
| 170 |
+
"is_deleted": bool(n_deleted)
|
| 171 |
})
|
| 172 |
return valid_notes
|
| 173 |
+
except Exception as e:
|
| 174 |
+
print(f"读取笔记失败: {e}")
|
| 175 |
return []
|
| 176 |
|
| 177 |
def write_notes(notes):
|
|
|
|
| 188 |
|
| 189 |
def pull(self):
|
| 190 |
try:
|
| 191 |
+
ensure_local_notes()
|
| 192 |
+
print(f"🔄 正在从 Dataset {DATASET_REPO_ID} 拉取 {REMOTE_NOTES_PATH}...")
|
| 193 |
downloaded_path = hf_hub_download(
|
| 194 |
repo_id=DATASET_REPO_ID,
|
| 195 |
filename=REMOTE_NOTES_PATH,
|
|
|
|
| 201 |
shutil.copy(downloaded_path, LOCAL_NOTES_PATH)
|
| 202 |
return True, f"✅ 云端拉取同步完成"
|
| 203 |
except Exception as e:
|
| 204 |
+
msg = str(e)
|
| 205 |
+
print(f"拉取失败详情: {msg}")
|
| 206 |
+
# 如果是 401/404,通常是 Token 没设或权限问题
|
| 207 |
+
if "401" in msg or "404" in msg:
|
| 208 |
+
return False, f"⚠️ 拉取失败: 请检查 Space 的 HF_TOKEN 是否已正确配置 (Dataset 可能为私有)"
|
| 209 |
+
return False, f"⚠️ 拉取失败: {msg}"
|
| 210 |
|
| 211 |
def push(self):
|
| 212 |
ensure_local_notes()
|
|
|
|
| 316 |
n["is_pinned"] = not n.get("is_pinned", False)
|
| 317 |
break
|
| 318 |
write_notes(notes)
|
| 319 |
+
backup_msg = sync_manager.push()[1]
|
| 320 |
return load_notes_list(current_filter)
|
| 321 |
|
| 322 |
# --- Gradio UI ---
|
|
|
|
| 371 |
|
| 372 |
search_box.change(load_notes_list, [current_filter_state, search_box], [note_list])
|
| 373 |
|
| 374 |
+
# 离开焦点时保存
|
| 375 |
edit_title.blur(handle_save, [selected_note_id, edit_title, edit_content], [status_text, note_list, selected_note_id])
|
| 376 |
edit_content.blur(handle_save, [selected_note_id, edit_title, edit_content], [status_text, note_list, selected_note_id])
|
| 377 |
|
|
|
|
| 386 |
return f"✨ [AI 润色已模拟完成]\n\n{content}\n\n(请在本地动作中使用完整的 DeepSeek 润色服务)"
|
| 387 |
btn_ai.click(ai_polish, [edit_content], [edit_content])
|
| 388 |
|
| 389 |
+
# 启动拉取
|
| 390 |
demo.load(lambda: (sync_manager.pull()[1], load_notes_list()), None, [status_text, note_list])
|
| 391 |
|
| 392 |
if __name__ == "__main__":
|