Fix Zotero save completion handling

This commit is contained in:
Mantao Huang 2026-03-09 12:21:45 -04:00
parent b4a7555104
commit f3076c52ce

View File

@ -104,8 +104,7 @@ async def save_to_zotero(url, headless_mode="new"):
else:
assert worker is not None
print("[*] Triggering save via extension service worker evaluation...")
# We wrap the call in a try/catch and return a structured object so we can extract the sessionID
session_id = await worker.evaluate('''async () => {
save_result = await worker.evaluate('''async () => {
try {
let tabs = await chrome.tabs.query({ active: true, currentWindow: true });
if (!tabs || tabs.length === 0) return {error: "No active tab found."};
@ -113,11 +112,11 @@ async def save_to_zotero(url, headless_mode="new"):
let tabInfo = Zotero.Connector_Browser.getTabInfo(tab.id);
if (tabInfo && tabInfo.translators && tabInfo.translators.length) {
await Zotero.Connector_Browser.saveWithTranslator(tab, 0, {fallbackOnFailure: true});
return { sessionID: tabInfo.instanceID }; // usually acts as sessionID
let result = await Zotero.Connector_Browser.saveWithTranslator(tab, 0, {fallbackOnFailure: true});
return { ok: true, mode: "translator", result };
} else if (tabInfo) {
await Zotero.Connector_Browser.saveAsWebpage(tab, tabInfo.frameId, { snapshot: true });
return { sessionID: tabInfo.instanceID };
let result = await Zotero.Connector_Browser.saveAsWebpage(tab, tabInfo.frameId, { snapshot: true });
return { ok: true, mode: "webpage", result };
} else {
return {error: "No translator or webpage saving options available."};
}
@ -126,33 +125,14 @@ async def save_to_zotero(url, headless_mode="new"):
}
}''')
if not session_id or "error" in session_id:
print(f"[!] Save trigger failed: {session_id.get('error') if session_id else 'Unknown error'}")
if not save_result or "error" in save_result:
print(f"[!] Save trigger failed: {save_result.get('error') if save_result else 'Unknown error'}")
else:
sid = session_id.get("sessionID")
print(f"[*] Save triggered (Session ID: {sid}). Polling for progress...")
# Poll for completion
max_polls = 60
for _ in range(max_polls):
await asyncio.sleep(1)
progress = await worker.evaluate('''async (sid) => {
try {
if (!Zotero.Connector) return {done: false, error: "Zotero.Connector uninitialized"};
let res = await Zotero.Connector.callMethod("sessionProgress", { sessionID: sid });
return res || {done: false};
} catch(e) {
return {done: true, error: e.message}; // typically throws when it's totally done/cleaned up
}
}''', sid)
if progress and progress.get("error"):
# Normally, when the progress tracker cleans up, callMethod("sessionProgress") throws
print(f"[*] Save completed or session ended. Error: {progress.get('error')}")
break
if progress and progress.get("done"):
print("[*] Translation and save processes finished successfully.")
break
save_mode = save_result.get("mode", "unknown")
returned = save_result.get("result")
print(f"[*] Save completed successfully via {save_mode}.")
if returned is not None:
print(f"[*] Save returned: {returned}")
print("[*] Operation finished. Closing browser.")
await browser_context.close()