papersearch 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/README.zh.md +5 -2
- package/carsi/README.md +1 -1
- package/carsi/paper_search_carsi/browser/watchdog.py +3 -3
- package/carsi/paper_search_carsi/config.py +4 -1
- package/carsi/paper_search_carsi/engine/batch.py +12 -2
- package/carsi/paper_search_carsi/engine/batch_capture.py +1 -1
- package/carsi/paper_search_carsi/engine/batch_login.py +38 -3
- package/carsi/paper_search_carsi/engine/batch_waits.py +15 -5
- package/carsi/paper_search_carsi/engine/bridge.py +1 -0
- package/carsi/paper_search_carsi/engine/supplements.py +6 -2
- package/carsi/paper_search_carsi/entitlements.py +12 -2
- package/carsi/paper_search_carsi/progress_bar.py +129 -6
- package/carsi/paper_search_carsi/user_settings.py +55 -0
- package/dist/capabilities/pdf-discovery/batch.d.ts.map +1 -1
- package/dist/capabilities/pdf-discovery/batch.js +34 -2
- package/dist/capabilities/pdf-discovery/batch.js.map +1 -1
- package/dist/capabilities/pdf-discovery/carsi/CarsiMcpClient.js +1 -1
- package/dist/infrastructure/pdf/PdfFirstPage.cjs +4 -1
- package/dist/infrastructure/pdf/PdfFirstPage.cjs.map +1 -1
- package/dist/infrastructure/pdf/PdfFirstPage.d.cts.map +1 -1
- package/package.json +1 -1
- package/skills/paper-search/references/browser-download.md +4 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ It is the open version by default: once installed it searches and downloads open
|
|
|
8
8
|
|
|
9
9
|

|
|
10
10
|

|
|
11
|
-

