diff --git a/services/kdocs_uploader.py b/services/kdocs_uploader.py index 02b6440..8bd0724 100644 --- a/services/kdocs_uploader.py +++ b/services/kdocs_uploader.py @@ -202,6 +202,7 @@ class KDocsUploader: def _open_document(self, doc_url: str, *, fast: bool = False) -> bool: try: self._doc_url = doc_url + self._ensure_clipboard_permissions(doc_url) if fast: doc_pages = self._find_doc_pages(doc_url) if doc_pages: @@ -232,6 +233,18 @@ class KDocsUploader: self._last_error = f"打开文档失败: {e}" return False + def _ensure_clipboard_permissions(self, doc_url: str) -> None: + if not self._context or not doc_url: + return + try: + parsed = urlparse(doc_url) + if not parsed.scheme or not parsed.netloc: + return + origin = f"{parsed.scheme}://{parsed.netloc}" + self._context.grant_permissions(["clipboard-read", "clipboard-write"], origin=origin) + except Exception: + return + def _normalize_doc_url(self, url: str) -> str: if not url: return "" @@ -953,38 +966,70 @@ class KDocsUploader: continue def _get_current_cell_address(self) -> str: - name_box = self._page.locator('#root input[type="text"]').first - return name_box.input_value() + try: + name_box = self._page.locator("input.edit-box").first + return name_box.input_value() + except Exception: + name_box = self._page.locator('#root input[type="text"]').first + return name_box.input_value() def _navigate_to_cell(self, cell_address: str) -> None: - name_box = self._page.locator('#root input[type="text"]').first - name_box.click() - name_box.fill(cell_address) - name_box.press("Enter") + try: + name_box = self._page.locator("input.edit-box").first + name_box.click() + name_box.fill(cell_address) + name_box.press("Enter") + except Exception: + name_box = self._page.locator('#root input[type="text"]').first + name_box.click() + name_box.fill(cell_address) + name_box.press("Enter") time.sleep(0.3) + def _focus_grid(self) -> None: + try: + info = self._page.evaluate( + """() => { + const canvases = Array.from(document.querySelectorAll("canvas")); + let best = null; + for (const c of canvases) { + const rect = c.getBoundingClientRect(); + if (!rect.width || !rect.height) continue; + if (rect.width < 200 || rect.height < 200) continue; + const area = rect.width * rect.height; + if (!best || area > best.area) { + best = {x: rect.left + rect.width / 2, y: rect.top + rect.height / 2, area}; + } + } + return best; + }""" + ) + if info and info.get("x") and info.get("y"): + self._page.mouse.click(info["x"], info["y"]) + time.sleep(0.1) + except Exception: + pass + + def _read_clipboard_text(self) -> str: + try: + return self._page.evaluate("() => navigator.clipboard.readText()") or "" + except Exception: + return "" + def _get_cell_value(self, cell_address: str) -> str: self._navigate_to_cell(cell_address) time.sleep(0.3) try: - formula_bar = self._page.locator('input[type="text"]').nth(1) - value = formula_bar.input_value() - if value: - return value.strip() + self._page.evaluate("() => navigator.clipboard.writeText('')") except Exception: pass + self._focus_grid() try: - formula_inputs = self._page.locator('textbox') - for i in range(formula_inputs.count()): - try: - value = formula_inputs.nth(i).input_value() - if value: - import re - - if not re.match(r"^[A-Z]+\d+$", value.strip()): - return value.strip() - except Exception: - continue + self._page.keyboard.press("Control+c") + time.sleep(0.2) + value = self._read_clipboard_text() + if value: + return value.strip() except Exception: pass return "" @@ -1020,6 +1065,7 @@ class KDocsUploader: return True def _search_person(self, name: str) -> None: + self._focus_grid() self._page.keyboard.press("Control+f") time.sleep(0.3) search_input = None