|
|
12
12
|
[](https://linux.do)
|
|
13
13
|
|
|
14
14
|
[How it works](#how-it-works) | [Quick start](#quick-start) | [Two ways to download](#two-ways-to-download) | [Search sources](#search-sources) | [Configuration](#configuration) | [Agent Skill](#agent-skill) | [Commands](#commands) | [Troubleshooting](#troubleshooting)
|
|
@@ -102,6 +102,7 @@ paper-search carsi status --format text
|
|
|
102
102
|
|
|
103
103
|
- Installing asks for your school (a CARSI member school, by Chinese name, English name or domain) and downloads the dedicated Camoufox browser, about 3 GB in all; on macOS, `--browser ego` uses ego lite instead, about 0.5 GB. `--skip-school` leaves the school for later.
|
|
104
104
|
- Schools sign in through CARSI (the Chinese university identity federation). When a publisher's institution list has no CARSI or no entry for your school, the program says so at once; download on campus or through your school's VPN instead.
|
|
105
|
+
- Downloads show a progress window: skip this paper, mark the journal or publisher as no access, stop the whole task, or change how long waits last (the gear at the top right). On the school's login page a paper waits up to 3 minutes by default; anywhere else (human checks, publisher pages, ...) it ends after 1 minute.
|
|
105
106
|
- `paper-search carsi update` updates the extension after a PaperSearch upgrade; `paper-search carsi uninstall` removes it (keeping the browser and the school settings by default).
|
|
106
107
|
- Windows: if PowerShell blocks `npm.ps1`, use `npm.cmd` or Command Prompt; downloads must run in a desktop session, as a browser window cannot open from SSH or a system service.
|
|
107
108
|
|
|
@@ -204,7 +205,9 @@ Some sources are subject to platform terms, institutional subscriptions or local
|
|
|
204
205
|
|
|
205
206
|
## Origins
|
|
206
207
|
|
|
207
|
-
Thanks to the [LinuxDo](https://linux.do) community, where the command-plus-Skill approach and workflow improvements came from discussion and open sharing.
|
|
208
|
+
- Thanks to the [LinuxDo](https://linux.do) community, where the command-plus-Skill approach and workflow improvements came from discussion and open sharing.
|
|
209
|
+
- [openags/paper-search-mcp](https://github.com/openags/paper-search-mcp): the project draws on its ideas, reworked into a standalone command.
|
|
210
|
+
- [Rimagination/scansci-pdf](https://github.com/Rimagination/scansci-pdf) (MIT): the institutional download backend (`carsi/`) was carved out of it, keeping only the institutional access part (CARSI and other federation sign-in, publisher site capture, session reuse, PDF capture), with publisher rules added one by one since; its copyright notice is kept in `carsi/NOTICE`.
|
|
208
211
|
|
|
209
212
|
## License
|
|
210
213
|
|
package/README.zh.md
CHANGED
|
@@ -8,7 +8,7 @@ PaperSearch 是给 AI 工具和终端用的学术文献命令 `paper-search`,
|
|
|
8
8
|
|
|
9
9
|

|
|
10
10
|

|
|
11
|
-

|
|
12
12
|
[](https://linux.do)
|
|
13
13
|
|
|
14
14
|
[整体逻辑](#整体逻辑) | [快速开始](#快速开始) | [两种下载方式](#两种下载方式) | [检索来源](#检索来源) | [配置](#配置) | [Agent Skill](#agent-skill) | [命令](#命令) | [排障](#排障)
|
|
@@ -102,6 +102,7 @@ paper-search carsi status --format text
|
|
|
102
102
|
|
|
103
103
|
- 安装时会问你的学校(CARSI 成员学校,中文名、英文名或域名都可以),并下载专用浏览器 Camoufox,共约 3 GB;macOS 上 `--browser ego` 改用 ego lite,约 0.5 GB。`--skip-school` 可以以后再选学校。
|
|
104
104
|
- 目前用 CARSI(中国高校身份联盟)登录学校;出版社的机构列表里没有 CARSI 或你的学校时,程序会立即说明,建议在校园网或学校 VPN 下下载。
|
|
105
|
+
- 下载时会出现进度窗口:可以跳过本篇、标记本刊或出版社无权限、终止整个任务,右上角齿轮可以调整等待时间。停在学校登录页默认最多等 3 分钟,停在其他页面(人机验证、出版社页面等)默认 1 分钟后结束这一篇。
|
|
105
106
|
- `paper-search carsi update` 在 PaperSearch 升级后更新扩展,`paper-search carsi uninstall` 卸载(默认保留浏览器和学校配置)。
|
|
106
107
|
- Windows:PowerShell 拦住 `npm.ps1` 时改用 `npm.cmd` 或命令提示符;下载要在桌面会话里运行,经 SSH 或系统服务启动时浏览器窗口打不开。
|
|
107
108
|
|
|
@@ -204,7 +205,9 @@ paper-search skills update --targets claude
|
|
|
204
205
|
|
|
205
206
|
## 项目来源
|
|
206
207
|
|
|
207
|
-
感谢 [LinuxDo](https://linux.do)
|
|
208
|
+
- 感谢 [LinuxDo](https://linux.do) 社区:命令 + Skill 的路线和工作流改进来自社区交流与开源分享。
|
|
209
|
+
- [openags/paper-search-mcp](https://github.com/openags/paper-search-mcp):本项目参考了它的思路,并改成独立的命令行工具。
|
|
210
|
+
- [Rimagination/scansci-pdf](https://github.com/Rimagination/scansci-pdf)(MIT):机构下载后端(`carsi/`)由它裁出,只保留机构访问这一段(CARSI 等联盟登录、出版社网站抓取、会话复用、PDF 捕获),再逐家补充出版社规则;原项目的版权声明保留在 `carsi/NOTICE`。
|
|
208
211
|
|
|
209
212
|
## License
|
|
210
213
|
|
package/carsi/README.md
CHANGED
|
@@ -23,7 +23,7 @@ python3 -m venv .venv
|
|
|
23
23
|
|
|
24
24
|
## 使用
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
等待用户操作:停在学校登录页(以及没配置学校时的选校页)每篇最多 3 分钟(配置键 `browser_login_timeout`,秒,默认 180);停在其他页面(人机验证、出版社页面、选机构页、取 PDF 时等待处理)连续超过 1 分钟就结束这一篇(`browser_page_wait_timeout`,默认 60)。两项和每家出版社每小时最多下载篇数都能在进度窗口右上角的设置(齿轮)里改。浏览器某一步 90 秒没有响应时,这一篇以 `browser_unresponsive` 结束。进度窗口的按钮:跳过本篇、本刊无权限、出版社无权限、终止任务(整批停下,剩余篇目记为 `batch_stopped`)、⚑ 报告问题。
|
|
27
27
|
|
|
28
28
|
浏览器调用超过 4 分钟没有返回时,后端会取消它并把这一篇记为 `browser_unresponsive`(日志里记下是哪个调用、从哪里调用),批量继续下一篇。后端一直停着不动(CPU 为 0、进度不再更新)时,`kill -USR1 <后端进程号>` 会把它所有线程的 Python 调用栈追加到 `<数据目录>/logs/stacks-<日期>.txt`,用来看它在等哪个浏览器调用;进程不会因此退出。
|
|
29
29
|
|
|
@@ -28,9 +28,9 @@ from typing import Any
|
|
|
28
28
|
|
|
29
29
|
log = logging.getLogger(__name__)
|
|
30
30
|
|
|
31
|
-
# The longest legitimate call is a page load
|
|
32
|
-
# the user are made of short calls.
|
|
33
|
-
LIMIT_SEC =
|
|
31
|
+
# The longest legitimate call is a page load (60 s, the engine's longest
|
|
32
|
+
# timeout); waits for the user are made of short calls.
|
|
33
|
+
LIMIT_SEC = 90
|
|
34
34
|
|
|
35
35
|
_inflight: dict[int, tuple[float, str, list[str], Any, Any]] = {}
|
|
36
36
|
_installed = False
|
|
@@ -100,8 +100,11 @@ DEFAULT_CONFIG: dict[str, Any] = {
|
|
|
100
100
|
"fast_retry_delay_sec": 15,
|
|
101
101
|
# 任务启动时自动弹出悬浮进度条(独立进程,已有实例则不重复弹出)。
|
|
102
102
|
"progress_bar_auto": True,
|
|
103
|
-
#
|
|
103
|
+
# 每篇文章在学校登录页等待用户输入的总时长上限,秒;从第一次等待算起。
|
|
104
104
|
"browser_login_timeout": 180,
|
|
105
|
+
# 不在学校登录页时(出版社页面、选机构页、人机验证、取 PDF 时等待处理)最多等多久,秒;
|
|
106
|
+
# 连续超过就结束这一篇。进度窗口里可以改。
|
|
107
|
+
"browser_page_wait_timeout": 60,
|
|
105
108
|
# 每个出版社每小时最多打开的文章数,防止学校因下载过多被出版社暂停访问;0 = 不限。
|
|
106
109
|
"publisher_hourly_limit": 100,
|
|
107
110
|
# Turnstile 交互门(如 sci-hub.vg):无头会话下无法点击,默认跳过并冷却。
|
|
@@ -86,7 +86,7 @@ from .batch_pdf_urls import PdfUrlsMixin
|
|
|
86
86
|
from .batch_runs import RunsMixin
|
|
87
87
|
from .batch_diagnostics import DiagnosticsMixin
|
|
88
88
|
from .batch_user import PdfFoundWhileWaiting, UserProvidedPdf, UserRequestsMixin
|
|
89
|
-
from ..entitlements import UserSkippedArticle
|
|
89
|
+
from ..entitlements import UserSkippedArticle, UserStoppedBatch
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
class PublisherBatchDownloader(
|
|
@@ -153,6 +153,7 @@ class PublisherBatchDownloader(
|
|
|
153
153
|
from . import supplements
|
|
154
154
|
|
|
155
155
|
self._phase(result, "supplements")
|
|
156
|
+
progress_reporter.update(part="supplements", supplements_saved=0, supplements_total=None)
|
|
156
157
|
try:
|
|
157
158
|
page = context.new_page()
|
|
158
159
|
except Exception as exc:
|
|
@@ -185,8 +186,10 @@ class PublisherBatchDownloader(
|
|
|
185
186
|
if links or url in own_page:
|
|
186
187
|
break
|
|
187
188
|
self._event(result, "supplements_found", str(len(links)))
|
|
189
|
+
progress_reporter.update(supplements_total=len(links))
|
|
188
190
|
files = supplements.collect(page.context.request, links, Path(output_dir), doi,
|
|
189
|
-
download=lambda url: self._download_in_new_tab(page, url)
|
|
191
|
+
download=lambda url: self._download_in_new_tab(page, url),
|
|
192
|
+
progress=lambda saved: progress_reporter.update(supplements_saved=saved))
|
|
190
193
|
saved = sum(1 for f in files if f.get("status") == "saved")
|
|
191
194
|
self._event(result, "supplements_saved", f"{saved}/{len(files)}")
|
|
192
195
|
return files
|
|
@@ -346,6 +349,7 @@ class PublisherBatchDownloader(
|
|
|
346
349
|
from ..browser import watchdog
|
|
347
350
|
|
|
348
351
|
self._phase(result, "open")
|
|
352
|
+
progress_reporter.update(part="main", supplements_saved=0, supplements_total=None)
|
|
349
353
|
self._run_dir = run_dir
|
|
350
354
|
watchdog.on_slow_call = lambda name, seconds, ended, where: self._event(
|
|
351
355
|
result, "wait", f"browser call {name}: {seconds:.0f} s, ended: {ended} ({where})")
|
|
@@ -512,6 +516,12 @@ class PublisherBatchDownloader(
|
|
|
512
516
|
self._event(result, "pdf_found_while_waiting" if isinstance(provided, PdfFoundWhileWaiting)
|
|
513
517
|
else "pdf_from_user_report", provided.url)
|
|
514
518
|
return self._save_captured_pdf(page, record, result, run_dir, provided.body, provided.url)
|
|
519
|
+
except UserStoppedBatch as decision:
|
|
520
|
+
watchdog.clear_interrupt()
|
|
521
|
+
result.reason = result.state = "batch_stopped"
|
|
522
|
+
self._event(result, "batch_stopped", str(decision))
|
|
523
|
+
self._write_diagnostic(page, result, run_dir)
|
|
524
|
+
return result
|
|
515
525
|
except UserSkippedArticle as decision:
|
|
516
526
|
watchdog.clear_interrupt()
|
|
517
527
|
result.reason = result.state = "user_skipped"
|
|
@@ -1256,7 +1256,7 @@ class CaptureMixin:
|
|
|
1256
1256
|
# Human verification gets its own budget: the user's time must
|
|
1257
1257
|
# not use up the PDF step, and once the check clears the PDF
|
|
1258
1258
|
# gets its full time again.
|
|
1259
|
-
challenge_deadline = time.time() + max(self.
|
|
1259
|
+
challenge_deadline = time.time() + max(self.page_wait_sec, timeout_sec)
|
|
1260
1260
|
if not self._wait_for_challenge_with_deadline(page, result, challenge_deadline):
|
|
1261
1261
|
return None, str(getattr(page, "url", "") or "")
|
|
1262
1262
|
deadline = time.time() + timeout_sec
|
|
@@ -260,6 +260,7 @@ class LoginMixin:
|
|
|
260
260
|
last_auto_action_at = 0.0
|
|
261
261
|
visited_idp = False
|
|
262
262
|
page_since, page_inputs = time.time(), ()
|
|
263
|
+
outside_since = time.time() # last seen on the user's own login step
|
|
263
264
|
article_returns = 0
|
|
264
265
|
session_returns = 0
|
|
265
266
|
away_from_publisher = False # on an IdP, federation or chooser page since the last probe
|
|
@@ -273,6 +274,14 @@ class LoginMixin:
|
|
|
273
274
|
result.reason = "institution_federation_unavailable"
|
|
274
275
|
self._event(result, result.reason, "the school is not in the publisher's institution list")
|
|
275
276
|
return False
|
|
277
|
+
over, outside_since = self._page_wait_over(page, outside_since)
|
|
278
|
+
if over:
|
|
279
|
+
# Off the school's login page for a whole page wait (a publisher
|
|
280
|
+
# page, a chooser, a redirect that goes nowhere): nobody is typing.
|
|
281
|
+
self._event(result, "page_wait_ended",
|
|
282
|
+
f"{self._login_wait_page(page)} after {self.page_wait_sec:.0f} s")
|
|
283
|
+
self._wait_ran_out(result)
|
|
284
|
+
return False
|
|
276
285
|
marker = f"{self._title(page)} | {getattr(page, 'url', '')[:160]}"
|
|
277
286
|
here = urlparse(str(getattr(page, "url", "") or ""))
|
|
278
287
|
on_publisher = self._on_publisher_host(here.geturl())
|
|
@@ -1143,6 +1152,26 @@ class LoginMixin:
|
|
|
1143
1152
|
return True
|
|
1144
1153
|
return self.adapter.is_article_page_url(url) is True
|
|
1145
1154
|
|
|
1155
|
+
def _page_wait_over(self, page: Any, outside_since: float) -> tuple[bool, float]:
|
|
1156
|
+
"""Whether a login wait has been off the user's own login step for a whole
|
|
1157
|
+
page wait, and when that step was last seen (now, when on it)."""
|
|
1158
|
+
now = time.time()
|
|
1159
|
+
if self._users_login_step(page):
|
|
1160
|
+
return False, now
|
|
1161
|
+
return now - outside_since >= self.page_wait_sec, outside_since
|
|
1162
|
+
|
|
1163
|
+
def _users_login_step(self, page: Any) -> bool:
|
|
1164
|
+
"""The user's own step of the login, which may take the long wait
|
|
1165
|
+
(``login_timeout_sec``): the school's login page (a password field, or the
|
|
1166
|
+
school's identity provider), or a school chooser when no school is
|
|
1167
|
+
configured or the user chooses by hand. Any other page off the publisher's
|
|
1168
|
+
site is not: Atypon's iam.atypon.com hub, where AHA's login stopped on
|
|
1169
|
+
2026-11-03, was taken for the school's page and waited three minutes."""
|
|
1170
|
+
url = str(getattr(page, "url", "") or "")
|
|
1171
|
+
if self._school_password_box(page, url) or self._is_idp_host(urlparse(url).netloc):
|
|
1172
|
+
return True
|
|
1173
|
+
return self._is_auth_page(url) and (not self.institution_query or bool(getattr(self, "_manual_school", False)))
|
|
1174
|
+
|
|
1146
1175
|
def _login_wait_page(self, page: Any) -> str:
|
|
1147
1176
|
"""Where a login that waited on the user ended (ADR 0012):
|
|
1148
1177
|
|
|
@@ -1155,7 +1184,9 @@ class LoginMixin:
|
|
|
1155
1184
|
if page.is_closed() is True:
|
|
1156
1185
|
return "closed"
|
|
1157
1186
|
url = str(getattr(page, "url", "") or "")
|
|
1158
|
-
|
|
1187
|
+
# The school's own page, by the same test as the long wait: a publisher's
|
|
1188
|
+
# SSO hub (iam.atypon.com) is no school login (2026-11-03).
|
|
1189
|
+
if self._school_password_box(page, url) or self._is_idp_host(urlparse(url).netloc):
|
|
1159
1190
|
return "school_login"
|
|
1160
1191
|
if self._is_auth_page(url):
|
|
1161
1192
|
return "institution_chooser" if self.institution_query else "school_choice"
|
|
@@ -1165,13 +1196,17 @@ class LoginMixin:
|
|
|
1165
1196
|
current_url = str(getattr(page, "url", "") or "")
|
|
1166
1197
|
host = (urlparse(current_url).netloc or "").lower()
|
|
1167
1198
|
if self.config.get("publisher_institution_federation") == "carsi":
|
|
1168
|
-
if (page
|
|
1169
|
-
and not self._personal_login_box(page, current_url)):
|
|
1199
|
+
if self._school_password_box(page, current_url):
|
|
1170
1200
|
return True
|
|
1171
1201
|
if not self._on_publisher_host(current_url):
|
|
1172
1202
|
return not self._is_federation_chooser(current_url)
|
|
1173
1203
|
return self._is_idp_host(host)
|
|
1174
1204
|
|
|
1205
|
+
def _school_password_box(self, page: Any, url: str) -> bool:
|
|
1206
|
+
"""A password or one-time-code field that is not a personal account's box on the publisher's site."""
|
|
1207
|
+
return bool(page.locator('input[type="password"]:visible, input[autocomplete="one-time-code"]:visible').count()
|
|
1208
|
+
and not self._personal_login_box(page, url))
|
|
1209
|
+
|
|
1175
1210
|
def _personal_login_box(self, page: Any, url: str) -> bool:
|
|
1176
1211
|
"""The password field is a personal account's login box on the publisher's
|
|
1177
1212
|
own article page, nobody typing in it: BMJ shows one next to "Log in via
|
|
@@ -35,7 +35,16 @@ class UserWaitMixin:
|
|
|
35
35
|
return self._wait_for_challenge(page, result, deadline=deadline)
|
|
36
36
|
return self._wait_for_challenge(page, result)
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
# A wait off the school's login page (verification, the publisher's pages and
|
|
39
|
+
# choosers, the PDF step): config ``browser_page_wait_timeout``, else this.
|
|
40
|
+
PAGE_WAIT_SEC = 60
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def page_wait_sec(self) -> float:
|
|
44
|
+
"""How long a wait that is not the user's own login step may last; the
|
|
45
|
+
school's login page has ``login_timeout_sec`` (user's choice, 2026-11-03)."""
|
|
46
|
+
value = (getattr(self, "config", None) or {}).get("browser_page_wait_timeout")
|
|
47
|
+
return self.PAGE_WAIT_SEC if value is None else max(10.0, float(value))
|
|
39
48
|
|
|
40
49
|
@staticmethod
|
|
41
50
|
def _visible_text_excerpt(body: str | bytes | None, limit: int = 600) -> str:
|
|
@@ -103,7 +112,7 @@ class UserWaitMixin:
|
|
|
103
112
|
|
|
104
113
|
def _wait_out_suspect_block(self, page: Any, result: DownloadResult, captured: dict[str, Any], suspect: str,
|
|
105
114
|
suspect_host: str, started: float) -> bool:
|
|
106
|
-
deadline = started +
|
|
115
|
+
deadline = started + self.page_wait_sec
|
|
107
116
|
reporter = None
|
|
108
117
|
attention_key = f"pdf-step:{id(self)}:{result.doi}"
|
|
109
118
|
try:
|
|
@@ -302,9 +311,10 @@ class UserWaitMixin:
|
|
|
302
311
|
return deadline
|
|
303
312
|
|
|
304
313
|
def _wait_deadline(self, result: DownloadResult, deadline: float | None = None) -> float:
|
|
305
|
-
"""End of a wait on the user that starts now
|
|
306
|
-
|
|
307
|
-
|
|
314
|
+
"""End of a wait on the user that starts now, off the school's login page
|
|
315
|
+
(verification pages): the caller's bound, the article's total, the page
|
|
316
|
+
wait, and when the user seems away the short wait."""
|
|
317
|
+
bounds = [self._user_wait_deadline(result), time.time() + self.page_wait_sec]
|
|
308
318
|
if deadline is not None:
|
|
309
319
|
bounds.append(deadline)
|
|
310
320
|
if self._user_away:
|
|
@@ -45,6 +45,7 @@ _FAILURE_KINDS = {
|
|
|
45
45
|
"unexpected_error": ("source_exception", ""),
|
|
46
46
|
"user_marked_no_entitlement": ("no_entitlement", "skipped_by_user"),
|
|
47
47
|
"user_skipped": ("user_skipped", "skipped_by_user"),
|
|
48
|
+
"batch_stopped": ("batch_stopped", "stopped_by_user"),
|
|
48
49
|
"pdf_wrong_article": ("pdf_wrong_article", "review_browser"),
|
|
49
50
|
"supplements_only": ("supplements_only", "supplements_only"),
|
|
50
51
|
# The DOI resolves to no site to sign in on (publishers/site.py): no driver can run.
|
|
@@ -87,12 +87,14 @@ def _get(request: Any, url: str, entry: dict[str, Any], sleep) -> Any:
|
|
|
87
87
|
|
|
88
88
|
def collect(request: Any, links: Iterable[SupplementLink], output_dir: Path, doi: str, *,
|
|
89
89
|
clock=time.monotonic, sleep=time.sleep,
|
|
90
|
-
download: Callable[[str], tuple[bytes, str]] | None = None
|
|
90
|
+
download: Callable[[str], tuple[bytes, str]] | None = None,
|
|
91
|
+
progress: Callable[[int], None] | None = None) -> list[dict[str, Any]]:
|
|
91
92
|
"""Fetch ``links`` with ``request`` (a Playwright APIRequestContext). A file
|
|
92
93
|
refused with 403 is taken through ``download`` when given: the browser
|
|
93
94
|
opens it and downloads it itself (Taylor & Francis behind Cloudflare
|
|
94
95
|
refused every scripted request with ego, the page's own fetch included,
|
|
95
|
-
and let the browser's own navigation through, 2026-11-01).
|
|
96
|
+
and let the browser's own navigation through, 2026-11-01). ``progress`` is
|
|
97
|
+
told how many files are saved after each one (the progress window)."""
|
|
96
98
|
unique: list[SupplementLink] = []
|
|
97
99
|
for link in links:
|
|
98
100
|
if link.url and link.url not in {u.url for u in unique}:
|
|
@@ -139,6 +141,8 @@ def collect(request: Any, links: Iterable[SupplementLink], output_dir: Path, doi
|
|
|
139
141
|
except Exception as exc:
|
|
140
142
|
entry.update(status="failed", reason=f"{type(exc).__name__}: {str(exc)[:160]}")
|
|
141
143
|
files.append(entry)
|
|
144
|
+
if progress is not None:
|
|
145
|
+
progress(sum(1 for f in files if f.get("status") == "saved"))
|
|
142
146
|
(target / "manifest.json").write_text(
|
|
143
147
|
json.dumps({"doi": doi, "files": files}, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
144
148
|
return files
|
|
@@ -34,6 +34,14 @@ class UserSkippedArticle(UserMarkedNoEntitlement):
|
|
|
34
34
|
"""The user pressed "skip this paper": it ends, nothing is remembered."""
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
class UserStoppedBatch(UserMarkedNoEntitlement):
|
|
38
|
+
"""The user pressed "stop the task": this paper ends and the batch stops."""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# Not an entitlement decision: nothing is recorded, the batch ends.
|
|
42
|
+
STOP_BATCH = "stop_batch"
|
|
43
|
+
|
|
44
|
+
|
|
37
45
|
SKIP = "skip"
|
|
38
46
|
ALLOW = "allow"
|
|
39
47
|
_ACTIONS = {
|
|
@@ -183,7 +191,7 @@ def clear(key: str) -> bool:
|
|
|
183
191
|
|
|
184
192
|
def request_action(current: str, action: str, run_id: str = "") -> None:
|
|
185
193
|
"""Written by the progress window when the user presses a button."""
|
|
186
|
-
if action not in _ACTIONS:
|
|
194
|
+
if action not in _ACTIONS and action != STOP_BATCH:
|
|
187
195
|
raise ValueError("unknown action")
|
|
188
196
|
_write_json(control_path(), {"current": current, "action": action, "run_id": run_id, "at": time.time()})
|
|
189
197
|
|
|
@@ -204,7 +212,7 @@ def take_action(doi: str, since: float) -> str | None:
|
|
|
204
212
|
except OSError:
|
|
205
213
|
pass
|
|
206
214
|
action = data.get("action")
|
|
207
|
-
return action if action in _ACTIONS else None
|
|
215
|
+
return action if action in _ACTIONS or action == STOP_BATCH else None
|
|
208
216
|
|
|
209
217
|
|
|
210
218
|
def apply_user_decision(doi: str, publisher: str, since: float) -> str | None:
|
|
@@ -212,6 +220,8 @@ def apply_user_decision(doi: str, publisher: str, since: float) -> str | None:
|
|
|
212
220
|
action = take_action(doi, since)
|
|
213
221
|
if not action:
|
|
214
222
|
return None
|
|
223
|
+
if action == STOP_BATCH:
|
|
224
|
+
raise UserStoppedBatch(action)
|
|
215
225
|
if action == "skip_item":
|
|
216
226
|
raise UserSkippedArticle(action)
|
|
217
227
|
try:
|
|
@@ -29,6 +29,7 @@ from typing import Any
|
|
|
29
29
|
import os as _os
|
|
30
30
|
import sys as _sys
|
|
31
31
|
|
|
32
|
+
from . import user_settings
|
|
32
33
|
from .progress_reporter import read_state
|
|
33
34
|
|
|
34
35
|
# --- Win32 / DWM constants -------------------------------------------------
|
|
@@ -43,6 +44,13 @@ DWMSBT_MAINWINDOW = 2 # light Mica
|
|
|
43
44
|
|
|
44
45
|
# Palettes: (light, dark). Picked once at start from the OS appearance.
|
|
45
46
|
CONTENT_LABELS = {"main": "正文", "supplements": "附录", "both": "正文+附录"}
|
|
47
|
+
# The step of the main text, as the status line says it ("正文 · 正在获取 PDF").
|
|
48
|
+
STAGE_TEXT = {
|
|
49
|
+
"starting": "准备中", "opening_article": "正在打开文章", "checking_access": "正在检查访问权限",
|
|
50
|
+
"waiting_login": "等待机构登录", "waiting_verification": "等待人机验证", "fetching_pdf": "正在获取 PDF",
|
|
51
|
+
"pdf_captured": "已读到 PDF,正在核对", "saved_pending_verification": "已保存",
|
|
52
|
+
"route_failed": "这条路没走通,正在换路",
|
|
53
|
+
}
|
|
46
54
|
|
|
47
55
|
PALETTES = {
|
|
48
56
|
"light": {
|
|
@@ -232,6 +240,8 @@ class ProgressWindow:
|
|
|
232
240
|
self._flash: tuple[str, float, str] | None = None # (text, until, doi)
|
|
233
241
|
self._chosen: tuple[str, str] | None = None # (doi, action) pressed for the current paper
|
|
234
242
|
self._hover = "" # the button under the mouse; kept across redraws
|
|
243
|
+
self._settings: tk.Toplevel | None = None # the settings dialog, when open
|
|
244
|
+
self._last_current = "" # the paper shown, for a message after the dialog closes
|
|
235
245
|
self.root.after(400, self._tick)
|
|
236
246
|
|
|
237
247
|
# --- window plumbing ---------------------------------------------------
|
|
@@ -294,6 +304,7 @@ class ProgressWindow:
|
|
|
294
304
|
self.f_count = tkfont.Font(family=ui, size=px(14), weight="bold")
|
|
295
305
|
self.f_body = tkfont.Font(family=ui, size=px(12))
|
|
296
306
|
self.f_small = tkfont.Font(family=ui, size=px(11))
|
|
307
|
+
self.f_gear = tkfont.Font(family=ui, size=px(15))
|
|
297
308
|
self.f_mono = tkfont.Font(family=mono, size=px(11))
|
|
298
309
|
|
|
299
310
|
def _anchor_x(self) -> int:
|
|
@@ -351,6 +362,21 @@ class ProgressWindow:
|
|
|
351
362
|
return _fmt_elapsed((end - started).total_seconds())
|
|
352
363
|
return _fmt_elapsed((datetime.now() - started).total_seconds())
|
|
353
364
|
|
|
365
|
+
@staticmethod
|
|
366
|
+
def _status_text(state: dict[str, Any], running: bool) -> str:
|
|
367
|
+
"""The status line: which part of the paper is being fetched and how far,
|
|
368
|
+
"正文 · 正在获取 PDF" or "附录 · 已保存 2/5"; between papers, the phase."""
|
|
369
|
+
phase = str(state.get("phase") or ("处理中" if running else ""))
|
|
370
|
+
part = str(state.get("part") or "")
|
|
371
|
+
if not running or state.get("awaiting_next") or part not in ("main", "supplements"):
|
|
372
|
+
return phase
|
|
373
|
+
if part == "supplements":
|
|
374
|
+
total = state.get("supplements_total")
|
|
375
|
+
if not isinstance(total, int):
|
|
376
|
+
return "附录 · 正在查找附录文件"
|
|
377
|
+
return f"附录 · 已保存 {int(state.get('supplements_saved') or 0)}/{total}"
|
|
378
|
+
return "正文 · " + STAGE_TEXT.get(str(state.get("stage") or ""), phase)
|
|
379
|
+
|
|
354
380
|
@staticmethod
|
|
355
381
|
def _attention_items(state: dict[str, Any]) -> list[dict[str, Any]]:
|
|
356
382
|
attention = state.get("attention")
|
|
@@ -370,7 +396,9 @@ class ProgressWindow:
|
|
|
370
396
|
Hl = max(self.H, c.winfo_height())
|
|
371
397
|
u = lambda n: int(round(n * s))
|
|
372
398
|
|
|
399
|
+
gear_left = self._draw_gear(Wl - P, P + u(9))
|
|
373
400
|
if not state:
|
|
401
|
+
self._last_current = ""
|
|
374
402
|
c.create_text(Wl // 2, Hl // 2 - u(8), text="PaperSearch", fill=col["text"], font=self.f_title)
|
|
375
403
|
c.create_text(Wl // 2, Hl // 2 + u(14), text="暂无下载任务", fill=col["dim"], font=self.f_small)
|
|
376
404
|
return
|
|
@@ -401,8 +429,8 @@ class ProgressWindow:
|
|
|
401
429
|
dot = u(8)
|
|
402
430
|
c.create_oval(P, y1 - dot // 2, P + dot, y1 + dot // 2, fill=tone, outline=tone)
|
|
403
431
|
count = f"{done} / {total}" if total else f"{done}"
|
|
404
|
-
c.create_text(
|
|
405
|
-
count_w = self.f_count.measure(count)
|
|
432
|
+
c.create_text(gear_left - u(8), y1, text=count, fill=col["text"], font=self.f_count, anchor="e")
|
|
433
|
+
count_w = self.f_count.measure(count) + (Wl - P - gear_left) + u(8)
|
|
406
434
|
# What this download fetches, as a small label left of the count.
|
|
407
435
|
content = CONTENT_LABELS.get(str(state.get("content") or "main"), CONTENT_LABELS["main"])
|
|
408
436
|
chip_h = u(18)
|
|
@@ -440,13 +468,14 @@ class ProgressWindow:
|
|
|
440
468
|
self._pill(P - u(2), y2 - u(11), P + self.f_body.measure(text) + u(14), y2 + u(11), col["warn_bg"])
|
|
441
469
|
c.create_text(P + u(6), y2, text=text, fill=col["warn"], font=self.f_body, anchor="w")
|
|
442
470
|
else:
|
|
443
|
-
phase =
|
|
471
|
+
phase = self._status_text(state, running)
|
|
444
472
|
c.create_text(P, y2, anchor="w", fill=col["dim"], font=self.f_body,
|
|
445
473
|
text=_elide(self.f_body, phase, phase_room))
|
|
446
474
|
|
|
447
475
|
# Row 3: the paper being worked on
|
|
448
476
|
y3 = y2 + u(22)
|
|
449
477
|
current = str((attention[-1].get("current") if attention else "") or state.get("current") or "")
|
|
478
|
+
self._last_current = current
|
|
450
479
|
if current:
|
|
451
480
|
c.create_text(P, y3, anchor="w", fill=col["text"] if running else col["dim"], font=self.f_mono,
|
|
452
481
|
text=_elide(self.f_mono, current, Wl - 2 * P))
|
|
@@ -484,7 +513,7 @@ class ProgressWindow:
|
|
|
484
513
|
x = P
|
|
485
514
|
chosen = self._chosen[1] if self._chosen and self._chosen[0] == current else ""
|
|
486
515
|
for key, label in (("skip_item", "跳过本篇"), ("skip_journal", "本刊无权限"),
|
|
487
|
-
("skip_publisher", "出版社无权限")):
|
|
516
|
+
("skip_publisher", "出版社无权限"), ("stop_batch", "终止任务")):
|
|
488
517
|
pressed = key == chosen
|
|
489
518
|
text = ("✓ " + label) if pressed else label
|
|
490
519
|
w = self.f_small.measure(text) + u(18)
|
|
@@ -492,7 +521,8 @@ class ProgressWindow:
|
|
|
492
521
|
self._pill(x, y6 - u(11), x + w, y6 + u(11), col["warn"] if pressed else col["track"], tags=(tag,))
|
|
493
522
|
fill = col["bg"] if pressed else (col["text"] if self._hover == key else col["btn"])
|
|
494
523
|
label_id = c.create_text(x + w / 2, y6, text=text, fill=fill, font=self.f_small, tags=(tag,))
|
|
495
|
-
c.tag_bind(tag, "<Button-1>", lambda e, k=key, d=current, s=state:
|
|
524
|
+
c.tag_bind(tag, "<Button-1>", lambda e, k=key, d=current, s=state: (
|
|
525
|
+
self._stop(d, s) if k == "stop_batch" else self._decide(k, d, s)))
|
|
496
526
|
if not pressed:
|
|
497
527
|
c.tag_bind(tag, "<Enter>", lambda e, k=key, i=label_id: self._hover_button(k, i))
|
|
498
528
|
c.tag_bind(tag, "<Leave>", lambda e, i=label_id: self._hover_button("", i))
|
|
@@ -516,7 +546,8 @@ class ProgressWindow:
|
|
|
516
546
|
from .entitlements import request_action
|
|
517
547
|
|
|
518
548
|
request_action(doi, action, str(state.get("run_id") or ""))
|
|
519
|
-
text = {"
|
|
549
|
+
text = {"stop_batch": "已终止任务:这一篇结束,剩下的不再下载",
|
|
550
|
+
"skip_item": "已跳过本篇,进入下一篇",
|
|
520
551
|
"skip_journal": "已记住:本刊无权限,以后自动跳过(可用 entitlements 撤销)",
|
|
521
552
|
"skip_publisher": "已记住:该出版社无权限,以后自动跳过"}[action]
|
|
522
553
|
except Exception as exc:
|
|
@@ -525,6 +556,98 @@ class ProgressWindow:
|
|
|
525
556
|
self._chosen = (doi, action)
|
|
526
557
|
self._draw(state)
|
|
527
558
|
|
|
559
|
+
def _stop(self, doi: str, state: dict[str, Any]) -> None:
|
|
560
|
+
"""Stop the whole task, after asking: this paper ends, the rest are not downloaded."""
|
|
561
|
+
from tkinter import messagebox
|
|
562
|
+
|
|
563
|
+
left = max(0, int(state.get("total", 0) or 0) - int(state.get("done", 0) or 0) - 1)
|
|
564
|
+
question = "终止整个下载任务?这一篇立即结束" + (f",剩下的 {left} 篇不再下载。" if left else "。")
|
|
565
|
+
if messagebox.askyesno("终止任务", question, parent=self.root):
|
|
566
|
+
self._decide("stop_batch", doi, state)
|
|
567
|
+
|
|
568
|
+
def _draw_gear(self, right: int, y: int) -> int:
|
|
569
|
+
"""The settings button at the top right, a round button like the others'
|
|
570
|
+
colours; returns its left edge."""
|
|
571
|
+
c, col = self.canvas, self.c
|
|
572
|
+
d = int(round(24 * self.s))
|
|
573
|
+
x0, y0 = right - d, y - d // 2
|
|
574
|
+
c.create_oval(x0, y0, right, y0 + d, fill=col["track"], outline=col["track"], tags=("settings",))
|
|
575
|
+
item = c.create_text(right - d / 2, y, text="\u2699", fill=col["btn"], font=self.f_gear, tags=("settings",))
|
|
576
|
+
c.tag_bind("settings", "<Button-1>", lambda e: self._open_settings())
|
|
577
|
+
c.tag_bind("settings", "<Enter>", lambda e: c.itemconfigure(item, fill=col["text"]))
|
|
578
|
+
c.tag_bind("settings", "<Leave>", lambda e: c.itemconfigure(item, fill=col["btn"]))
|
|
579
|
+
return x0
|
|
580
|
+
|
|
581
|
+
def _open_settings(self) -> None:
|
|
582
|
+
"""The settings dialog: each value typed in and checked; saved values
|
|
583
|
+
apply from the next paper."""
|
|
584
|
+
if self._settings is not None and self._settings.winfo_exists():
|
|
585
|
+
self._settings.lift()
|
|
586
|
+
return
|
|
587
|
+
col, pad = self.c, int(round(14 * self.s))
|
|
588
|
+
top = self._settings = tk.Toplevel(self.root, bg=col["bg"])
|
|
589
|
+
top.title("设置")
|
|
590
|
+
top.resizable(False, False)
|
|
591
|
+
top.attributes("-topmost", True)
|
|
592
|
+
top.transient(self.root)
|
|
593
|
+
frame = tk.Frame(top, bg=col["bg"], padx=pad, pady=pad)
|
|
594
|
+
frame.pack(fill="both", expand=True)
|
|
595
|
+
tk.Label(frame, text="设置", bg=col["bg"], fg=col["text"], font=self.f_title).grid(
|
|
596
|
+
row=0, column=0, columnspan=3, sticky="w", pady=(0, pad // 2))
|
|
597
|
+
values = user_settings.current()
|
|
598
|
+
entries: dict[str, tk.Entry] = {}
|
|
599
|
+
errors: dict[str, tk.Label] = {}
|
|
600
|
+
for i, field in enumerate(user_settings.FIELDS):
|
|
601
|
+
row = 1 + 2 * i
|
|
602
|
+
tk.Label(frame, text=field.label, bg=col["bg"], fg=col["text"], font=self.f_body).grid(
|
|
603
|
+
row=row, column=0, sticky="w", padx=(0, pad))
|
|
604
|
+
entry = tk.Entry(frame, width=6, justify="right", font=self.f_body)
|
|
605
|
+
entry.insert(0, str(values[field.name]))
|
|
606
|
+
entry.grid(row=row, column=1, pady=3)
|
|
607
|
+
tk.Label(frame, text=field.unit, bg=col["bg"], fg=col["dim"], font=self.f_body).grid(
|
|
608
|
+
row=row, column=2, sticky="w", padx=(6, 0))
|
|
609
|
+
error = tk.Label(frame, text="", bg=col["bg"], fg=col["bad"], font=self.f_small)
|
|
610
|
+
error.grid(row=row + 1, column=0, columnspan=3, sticky="w")
|
|
611
|
+
error.grid_remove()
|
|
612
|
+
entries[field.name], errors[field.name] = entry, error
|
|
613
|
+
|
|
614
|
+
def reset() -> None:
|
|
615
|
+
for field in user_settings.FIELDS:
|
|
616
|
+
entries[field.name].delete(0, "end")
|
|
617
|
+
entries[field.name].insert(0, str(field.default))
|
|
618
|
+
errors[field.name].grid_remove()
|
|
619
|
+
|
|
620
|
+
def save() -> None:
|
|
621
|
+
chosen: dict[str, int] = {}
|
|
622
|
+
for field in user_settings.FIELDS:
|
|
623
|
+
value, problem = user_settings.check(field, entries[field.name].get())
|
|
624
|
+
if problem:
|
|
625
|
+
errors[field.name].configure(text=problem)
|
|
626
|
+
errors[field.name].grid()
|
|
627
|
+
else:
|
|
628
|
+
errors[field.name].grid_remove()
|
|
629
|
+
chosen[field.name] = int(value)
|
|
630
|
+
if len(chosen) < len(user_settings.FIELDS):
|
|
631
|
+
return
|
|
632
|
+
try:
|
|
633
|
+
user_settings.save(chosen)
|
|
634
|
+
text = "设置已保存,从下一篇起生效"
|
|
635
|
+
except Exception as exc:
|
|
636
|
+
text = f"保存失败:{type(exc).__name__}"
|
|
637
|
+
top.destroy()
|
|
638
|
+
self._flash = (text, time.time() + 6, self._last_current)
|
|
639
|
+
|
|
640
|
+
buttons = tk.Frame(frame, bg=col["bg"])
|
|
641
|
+
buttons.grid(row=1 + 2 * len(user_settings.FIELDS), column=0, columnspan=3, sticky="e", pady=(pad // 2, 0))
|
|
642
|
+
for text, command in (("恢复默认", reset), ("取消", top.destroy), ("保存", save)):
|
|
643
|
+
tk.Button(buttons, text=text, command=command, font=self.f_small).pack(side="left", padx=(6, 0))
|
|
644
|
+
top.bind("<Return>", lambda e: save())
|
|
645
|
+
top.bind("<Escape>", lambda e: top.destroy())
|
|
646
|
+
top.update_idletasks()
|
|
647
|
+
x = self.root.winfo_rootx()
|
|
648
|
+
y = max(0, self.root.winfo_rooty() - top.winfo_height() - 8)
|
|
649
|
+
top.geometry(f"+{x}+{y}")
|
|
650
|
+
|
|
528
651
|
def _hover_button(self, key: str, label_id: int) -> None:
|
|
529
652
|
self._hover = key
|
|
530
653
|
self.canvas.itemconfigure(label_id, fill=self.c["text"] if key else self.c["btn"])
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""The settings the progress window lets the user type in: how long a download
|
|
2
|
+
waits on the school's login page and elsewhere, and how many papers each
|
|
3
|
+
publisher may open per hour. They apply from the next paper."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from . import config as _config
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class Field:
|
|
14
|
+
name: str
|
|
15
|
+
label: str
|
|
16
|
+
key: str # the backend's config key
|
|
17
|
+
default: int
|
|
18
|
+
low: int
|
|
19
|
+
high: int
|
|
20
|
+
unit: str
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
FIELDS = (
|
|
24
|
+
Field("login", "学校登录页最多等", "browser_login_timeout", 180, 30, 1800, "秒"),
|
|
25
|
+
Field("page", "其他页面最多等", "browser_page_wait_timeout", 60, 10, 600, "秒"),
|
|
26
|
+
Field("hourly", "每家出版社每小时最多", "publisher_hourly_limit", 100, 0, 1000, "篇"),
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def current() -> dict[str, int]:
|
|
31
|
+
"""The values now set, by field name."""
|
|
32
|
+
config = _config.load_config()
|
|
33
|
+
return {field.name: int(config.get(field.key, field.default)) for field in FIELDS}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def check(field: Field, text: str) -> tuple[int | None, str]:
|
|
37
|
+
"""A typed value, or why it cannot be saved."""
|
|
38
|
+
try:
|
|
39
|
+
value = int(str(text).strip())
|
|
40
|
+
except ValueError:
|
|
41
|
+
value = None
|
|
42
|
+
if value is None or not field.low <= value <= field.high:
|
|
43
|
+
return None, f"请输入 {field.low} 到 {field.high} 之间的整数"
|
|
44
|
+
return value, ""
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def save(values: dict[str, int]) -> None:
|
|
48
|
+
"""Save values by field name; each is checked again first."""
|
|
49
|
+
for field in FIELDS:
|
|
50
|
+
if field.name not in values:
|
|
51
|
+
continue
|
|
52
|
+
value, problem = check(field, str(values[field.name]))
|
|
53
|
+
if problem:
|
|
54
|
+
raise ValueError(f"{field.key}: {problem}")
|
|
55
|
+
_config.update_config(field.key, str(value))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../../src/capabilities/pdf-discovery/batch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,UAAU,GAAG,eAAe,CAAC;AAE3E,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,uBACf,SAAQ,IAAI,CAAC,0BAA0B,EAAE,QAAQ,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,IAAI,EAAE,iBAAiB,CAAC;IACxB,8DAA8D;IAC9D,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,KAAK,EAAE,uBAAuB,EAAE,CAAC;CAClC;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,2BAA2B,GAAG;IAAE,KAAK,EAAE,qBAAqB,CAAA;CAAE,EACvE,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,0BAA0B,CAAC,CAIrC;AAgDD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,2BAA2B,EACpC,OAAO,EAAE,YAAY,GAAG,SAAS,GAChC,OAAO,CAAC,0BAA0B,CAAC,CAsBrC;
|
|
1
|
+
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../../src/capabilities/pdf-discovery/batch.ts"],"names":[],"mappings":"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"}
|
|
@@ -121,6 +121,15 @@ async function pastHourlyLimit(run, log, pause) {
|
|
|
121
121
|
/** The journal's site blocked the current network (state L): a protection page,
|
|
122
122
|
* or the school paused for downloading too much. The backend answers the
|
|
123
123
|
* journal's later items at once; every other item goes on (the user, 2026-11-02). */
|
|
124
|
+
/** The user pressed "终止任务" in the progress window: the batch ends after this item. */
|
|
125
|
+
function stoppedByUser(result) {
|
|
126
|
+
return result.attempts.some((attempt) => attempt.code === "batch_stopped");
|
|
127
|
+
}
|
|
128
|
+
const STOP_NOTICE = "[批量] 已在进度窗口终止任务,剩下的篇目不再下载";
|
|
129
|
+
/** The attempt recorded for an item the batch did not reach because the user stopped it. */
|
|
130
|
+
function notReached() {
|
|
131
|
+
return { stage: "entitled_access", status: "skipped", message: "已终止任务,未下载", code: "batch_stopped" };
|
|
132
|
+
}
|
|
124
133
|
function publisherBlocked(result) {
|
|
125
134
|
return (result.status !== "ok" &&
|
|
126
135
|
result.attempts.some((a) => a.stage === "entitled_access" && a.code === "access_blocked"));
|
|
@@ -244,11 +253,24 @@ async function downloadPerItem(searchers, options, backend, log, createTiers, pa
|
|
|
244
253
|
log(AWAY_NOTICE);
|
|
245
254
|
}
|
|
246
255
|
const finished = itemResult(result, index, request);
|
|
247
|
-
|
|
256
|
+
if (!stoppedByUser(result))
|
|
257
|
+
await supplementsForOpenItem(finished, recorded(request, ledger, entry), backend);
|
|
248
258
|
ledger?.item(entry, finished);
|
|
249
259
|
items.push(finished);
|
|
250
260
|
if (publisherBlocked(result))
|
|
251
261
|
log(blockedNotice(request.doi || request.paperId));
|
|
262
|
+
if (stoppedByUser(result)) {
|
|
263
|
+
for (const [rest, restItem] of options.items.entries()) {
|
|
264
|
+
if (rest <= offset)
|
|
265
|
+
continue;
|
|
266
|
+
const restRequest = itemOptions(restItem, options);
|
|
267
|
+
const restFinished = itemResult({ status: "error", attempts: [notReached()] }, rest + 1, restRequest);
|
|
268
|
+
ledger?.item(runItem(rest + 1, restRequest), restFinished);
|
|
269
|
+
items.push(restFinished);
|
|
270
|
+
}
|
|
271
|
+
log(STOP_NOTICE);
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
252
274
|
}
|
|
253
275
|
ledger?.close();
|
|
254
276
|
return summary("per_item", batchId, items, {
|
|
@@ -294,6 +316,7 @@ async function downloadTwoPhase(searchers, options, backend, log, createTiers, m
|
|
|
294
316
|
let succeeded = 0;
|
|
295
317
|
let failed = 0;
|
|
296
318
|
let away = false;
|
|
319
|
+
let stopped = false;
|
|
297
320
|
for (const [step, offset] of pending.entries()) {
|
|
298
321
|
const request = requests[offset];
|
|
299
322
|
log(`[批量] 机构下载 ${step + 1}/${remaining}:${request.doi || request.paperId}`);
|
|
@@ -316,9 +339,18 @@ async function downloadTwoPhase(searchers, options, backend, log, createTiers, m
|
|
|
316
339
|
ledger?.item(entries[offset], items[offset]);
|
|
317
340
|
if (publisherBlocked(result))
|
|
318
341
|
log(blockedNotice(request.doi || request.paperId));
|
|
342
|
+
if (stoppedByUser(result)) {
|
|
343
|
+
stopped = true;
|
|
344
|
+
for (const rest of pending.slice(step + 1)) {
|
|
345
|
+
items[rest] = itemResult({ ...items[rest], status: "error", attempts: [...items[rest].attempts, notReached()] }, rest + 1, requests[rest]);
|
|
346
|
+
ledger?.item(entries[rest], items[rest]);
|
|
347
|
+
}
|
|
348
|
+
log(STOP_NOTICE);
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
319
351
|
}
|
|
320
352
|
// Phase 3: supplementary files for the items the open stages already got.
|
|
321
|
-
if (options.content === "both") {
|
|
353
|
+
if (options.content === "both" && !stopped) {
|
|
322
354
|
const open = requests.map((_, offset) => offset).filter((offset) => !pending.includes(offset));
|
|
323
355
|
if (open.length)
|
|
324
356
|
ledger?.phase(`补充材料 ${open.length} 篇`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch.js","sourceRoot":"","sources":["../../../src/capabilities/pdf-discovery/batch.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"batch.js","sourceRoot":"","sources":["../../../src/capabilities/pdf-discovery/batch.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,7 +16,7 @@ export const CARSI_DOWNLOAD_TIMEOUT_MS = 1_200_000;
|
|
|
16
16
|
export const CARSI_CLEANUP_TIMEOUT_MS = 5_000;
|
|
17
17
|
const CARSI_BACKEND_SOURCE = "carsi";
|
|
18
18
|
// MCP clientInfo is informational only; keep in step with package.json on release.
|
|
19
|
-
const PAPER_SEARCH_MCP_CLIENT_VERSION = "0.4.
|
|
19
|
+
const PAPER_SEARCH_MCP_CLIENT_VERSION = "0.4.2";
|
|
20
20
|
const NO_BATCH_SUPPORT = {
|
|
21
21
|
downloadFields: false,
|
|
22
22
|
supplementsField: false,
|
|
@@ -5,7 +5,10 @@ const { Worker, parentPort, workerData } = require("node:worker_threads");
|
|
|
5
5
|
const { readFileSync } = require("node:fs");
|
|
6
6
|
if (workerData?.paperSearchPdfFirstPage === true) {
|
|
7
7
|
const parse = require("pdf-parse/lib/pdf-parse.js");
|
|
8
|
-
|
|
8
|
+
// A plain Uint8Array, not the Buffer: in a worker on Node 24 pdf-parse fails on
|
|
9
|
+
// a Buffer ("bad XRef entry"), and every PDF would read as unreadable.
|
|
10
|
+
const file = readFileSync(workerData.filePath);
|
|
11
|
+
parse(new Uint8Array(file.buffer, file.byteOffset, file.byteLength), { max: workerData.maxPages || 1 })
|
|
9
12
|
.then((result) => {
|
|
10
13
|
const text = typeof result.text === "string"
|
|
11
14
|
? result.text.slice(0, (workerData.maxPages || 1) > 1 ? 400000 : 50000)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PdfFirstPage.cjs","sourceRoot":"","sources":["../../../src/infrastructure/pdf/PdfFirstPage.cjs"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,6EAA6E;AAC7E,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAC1E,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AAE5C,IAAI,UAAU,EAAE,uBAAuB,KAAK,IAAI,EAAE,CAAC;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;IACpD,
|
|
1
|
+
{"version":3,"file":"PdfFirstPage.cjs","sourceRoot":"","sources":["../../../src/infrastructure/pdf/PdfFirstPage.cjs"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PdfFirstPage.d.cts","sourceRoot":"","sources":["../../../src/infrastructure/pdf/PdfFirstPage.cjs"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PdfFirstPage.d.cts","sourceRoot":"","sources":["../../../src/infrastructure/pdf/PdfFirstPage.cjs"],"names":[],"mappings":"AA+DA;;;;GAIG;AACH,+CAFW,MAAM,GAAqB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAIvF;AAED;;;;GAIG;AACH,uCAFW,MAAM,YAAmB,MAAM,GAAqB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIpF"}
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
- 只用开放来源和学校权限(不用 Sci-Hub):`download_with_fallback` / `download_batch` 设 `useSciHub=false`。只测学校权限这一步:`download_batch` 设 `"mode":"entitled_only"`。
|
|
18
18
|
- 同一个数据目录同时只跑一个下载。命令没结束时,不因窗口看似停住而重新下载或登录。
|
|
19
|
-
-
|
|
19
|
+
- 批量按顺序逐篇进行。遇到学校登录或人机验证时停在这一篇,提醒用户到下载浏览器操作。等待时限:停在学校登录页(以及没配置学校、要用户自己选学校的页面)最多 3 分钟(后端配置 `browser_login_timeout`,秒);停在其他页面(人机验证、出版社页面、选机构页、取 PDF 时等待处理)连续超过 1 分钟就结束这一篇(`browser_page_wait_timeout`)。两项都能在进度窗口右上角的设置(齿轮)里改,从下一篇起生效。学校统一认证登录一次后,其余篇目通常自动通过。一篇等满时限后(日志写“这一篇等你登录或验证已到时限”),后面每篇只等 60 秒;用户在登录框输入时照常等。
|
|
20
20
|
- 每个出版社每小时最多打开 100 篇(后端配置 `publisher_hourly_limit`,0 为不限)。到上限时批量等到可以继续再下这一篇(日志写明时间);单篇返回 `rate_limited`,稍后再试。
|
|
21
21
|
- 出版社网站拦截了当前网络(`access_blocked`,如 Cloudflare 拦截页)时这一篇结束;同一期刊 30 分钟内的其他文章直接跳过(`journal_blocked_earlier`),其他期刊照常继续。告诉用户可能是当前网络被网站防护拦截,也可能是下载过多被暂停:可换网络或稍后再试,后者请联系学校图书馆。
|
|
22
22
|
- 登录和人机验证只由用户在下载浏览器里完成;不索取账号、密码、验证码,不代替用户通过验证。
|
|
@@ -26,6 +26,9 @@
|
|
|
26
26
|
|
|
27
27
|
## 进度窗口和问题报告
|
|
28
28
|
|
|
29
|
+
- “终止任务”:确认后当前这一篇立即结束,整批停下,剩下的篇目记为 `batch_stopped`(未下载)。用户想停下整批时让他点这个,不要另外中止命令。
|
|
30
|
+
- 第二行写明正在下哪部分:“正文 · 正在获取 PDF”“附录 · 已保存 2/5”。
|
|
31
|
+
- 右上角齿轮(设置):手动输入学校登录页、其他页面的最长等待(秒)和每家出版社每小时最多下载篇数,保存后从下一篇起生效。
|
|
29
32
|
- “跳过本篇”:只结束当前这一篇。“本刊无权限”“出版社无权限”:结束这一篇并记住,以后自动跳过;查看或撤销用 `paper-search-carsi entitlements`(`list` / `clear <key>`)。点击后 1–2 秒内生效。
|
|
30
33
|
- ⚑ 报告问题:用户选择看到的问题后,后端截下页面并处理(读取已打开的 PDF、回到文章、刷新、停止自动选校),窗口显示处理结果。
|
|
31
34
|
- 发起机构下载时同时监听用户的报告(与下载相同的 `CARSI_DATA_DIR`):
|