novel-downloader 2.0.0__py3-none-any.whl → 2.0.2__py3-none-any.whl
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.
- novel_downloader/__init__.py +1 -1
- novel_downloader/cli/download.py +14 -11
- novel_downloader/cli/export.py +19 -19
- novel_downloader/cli/ui.py +35 -8
- novel_downloader/config/adapter.py +216 -153
- novel_downloader/core/__init__.py +5 -6
- novel_downloader/core/archived/deqixs/fetcher.py +1 -28
- novel_downloader/core/downloaders/__init__.py +2 -0
- novel_downloader/core/downloaders/base.py +34 -85
- novel_downloader/core/downloaders/common.py +147 -171
- novel_downloader/core/downloaders/qianbi.py +30 -64
- novel_downloader/core/downloaders/qidian.py +157 -184
- novel_downloader/core/downloaders/qqbook.py +292 -0
- novel_downloader/core/downloaders/registry.py +2 -2
- novel_downloader/core/exporters/__init__.py +2 -0
- novel_downloader/core/exporters/base.py +37 -59
- novel_downloader/core/exporters/common.py +620 -0
- novel_downloader/core/exporters/linovelib.py +47 -0
- novel_downloader/core/exporters/qidian.py +41 -12
- novel_downloader/core/exporters/qqbook.py +28 -0
- novel_downloader/core/exporters/registry.py +2 -2
- novel_downloader/core/fetchers/__init__.py +4 -2
- novel_downloader/core/fetchers/aaatxt.py +2 -22
- novel_downloader/core/fetchers/b520.py +3 -23
- novel_downloader/core/fetchers/base.py +80 -105
- novel_downloader/core/fetchers/biquyuedu.py +2 -22
- novel_downloader/core/fetchers/dxmwx.py +10 -22
- novel_downloader/core/fetchers/esjzone.py +6 -29
- novel_downloader/core/fetchers/guidaye.py +2 -22
- novel_downloader/core/fetchers/hetushu.py +9 -29
- novel_downloader/core/fetchers/i25zw.py +2 -16
- novel_downloader/core/fetchers/ixdzs8.py +2 -16
- novel_downloader/core/fetchers/jpxs123.py +2 -16
- novel_downloader/core/fetchers/lewenn.py +2 -22
- novel_downloader/core/fetchers/linovelib.py +4 -20
- novel_downloader/core/fetchers/{eightnovel.py → n8novel.py} +12 -40
- novel_downloader/core/fetchers/piaotia.py +2 -16
- novel_downloader/core/fetchers/qbtr.py +2 -16
- novel_downloader/core/fetchers/qianbi.py +1 -20
- novel_downloader/core/fetchers/qidian.py +27 -68
- novel_downloader/core/fetchers/qqbook.py +177 -0
- novel_downloader/core/fetchers/quanben5.py +9 -29
- novel_downloader/core/fetchers/rate_limiter.py +22 -53
- novel_downloader/core/fetchers/sfacg.py +3 -16
- novel_downloader/core/fetchers/shencou.py +2 -16
- novel_downloader/core/fetchers/shuhaige.py +2 -22
- novel_downloader/core/fetchers/tongrenquan.py +2 -22
- novel_downloader/core/fetchers/ttkan.py +3 -14
- novel_downloader/core/fetchers/wanbengo.py +2 -22
- novel_downloader/core/fetchers/xiaoshuowu.py +2 -16
- novel_downloader/core/fetchers/xiguashuwu.py +4 -20
- novel_downloader/core/fetchers/xs63b.py +3 -15
- novel_downloader/core/fetchers/xshbook.py +2 -22
- novel_downloader/core/fetchers/yamibo.py +4 -28
- novel_downloader/core/fetchers/yibige.py +13 -26
- novel_downloader/core/interfaces/exporter.py +19 -7
- novel_downloader/core/interfaces/fetcher.py +23 -49
- novel_downloader/core/interfaces/parser.py +2 -2
- novel_downloader/core/parsers/__init__.py +4 -2
- novel_downloader/core/parsers/b520.py +2 -2
- novel_downloader/core/parsers/base.py +5 -39
- novel_downloader/core/parsers/esjzone.py +3 -3
- novel_downloader/core/parsers/{eightnovel.py → n8novel.py} +7 -7
- novel_downloader/core/parsers/qidian.py +717 -0
- novel_downloader/core/parsers/qqbook.py +709 -0
- novel_downloader/core/parsers/xiguashuwu.py +8 -15
- novel_downloader/core/searchers/__init__.py +2 -2
- novel_downloader/core/searchers/b520.py +1 -1
- novel_downloader/core/searchers/base.py +2 -2
- novel_downloader/core/searchers/{eightnovel.py → n8novel.py} +5 -5
- novel_downloader/locales/en.json +3 -3
- novel_downloader/locales/zh.json +3 -3
- novel_downloader/models/__init__.py +2 -0
- novel_downloader/models/book.py +1 -0
- novel_downloader/models/config.py +12 -0
- novel_downloader/resources/config/settings.toml +23 -5
- novel_downloader/resources/js_scripts/expr_to_json.js +14 -0
- novel_downloader/resources/js_scripts/qidian_decrypt_node.js +21 -16
- novel_downloader/resources/js_scripts/qq_decrypt_node.js +92 -0
- novel_downloader/utils/__init__.py +0 -2
- novel_downloader/utils/chapter_storage.py +2 -3
- novel_downloader/utils/constants.py +7 -3
- novel_downloader/utils/cookies.py +32 -17
- novel_downloader/utils/crypto_utils/__init__.py +0 -6
- novel_downloader/utils/crypto_utils/aes_util.py +1 -1
- novel_downloader/utils/crypto_utils/rc4.py +40 -50
- novel_downloader/utils/epub/__init__.py +2 -3
- novel_downloader/utils/epub/builder.py +6 -6
- novel_downloader/utils/epub/constants.py +1 -6
- novel_downloader/utils/epub/documents.py +7 -7
- novel_downloader/utils/epub/models.py +8 -8
- novel_downloader/utils/epub/utils.py +10 -10
- novel_downloader/utils/file_utils/io.py +48 -73
- novel_downloader/utils/file_utils/normalize.py +1 -7
- novel_downloader/utils/file_utils/sanitize.py +4 -11
- novel_downloader/utils/fontocr/__init__.py +13 -0
- novel_downloader/utils/{fontocr.py → fontocr/core.py} +72 -61
- novel_downloader/utils/fontocr/loader.py +52 -0
- novel_downloader/utils/logger.py +80 -56
- novel_downloader/utils/network.py +16 -40
- novel_downloader/utils/node_decryptor/__init__.py +13 -0
- novel_downloader/utils/node_decryptor/decryptor.py +342 -0
- novel_downloader/{core/parsers/qidian/utils → utils/node_decryptor}/decryptor_fetcher.py +5 -6
- novel_downloader/utils/text_utils/text_cleaner.py +39 -30
- novel_downloader/utils/text_utils/truncate_utils.py +3 -14
- novel_downloader/utils/time_utils/sleep_utils.py +53 -43
- novel_downloader/web/main.py +1 -1
- novel_downloader/web/pages/download.py +1 -1
- novel_downloader/web/pages/search.py +4 -4
- novel_downloader/web/services/task_manager.py +2 -0
- {novel_downloader-2.0.0.dist-info → novel_downloader-2.0.2.dist-info}/METADATA +5 -1
- novel_downloader-2.0.2.dist-info/RECORD +203 -0
- novel_downloader/core/exporters/common/__init__.py +0 -11
- novel_downloader/core/exporters/common/epub.py +0 -198
- novel_downloader/core/exporters/common/main_exporter.py +0 -64
- novel_downloader/core/exporters/common/txt.py +0 -146
- novel_downloader/core/exporters/epub_util.py +0 -215
- novel_downloader/core/exporters/linovelib/__init__.py +0 -11
- novel_downloader/core/exporters/linovelib/epub.py +0 -349
- novel_downloader/core/exporters/linovelib/main_exporter.py +0 -66
- novel_downloader/core/exporters/linovelib/txt.py +0 -139
- novel_downloader/core/exporters/txt_util.py +0 -67
- novel_downloader/core/parsers/qidian/__init__.py +0 -10
- novel_downloader/core/parsers/qidian/book_info_parser.py +0 -89
- novel_downloader/core/parsers/qidian/chapter_encrypted.py +0 -470
- novel_downloader/core/parsers/qidian/chapter_normal.py +0 -126
- novel_downloader/core/parsers/qidian/chapter_router.py +0 -68
- novel_downloader/core/parsers/qidian/main_parser.py +0 -101
- novel_downloader/core/parsers/qidian/utils/__init__.py +0 -30
- novel_downloader/core/parsers/qidian/utils/fontmap_recover.py +0 -143
- novel_downloader/core/parsers/qidian/utils/helpers.py +0 -110
- novel_downloader/core/parsers/qidian/utils/node_decryptor.py +0 -175
- novel_downloader-2.0.0.dist-info/RECORD +0 -210
- {novel_downloader-2.0.0.dist-info → novel_downloader-2.0.2.dist-info}/WHEEL +0 -0
- {novel_downloader-2.0.0.dist-info → novel_downloader-2.0.2.dist-info}/entry_points.txt +0 -0
- {novel_downloader-2.0.0.dist-info → novel_downloader-2.0.2.dist-info}/licenses/LICENSE +0 -0
- {novel_downloader-2.0.0.dist-info → novel_downloader-2.0.2.dist-info}/top_level.txt +0 -0
@@ -15,7 +15,7 @@ _SUPPORT_SITES = {
|
|
15
15
|
"biquge": "笔趣阁 (biquge)",
|
16
16
|
"biquyuedu": "精彩小说 (biquyuedu)",
|
17
17
|
"dxmwx": "大熊猫文学网 (dxmwx)",
|
18
|
-
"
|
18
|
+
"n8novel": "无限轻小说 (n8novel)",
|
19
19
|
"esjzone": "ESJ Zone (esjzone)",
|
20
20
|
"guidaye": "名著阅读 (guidaye)",
|
21
21
|
"hetushu": "和图书 (hetushu)",
|
@@ -26,7 +26,7 @@ _SUPPORT_SITES = {
|
|
26
26
|
"aaatxt": "3A电子书",
|
27
27
|
"biquge": "笔趣阁",
|
28
28
|
"dxmwx": "大熊猫文学网",
|
29
|
-
"
|
29
|
+
"n8novel": "无限轻小说",
|
30
30
|
"esjzone": "ESJ Zone",
|
31
31
|
"hetushu": "和图书",
|
32
32
|
"i25zw": "25中文网",
|
@@ -145,9 +145,9 @@ def _build_settings_dropdown(
|
|
145
145
|
Create settings button + anchored menu with initial values from state.
|
146
146
|
|
147
147
|
Returns a tuple of getter functions:
|
148
|
-
|
149
|
-
|
150
|
-
|
148
|
+
* get_sites(): list of site keys, or None if none selected
|
149
|
+
* get_psl(): per-site limit (int)
|
150
|
+
* get_timeout(): timeout (float)
|
151
151
|
"""
|
152
152
|
site_cbs: dict[str, Any] = {}
|
153
153
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: novel-downloader
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.2
|
4
4
|
Summary: A command-line tool for downloading Chinese web novels from Qidian and similar platforms.
|
5
5
|
Author-email: Saudade Z <saudadez217@gmail.com>
|
6
6
|
License: MIT License
|
@@ -47,6 +47,7 @@ Requires-Dist: aiohttp
|
|
47
47
|
Requires-Dist: lxml
|
48
48
|
Requires-Dist: platformdirs
|
49
49
|
Provides-Extra: font-recovery
|
50
|
+
Requires-Dist: brotli; extra == "font-recovery"
|
50
51
|
Requires-Dist: numpy; extra == "font-recovery"
|
51
52
|
Requires-Dist: fonttools; extra == "font-recovery"
|
52
53
|
Requires-Dist: pillow; extra == "font-recovery"
|
@@ -122,6 +123,7 @@ novel-cli download 123456
|
|
122
123
|
|
123
124
|
* 支持站点见: [支持站点列表](https://github.com/saudadez21/novel-downloader/blob/main/docs/4-supported-sites.md)
|
124
125
|
* 更多示例见: [CLI 使用示例](https://github.com/saudadez21/novel-downloader/blob/main/docs/5-cli-usage-examples.md)
|
126
|
+
* 运行中可使用 `CTRL+C` 取消任务
|
125
127
|
|
126
128
|
### 3. 图形界面 (GUI / Web)
|
127
129
|
|
@@ -133,6 +135,8 @@ novel-web
|
|
133
135
|
# novel-web --listen public
|
134
136
|
```
|
135
137
|
|
138
|
+
* 运行中可使用 `CTRL+C` 停止服务
|
139
|
+
|
136
140
|
---
|
137
141
|
|
138
142
|
## 从源码安装 (开发版)
|
@@ -0,0 +1,203 @@
|
|
1
|
+
novel_downloader/__init__.py,sha256=WykQ4IZGl_tkfxTDIG30i3MPMwO60d_GPd06zSvR99g,218
|
2
|
+
novel_downloader/cli/__init__.py,sha256=okUd_09fBWx8lz3zx3329dIK0xNRlNQJkUzDXYoSE1U,167
|
3
|
+
novel_downloader/cli/clean.py,sha256=VaiJox75-ZuXvSDFMaiAUawEbdtuEUsnsVWZGKuirJ4,2395
|
4
|
+
novel_downloader/cli/config.py,sha256=W4-f59dK5jdlg_9XDwGIyzd6VtpyNpB9U4qcxfso8Xg,3598
|
5
|
+
novel_downloader/cli/download.py,sha256=v-__VwnrS1S8j8x7YqS6OB5b30gr_wde0Qzx6PKDjhI,7633
|
6
|
+
novel_downloader/cli/export.py,sha256=a14ng11RVboJ0aBzhQ54wS5M_rVN-B-b6XbeZwPV12o,2640
|
7
|
+
novel_downloader/cli/main.py,sha256=GKtxeumw_VvWManp52Am538jL2t7xz7yVrGIaxrvSVk,1009
|
8
|
+
novel_downloader/cli/search.py,sha256=_Ci4fa1ECiYmBZI2OZBxzwddYGIvdUyIp4AOIJiL1Ds,3641
|
9
|
+
novel_downloader/cli/ui.py,sha256=vL0FF0vqYE51cKkQUTl_6mmDpiIEhQ4RrCPYwywuJtA,4787
|
10
|
+
novel_downloader/config/__init__.py,sha256=gwaDMlcBX7Lw8Hi8dY2HxNEt9ysMhIFNhkziyjramWo,405
|
11
|
+
novel_downloader/config/adapter.py,sha256=olYPMwUxd2w5Su6h-txA42WRxLuk--QJ2g14AxPu7Kc,14380
|
12
|
+
novel_downloader/config/file_io.py,sha256=ncKk7rj07UnYYVEPR_RHS2D5igMSv8xaHySNvJQWhB8,6495
|
13
|
+
novel_downloader/core/__init__.py,sha256=oCmWj9t7CEyNfew5O25YeaMPeMvXt082jprKAPMffKk,1166
|
14
|
+
novel_downloader/core/archived/deqixs/fetcher.py,sha256=rXJf72PGpwGmRWCTDBmCPJPxVh6vaejVrUcvvr6mBhU,2557
|
15
|
+
novel_downloader/core/archived/deqixs/parser.py,sha256=udM6MYdunPVYwUNjEoBDjffHR_SsXPvv_EqsCMJJVrE,4169
|
16
|
+
novel_downloader/core/archived/deqixs/searcher.py,sha256=ezXCQ0pM8AqmTXmkzLrOSebTvHg_GouIywIE23c5hwY,2920
|
17
|
+
novel_downloader/core/archived/qidian/searcher.py,sha256=Q0-MdYfO-NrFW7rhF92lXk8EX1Gdcmp_gYzhcM06cLU,2460
|
18
|
+
novel_downloader/core/archived/wanbengo/searcher.py,sha256=RAXHENGgqGzWRop3N4_PPlRB7JdUZotQqKaA2RRrzZM,3056
|
19
|
+
novel_downloader/core/archived/xshbook/searcher.py,sha256=pfyVPl7DP_cq0mjIIyOkQPKZL-piOTO5agSSPeY4Qi4,2915
|
20
|
+
novel_downloader/core/downloaders/__init__.py,sha256=n8MQEIpD3UWDMNY6-u4tCsOWSg2TjIqgj-5AfwLI6h4,491
|
21
|
+
novel_downloader/core/downloaders/base.py,sha256=t3PzP58YLJRA6ug8LfYhxv58qHB8n5nl2EC0ureVKtU,10531
|
22
|
+
novel_downloader/core/downloaders/common.py,sha256=B-5kTuKiojPCDmx_SLUPoukdAN7r-krurxb82dqoDOY,9133
|
23
|
+
novel_downloader/core/downloaders/qianbi.py,sha256=yOK2NJNSfGsvgXnu4ktuwQeX35vkrD3LVjyVYNKU34s,11820
|
24
|
+
novel_downloader/core/downloaders/qidian.py,sha256=dK1UTaQml68koWUSjdfXD60rEhgAggQNXV1wO8i_A8U,11019
|
25
|
+
novel_downloader/core/downloaders/qqbook.py,sha256=SP-xfxtjuuqEC78xYDLWs-0_stQHpJt3uWfJDH83Jh8,10308
|
26
|
+
novel_downloader/core/downloaders/registry.py,sha256=DWCC_zQ5_Z2qAXAq4w_rOi4j83aPC_8Nlr0APqmeOxo,1902
|
27
|
+
novel_downloader/core/downloaders/signals.py,sha256=fgiSH8iRqkNqyI7pZX-hfJEOMY1KbXB1lT49eSJyHqQ,1093
|
28
|
+
novel_downloader/core/exporters/__init__.py,sha256=sPgSODCrI4edijIkcyltmgWphUv2v19eERBA3fHs8H8,490
|
29
|
+
novel_downloader/core/exporters/base.py,sha256=W6LYrJvbg9JMNQqtev1OZDuSZTSY0tMvRy20LyFTXjw,8315
|
30
|
+
novel_downloader/core/exporters/common.py,sha256=skuHohMRpqtwRxPewdXSzSxSrc_bLzmGLR-lVll3As4,21422
|
31
|
+
novel_downloader/core/exporters/linovelib.py,sha256=hTlRANVw3pQ3xnGWKQ_e5MZg6173fWHUEUEMhIP2cv4,1226
|
32
|
+
novel_downloader/core/exporters/qidian.py,sha256=w0mp0BvvchToESK-zLTcR8UWT2KQgysb0enR9y2P5rA,1824
|
33
|
+
novel_downloader/core/exporters/qqbook.py,sha256=742nlK3hfWqsEQmUiC9GPyufSakcgWS-ywTF4ycNHgk,731
|
34
|
+
novel_downloader/core/exporters/registry.py,sha256=rPWjq6TabFfWc7AtrqJ3ZY0N4ZuyAxMXXCOyJV4WcwU,1567
|
35
|
+
novel_downloader/core/fetchers/__init__.py,sha256=ppRZ1tNOTLkxwFlUm-b1rENySV2oTqQMeZZOPnGYsRw,2028
|
36
|
+
novel_downloader/core/fetchers/aaatxt.py,sha256=yRavuz6PrD28JAWLeZRFbFQ646vvLaSGh_6y7N4UETA,1768
|
37
|
+
novel_downloader/core/fetchers/b520.py,sha256=eNkZ3MMmjaygjdMX4-P_N9FoB4GkZPiAESaOds5L_gY,1800
|
38
|
+
novel_downloader/core/fetchers/base.py,sha256=BKrwUeTSqBpnP7qJpSFkIBQte9z7Lbn9l5vKWEcXjkM,12770
|
39
|
+
novel_downloader/core/fetchers/biquyuedu.py,sha256=kTfkX5cT8wXOpRjs3vxhjauzxe5ddS6nEBk5ncZv4ic,1824
|
40
|
+
novel_downloader/core/fetchers/dxmwx.py,sha256=WwQUlDjpYGQq_oQAgtG8pGDvAKre4msQw0pq2HntFfA,3023
|
41
|
+
novel_downloader/core/fetchers/esjzone.py,sha256=A1YpLGfmCMnhXCL73QZUZio59u_ZlZ5p0kP1hoB9r2M,6807
|
42
|
+
novel_downloader/core/fetchers/guidaye.py,sha256=YbaSWiD2CRxu3ZSjKdywjOxu63lreUnOLFVmvTNqiSs,1886
|
43
|
+
novel_downloader/core/fetchers/hetushu.py,sha256=VzbQtoAAi1iEFxo6Lgx5u_Wj7_H4c5wzjAm7mP7Sa04,2146
|
44
|
+
novel_downloader/core/fetchers/i25zw.py,sha256=AGT-t7tkP_y3F2bX6H0gF-4_N4lJflchbTe3_H9X-6Y,2622
|
45
|
+
novel_downloader/core/fetchers/ixdzs8.py,sha256=s3bguwtnlJXfkOell7Q5fcX-CqlrHtujStt2r_pRKAU,3066
|
46
|
+
novel_downloader/core/fetchers/jpxs123.py,sha256=SCBHE2uve9prpZd7h5_Z0Awuf6Sb9lMVHVm2No4oZbA,2656
|
47
|
+
novel_downloader/core/fetchers/lewenn.py,sha256=2NGvn8HVUQGIRn3vYQn2REJcXHs7yQrcyQ2c3EYZoQk,1808
|
48
|
+
novel_downloader/core/fetchers/linovelib.py,sha256=eh2ODbRDRI7FEo4E0uP8u5Ec-wRpWF74AyegZKwVuPw,5564
|
49
|
+
novel_downloader/core/fetchers/n8novel.py,sha256=0w1wc65bRfkC7c5XatAoeKbEMfbVT4pOsija0iecJKs,3481
|
50
|
+
novel_downloader/core/fetchers/piaotia.py,sha256=idSdaLfXwcQrWxWJeUeX31DhMsHrmk_dDtvzvpvHlOE,2756
|
51
|
+
novel_downloader/core/fetchers/qbtr.py,sha256=RXZVVHHS71w88Id20hftkeE9R3EXfG-tn7CdRG_ycHs,2630
|
52
|
+
novel_downloader/core/fetchers/qianbi.py,sha256=cby1Zx3PLomshIYNDlR-7Jxoay3V-_d-ZaKOxqNDaTQ,2637
|
53
|
+
novel_downloader/core/fetchers/qidian.py,sha256=sdNvnkk33X3tOBIEIlUiP47qYZBC2o4KGgsJN-jZ9Zw,9581
|
54
|
+
novel_downloader/core/fetchers/qqbook.py,sha256=p3goeLF-4YEoPkU3SdSxjE7xD58AxhK1SzpyuX6PkZU,5246
|
55
|
+
novel_downloader/core/fetchers/quanben5.py,sha256=pktaWblBE7pB-gWnh_s9DBM9RdDLpnl7xrqehdDmNaI,2146
|
56
|
+
novel_downloader/core/fetchers/rate_limiter.py,sha256=5h8pcVGsxcywph_DFqcMao5UnyAHseDAmP1_HZKNC3U,1552
|
57
|
+
novel_downloader/core/fetchers/registry.py,sha256=z9DDTUjc2r-Xiq3MqaPfV_3EmQBXr2TK_G8eARnblkA,1580
|
58
|
+
novel_downloader/core/fetchers/sfacg.py,sha256=xJILO3usvOVU41-XW6DqtMAdwZtNeiSDm24fQ9IkheM,4721
|
59
|
+
novel_downloader/core/fetchers/shencou.py,sha256=BDuR0zJ7AWrLcW7OwWOKxO3ySVY9x4tImWm87xqAFrs,2805
|
60
|
+
novel_downloader/core/fetchers/shuhaige.py,sha256=G5kR5xG4YY90GG59Ou9NtYEtdoNB0i8psKtH4ewbX80,1822
|
61
|
+
novel_downloader/core/fetchers/tongrenquan.py,sha256=OI9B6IhyccH2UnJ744WAwBoy_QyuQJVezfpzyCT0ktc,1898
|
62
|
+
novel_downloader/core/fetchers/ttkan.py,sha256=36ddzHAwLkKdytmCh4LjKAjnE1PzkmMuvJ4xAukHgQw,2414
|
63
|
+
novel_downloader/core/fetchers/wanbengo.py,sha256=MYpdVPqB2Dq2ZT9Glkx6un8wM9eBJiKJVTRLT3YiLAA,1812
|
64
|
+
novel_downloader/core/fetchers/xiaoshuowu.py,sha256=9_1xrlHpl7JGjC9-jIQZFOAoXYDCFHwaCx5NtTHWZ_4,2846
|
65
|
+
novel_downloader/core/fetchers/xiguashuwu.py,sha256=eZIHKZksLIL5yoer8yvhMawMug-sJvWxAuMFYtUspDs,5211
|
66
|
+
novel_downloader/core/fetchers/xs63b.py,sha256=8hoJVjsTBduPiHWQc48wxgBUIw8fqHPWWKvnwWvPX9w,4788
|
67
|
+
novel_downloader/core/fetchers/xshbook.py,sha256=BPvmnldQ6ox_7ckJBXUtY0YHikybKH0C6_dgBz_II24,1889
|
68
|
+
novel_downloader/core/fetchers/yamibo.py,sha256=mU0bnMDx1WLEEICg-tC4cubO0FXLctuOBwp16xYXf9g,6765
|
69
|
+
novel_downloader/core/fetchers/yibige.py,sha256=kAv3GTiQH6s_uHAtWor_UtT47QwSE1M8ZNdc-RhLt7Q,3172
|
70
|
+
novel_downloader/core/interfaces/__init__.py,sha256=YwDOPw_UCjuAE5u_LpUYxXjOH4X2kNMXrmUoBa5jp2Q,490
|
71
|
+
novel_downloader/core/interfaces/downloader.py,sha256=nGY2LYCCBzrKhs612L5tevGG8kJp_XfCyKvqjXEIeoI,1763
|
72
|
+
novel_downloader/core/interfaces/exporter.py,sha256=j160HjMQSobgIMlH2ULm1m1b2APgnYqSRIKX9Q4bFfo,1836
|
73
|
+
novel_downloader/core/interfaces/fetcher.py,sha256=qEgGm1fAiWYiziT81ZVJYaZxDoWDqV5W1nTcMN3Z2-4,3025
|
74
|
+
novel_downloader/core/interfaces/parser.py,sha256=B_HsE_PshnUjz-QibBpuNht6whN9gboW-k1BAsnMe6M,1317
|
75
|
+
novel_downloader/core/interfaces/searcher.py,sha256=1orneqFtwcqM5sFBKmhpWFbHk5bV7oEp0mN_77lgy6E,587
|
76
|
+
novel_downloader/core/parsers/__init__.py,sha256=4MzNhYriNPupNRO_bzEy6YAVAhqNTVKmj29n9ru1Eko,1971
|
77
|
+
novel_downloader/core/parsers/aaatxt.py,sha256=1NCrhbbpd5FUi0ybMX2LYf6Sss4pY3eDXTXk7MEkrkk,3633
|
78
|
+
novel_downloader/core/parsers/b520.py,sha256=hCQxd02Bz6-_yqAiNVpIYlA6YJ7Au0Q4EdH_6RdCK3U,3245
|
79
|
+
novel_downloader/core/parsers/base.py,sha256=g701qVIcqX8ZZ_SZXDY4rLrklzeJVVVTiYBSJCSW1WI,3737
|
80
|
+
novel_downloader/core/parsers/biquyuedu.py,sha256=IpZfL2AC0oUq5Gx8iqwTH8sItxtzpxvDRKaMmtYf_xU,3867
|
81
|
+
novel_downloader/core/parsers/dxmwx.py,sha256=uj3tj36d8lnXbgFvmpHzrvv9oDYuMXWZCb0d8I32GfA,5006
|
82
|
+
novel_downloader/core/parsers/esjzone.py,sha256=WeBwFn8waUtiZ3rzGJaiuB21ga7mnMnuBCA-0XnXOQI,7958
|
83
|
+
novel_downloader/core/parsers/guidaye.py,sha256=o1d987B5hkCEIVHYhszSavwKJFAErZVwpDaUPkSNUh4,3879
|
84
|
+
novel_downloader/core/parsers/hetushu.py,sha256=WUG4E9lvDJsa_l1xezYt0epPPJ4V9y_C4wwqWB8sxJs,4047
|
85
|
+
novel_downloader/core/parsers/i25zw.py,sha256=qILX6HQifu0hLJDNFc7XCqUNSQpfALhVgPC9jEGQt4g,4221
|
86
|
+
novel_downloader/core/parsers/ixdzs8.py,sha256=IyT9xoiyzghRuHg9-VASdEkmj-OMrrOBDWhjRNNmrVg,5690
|
87
|
+
novel_downloader/core/parsers/jpxs123.py,sha256=YwZAayPe_N2HJvioKifb3TJmk_EMsaRnPlknCCxHmrA,4211
|
88
|
+
novel_downloader/core/parsers/lewenn.py,sha256=YNk1Jl8eHwFFAAn-NyB1t0cVTZgl-Gkyy1SjGnKYSAU,4225
|
89
|
+
novel_downloader/core/parsers/linovelib.py,sha256=7d4nw6XowcRLGA_BY9q_3tJ8o19JS6_qAIl2vJoVelg,7083
|
90
|
+
novel_downloader/core/parsers/n8novel.py,sha256=AOAaOk1RKJe0gnUggSiVrIwgWD8bNs6cEaiFfb92_MY,7279
|
91
|
+
novel_downloader/core/parsers/piaotia.py,sha256=VGj10yVGzNK_TwUmo-5tVbCgbQA2FlJDv67m-KMxfIo,6086
|
92
|
+
novel_downloader/core/parsers/qbtr.py,sha256=0sae3Ms68Z7XaHav7_5Eid8sqlW1VBn0zZsy1WmVu64,4241
|
93
|
+
novel_downloader/core/parsers/qianbi.py,sha256=ULRLFE-bwnHU8Eifa7egD-cNk_-ea4vyFSCZwGAVTWM,4811
|
94
|
+
novel_downloader/core/parsers/qidian.py,sha256=tq-foRGo2H4C64cWYpD8nrPIzlOmg-JgkvIqVZ9Nn5I,25537
|
95
|
+
novel_downloader/core/parsers/qqbook.py,sha256=9QMSrsSRQUzQYCsZuDP9Rva5hw7QeRU1DvRzf5CW64w,24487
|
96
|
+
novel_downloader/core/parsers/quanben5.py,sha256=wr8QgIYk8FBcJBwm_wjXDdG0yMnodHHzBqnaPn1JETE,3075
|
97
|
+
novel_downloader/core/parsers/registry.py,sha256=2L6yRew4hxN04UUB4xm4E4v8R5RUldawF-Xkg8nXBPI,1534
|
98
|
+
novel_downloader/core/parsers/sfacg.py,sha256=7FuiLgN2SuDTkVmClQe4I8oU35RuLlPEEAHLSLEWqwk,5598
|
99
|
+
novel_downloader/core/parsers/shencou.py,sha256=pdkBCU7n6NmNs64cD6jfbDtEHNSuGqLOiQaIYhLeNr8,6775
|
100
|
+
novel_downloader/core/parsers/shuhaige.py,sha256=rlHXcpKil8anKMi6OVvoPAqGuQdA15hMLlCuSr6C5tM,3128
|
101
|
+
novel_downloader/core/parsers/tongrenquan.py,sha256=y3ok9g-BzA2YVM4KqoNPPpclE0wdNL5mVY3GRQ9FshM,3399
|
102
|
+
novel_downloader/core/parsers/ttkan.py,sha256=_8nc6diogbb9uGHm_lXYJT-RHR9p76o7ARn4NPom2-E,3564
|
103
|
+
novel_downloader/core/parsers/wanbengo.py,sha256=boEnK1gLLpqmf5EUFY9gVEhBxqxYrVka9ou_mDGZ4co,6407
|
104
|
+
novel_downloader/core/parsers/xiaoshuowu.py,sha256=k8j0TY5t7s0n1f-FWuRTZ-eN3A8p-_xnKy7-kp2deK4,5328
|
105
|
+
novel_downloader/core/parsers/xiguashuwu.py,sha256=V3bgvntbDBYm_l9UQUyytfSQ023Qb4Eov1edH52zD84,14225
|
106
|
+
novel_downloader/core/parsers/xs63b.py,sha256=A02abnMtsnWTomx-Hcfr97HFnNO38X9mmqKxHKrS610,5312
|
107
|
+
novel_downloader/core/parsers/xshbook.py,sha256=WwIGXEBAY8h-MLeApB1oVko_g3HF1Uj0X-Hko3TTrJ8,3995
|
108
|
+
novel_downloader/core/parsers/yamibo.py,sha256=B2ijBHCS0JW0I387LH8gDjevwakOE0RRKaKRsV4zo7A,5018
|
109
|
+
novel_downloader/core/parsers/yibige.py,sha256=K_nQ1SwVKLndgzlRvoTd2wd0tWXKb-T02c0sE6-bS5M,4846
|
110
|
+
novel_downloader/core/searchers/__init__.py,sha256=jU5kOLbzj10EYdNtnKQuKbZweGrtdXgBHNli6GvJhDM,1370
|
111
|
+
novel_downloader/core/searchers/aaatxt.py,sha256=KHaX1dpDBaAJz-_7UlaTtnMbFlTplWHaFyOfCkn4gX4,3717
|
112
|
+
novel_downloader/core/searchers/b520.py,sha256=n6X2f0FRoxGDSsvOIMwbs0yZ6U7V6LnkGajGwkPzztQ,2614
|
113
|
+
novel_downloader/core/searchers/base.py,sha256=KKX1-s5qUBX09LKV5wZP0v4SFDmawCSAL_1HhQU868U,5111
|
114
|
+
novel_downloader/core/searchers/dxmwx.py,sha256=ZaeFSU2T3Yl9x6hquila7cF4wYdwm9d82cTjFT9byCQ,3225
|
115
|
+
novel_downloader/core/searchers/esjzone.py,sha256=zw7bQalTfYjp9an0Ghk0ZDsWEOOh-fNsR4Lsoi4u7xA,3199
|
116
|
+
novel_downloader/core/searchers/hetushu.py,sha256=qhX6-QdvzPCXHh7hO6tHXFd3dpbcff_1PL7YvqgOQho,2829
|
117
|
+
novel_downloader/core/searchers/i25zw.py,sha256=1h3IZxjFO8XirDYN7x7fc96XjuspuTdkAUNHf1xVeBM,2827
|
118
|
+
novel_downloader/core/searchers/ixdzs8.py,sha256=Q-tZk5czA-wTSDQ4jnJEITfWWnsMXre5nPTjwJxGl6s,3454
|
119
|
+
novel_downloader/core/searchers/jpxs123.py,sha256=BeEa7wkE0KGwZ3HPIKSh7I8wpF_V8Z2L87eWjzphzwk,3345
|
120
|
+
novel_downloader/core/searchers/n8novel.py,sha256=pvAGlXj8JDLnMdpWsCd56Oh5FwjZB1ksSaqQgeXztok,2517
|
121
|
+
novel_downloader/core/searchers/piaotia.py,sha256=dGueBh819EvxgL-cyBITud3DGXJhebhZkExVxcPcH6E,3510
|
122
|
+
novel_downloader/core/searchers/qbtr.py,sha256=yokdCqlhlfJYy6HDhMZS4nGNzHGYwTy36glXq_AlSDw,3231
|
123
|
+
novel_downloader/core/searchers/qianbi.py,sha256=UK7znw9RZkhpsDTy3_wavi3aBLnaLVUGd9E_Epq5c20,5404
|
124
|
+
novel_downloader/core/searchers/quanben5.py,sha256=xDKtDsZ8e4bhmA9rIG-cdIkbtnaUUxSxJRqZrad1u3g,4265
|
125
|
+
novel_downloader/core/searchers/registry.py,sha256=VFtvtbAqLBSYO7CvXrVya-85t-jOUmyth30wls-6noY,2441
|
126
|
+
novel_downloader/core/searchers/shuhaige.py,sha256=8XW39aIdyHzWwG8r_hsr7YhOEGQLLTIXObe2HlAW8D4,3841
|
127
|
+
novel_downloader/core/searchers/tongrenquan.py,sha256=NE0BN4gutipfBPMm5TJP3YyI29ce6ERpmC1mqfQNgdc,3471
|
128
|
+
novel_downloader/core/searchers/ttkan.py,sha256=Y-qjePD7zQx8RUgASTuz4yu5fzT5MOJg7Qh9_SaP1z0,2851
|
129
|
+
novel_downloader/core/searchers/xiaoshuowu.py,sha256=gAS3OpoMwfksEtlXPL5XPrfD7KVprl8YA7HGn3gGANg,4132
|
130
|
+
novel_downloader/core/searchers/xiguashuwu.py,sha256=YWxOQpXUhMMsgxt7zc51rtdbe6mn9yv5Vzeg63OCJlQ,2952
|
131
|
+
novel_downloader/core/searchers/xs63b.py,sha256=T4QUQphYFvnbnENxFbYVNtZMi2QhXypxOJU-FjjVYwU,3443
|
132
|
+
novel_downloader/locales/en.json,sha256=w3TA-AtsQE2C1EVf5tNiOQRnaaXEaXX88-0Bb3xWdU8,3942
|
133
|
+
novel_downloader/locales/zh.json,sha256=XRku9SHycZ8zP0YYBwchBAg4yYjCWpgCLDItW8cmUcI,3779
|
134
|
+
novel_downloader/models/__init__.py,sha256=nKjRzf2rniAKSptHdngY9uZn6H0CuXIrCrTHsKVKS1A,730
|
135
|
+
novel_downloader/models/book.py,sha256=Xt59n7NRLoqb2Xh5W-VY0ogVXE_XdhXtyYCrtaDOHBE,909
|
136
|
+
novel_downloader/models/config.py,sha256=oF2NkXwInYOCpnb2cG1LpbBKPared3g5Ap-l952HGcI,2547
|
137
|
+
novel_downloader/models/login.py,sha256=VpTKfistRmlEJ67bzRpnAeQFBqs8R7VeGXZ74BZvTF0,355
|
138
|
+
novel_downloader/models/search.py,sha256=NSAXbQJvUY1Zdp1HfAt6JJ-mTFw2aX4-Je-JLeMG8ZY,351
|
139
|
+
novel_downloader/resources/config/settings.toml,sha256=RaG-VIa9K6e60vMaM7G9EjaAU8NXxQzLoYlCNtBbbsg,3702
|
140
|
+
novel_downloader/resources/css_styles/intro.css,sha256=Nqzp-A5we92d90CCiGL8h2FeuMnCz-G0TLevMF_Pl2U,1271
|
141
|
+
novel_downloader/resources/css_styles/main.css,sha256=1nsDTr698eY3furWDHuQMDKP1Vqd2h5x40eJMZpktNE,559
|
142
|
+
novel_downloader/resources/images/volume_border.png,sha256=2dEVimnTHKOfLMhi7bhkh_5joWNnrqg8duomLSNOZx4,28613
|
143
|
+
novel_downloader/resources/js_scripts/expr_to_json.js,sha256=ZyJ1l_2hB8-QMepDbE0KNJQhtr_yg959f7rtAjfZy7s,340
|
144
|
+
novel_downloader/resources/js_scripts/qidian_decrypt_node.js,sha256=mfBqyzSCC38UFjWrFbjX7SsBoIeok1Iv20Nxk6zIFV0,1914
|
145
|
+
novel_downloader/resources/js_scripts/qq_decrypt_node.js,sha256=QUuWrQhsdUtfhRc38Alg3mPRaHszXTsCIhXWwhOTApQ,2280
|
146
|
+
novel_downloader/resources/json/linovelib_font_map.json,sha256=F1IlEcvXGcagnZCu4Gw2vQ2NLnhy6cJOLhabukqnftw,67854
|
147
|
+
novel_downloader/resources/json/xiguashuwu.json,sha256=AT8KSFBWuiHj4Ggz3O1LqED0Tw22k0A4-V4OziHbqfo,16471
|
148
|
+
novel_downloader/utils/__init__.py,sha256=_l77NlxmGA3HHGSwK68o4_Nc7xRaVP8Bo8SUuImP5Uk,867
|
149
|
+
novel_downloader/utils/chapter_storage.py,sha256=7jpVdOguuylnjsJi_yQ-jCMIPljtJWsq_NqXMDDv0lQ,10315
|
150
|
+
novel_downloader/utils/constants.py,sha256=t4lUTT_VHryJ8AyUg9edCoXWmvLgzTjQoODiUImiLws,3413
|
151
|
+
novel_downloader/utils/cookies.py,sha256=Z_9mjJYfhv6xPVgsm7BzCpWeMTcPKoxAoUFWZYuEFWM,2117
|
152
|
+
novel_downloader/utils/i18n.py,sha256=86Wz4zT0_YTnmOSS6cliqO_uMgJJdfC-hNLyqZnXgvU,1050
|
153
|
+
novel_downloader/utils/logger.py,sha256=QuPyblYOIXEa4X0YBHLZgwbv1ZhkPNq159qyGmFKOno,3551
|
154
|
+
novel_downloader/utils/network.py,sha256=AIbM2kEfA9OjkMluFRKqGZIY2ZfNxVAoPnUHUkKkzgw,3625
|
155
|
+
novel_downloader/utils/state.py,sha256=QHfvS9CrO08fRZLNM0B_s0n5XIz7ap20NdAfesQI0Ek,1852
|
156
|
+
novel_downloader/utils/crypto_utils/__init__.py,sha256=MOl8pb73dRk8yQDuh2RZULnM3mn9VnJnOkh0SWcvaPs,136
|
157
|
+
novel_downloader/utils/crypto_utils/aes_util.py,sha256=PiDn1RPkTtki-9ZiTiE2rDgjhN7Ag79k2VDjjpTlkvc,2880
|
158
|
+
novel_downloader/utils/crypto_utils/aes_v1.py,sha256=_jW86_WyUTJfOzqYbZ6QvNPF-V8YRaqaOsyLjMsO610,34247
|
159
|
+
novel_downloader/utils/crypto_utils/aes_v2.py,sha256=OAsMnsztkJilqo8jM6nkrPMyujPqgGhohd-TcwW6fVA,48945
|
160
|
+
novel_downloader/utils/crypto_utils/rc4.py,sha256=SbC0oAdg2N7LWMnq9YbNh-zChI8SfpeBiijTPxFkYFc,1319
|
161
|
+
novel_downloader/utils/epub/__init__.py,sha256=77WorOLdsaxNoiuDPVxvQkiU49NW774bf3E7erPBv1I,725
|
162
|
+
novel_downloader/utils/epub/builder.py,sha256=2Vd7qD12vWqu05hVHrcgn5gfRzxGklY88nv8unuXF4M,11676
|
163
|
+
novel_downloader/utils/epub/constants.py,sha256=1P75NXAiKhoWqgAs_FDisT-U3ULnpk8wdvMnASCMg_o,2867
|
164
|
+
novel_downloader/utils/epub/documents.py,sha256=UijMa8yHpleZLUtRrwwTsOPZlqYlC5-qqXEuKh_StPI,9882
|
165
|
+
novel_downloader/utils/epub/models.py,sha256=CppM1qIC_G53L-lbouJO-pBBKLMTRfMvOM2PUOSPT78,2489
|
166
|
+
novel_downloader/utils/epub/utils.py,sha256=7eRYXUZFZ3NQU69UDwLK_yxiPQWpRhxBPhzKkQSTS0s,5090
|
167
|
+
novel_downloader/utils/file_utils/__init__.py,sha256=PIE96UKkI73wNr5v8kbP159BIbkEwsOQa9iEFr5RGUw,366
|
168
|
+
novel_downloader/utils/file_utils/io.py,sha256=bF1q38BdwjTkM8ylfQGczWAcAMHI0gBB5xNkYwTYqrk,2167
|
169
|
+
novel_downloader/utils/file_utils/normalize.py,sha256=j8d6kmiQyafa-E8NjTv33uUrnNDoxyJ18orXfS5J_Gw,1708
|
170
|
+
novel_downloader/utils/file_utils/sanitize.py,sha256=IuJA2JjcrxxOnJtehPLBpBNOuyNbj97TUZvw-vXB9PE,1713
|
171
|
+
novel_downloader/utils/fontocr/__init__.py,sha256=lWT8hVKeuYatEanyw6EjlgPidlyWSMkgCiRliEG_VtA,314
|
172
|
+
novel_downloader/utils/fontocr/core.py,sha256=pea9WkepQcD2tRgjX0xsvSABVCz7W9qJHy4s8QTY1Ag,7544
|
173
|
+
novel_downloader/utils/fontocr/loader.py,sha256=lgBjEC_c4JMxhTM1kbIth0F30rr9_zy-kOP_2EwhOAI,1422
|
174
|
+
novel_downloader/utils/node_decryptor/__init__.py,sha256=d5ISKEWv4i5ZF7rLtaOnnoLHrUENbVI9r9-FCCOYZTw,368
|
175
|
+
novel_downloader/utils/node_decryptor/decryptor.py,sha256=Nm9t_qL8N1xFplr0ntThVui2M4YlIxQKUJHOGSArIPU,11165
|
176
|
+
novel_downloader/utils/node_decryptor/decryptor_fetcher.py,sha256=U9nBp-DKutqQDjCMkxwR36w869-GiQErXkGN1XdiyZ4,4595
|
177
|
+
novel_downloader/utils/text_utils/__init__.py,sha256=cr0HCvgQFJE2ZEXqjkkmrOA7PnH50dKegrjdpIytUJs,601
|
178
|
+
novel_downloader/utils/text_utils/diff_display.py,sha256=5zvVtzsLbRxmUnn_dWUsXFaq6hch02OlOpqKYP8GB3g,2491
|
179
|
+
novel_downloader/utils/text_utils/numeric_conversion.py,sha256=RJ3L5GBxgNEQYJ7xFoihLVsjGcObBfpUAk_Gz5MxlkA,6627
|
180
|
+
novel_downloader/utils/text_utils/text_cleaner.py,sha256=9GbJChhZQGW06LApnHNzy6t5gS73AA9BTBigBn9qgcs,6410
|
181
|
+
novel_downloader/utils/text_utils/truncate_utils.py,sha256=xg5nlQvq6O1g3K-I64aTZvtnesN0P5QBGUVCPj09g8s,1284
|
182
|
+
novel_downloader/utils/time_utils/__init__.py,sha256=XbBeSbpNqiJy7Lsv-_udz29hPnIY53F0Drbuh730y44,331
|
183
|
+
novel_downloader/utils/time_utils/datetime_utils.py,sha256=ECidI5yvWVia8BWWLu7U0O0YYMIKgJwzWQmOuA_un3U,4499
|
184
|
+
novel_downloader/utils/time_utils/sleep_utils.py,sha256=uwQfnhFHqNOku8UwUJ7btD2N0NgDjY925QKDzT-9_sE,3000
|
185
|
+
novel_downloader/web/__init__.py,sha256=ga8qRQhYcGEiL0WKhSSyldLxkOEfrq-UU71T7MYv7EU,174
|
186
|
+
novel_downloader/web/main.py,sha256=ZzQcpJkAZb7tRlBkub6LGggNrbM4gtrI4nb-MyiUAlY,1783
|
187
|
+
novel_downloader/web/components/__init__.py,sha256=fxBI7rpAQvdZU3obR6_-bFqgmA7nzvRpW05Rw3b4jp8,193
|
188
|
+
novel_downloader/web/components/navigation.py,sha256=m-rjbNRlYjqXsu2dq5PdCzpqy7oW6_otra2ZufRsh1c,1156
|
189
|
+
novel_downloader/web/pages/__init__.py,sha256=KP_aH8y8dtCeRze8jDJ4tC3Ft7UTGhlW8ZKDdKPdwcM,383
|
190
|
+
novel_downloader/web/pages/download.py,sha256=cJ7txLvcXydLTciaSYUSul0jglulRAHMQ7UF25JsvtA,2598
|
191
|
+
novel_downloader/web/pages/progress.py,sha256=whWduqLvQ1PPZpDNVfvFCVaFgFhD87LT4CDb8JuqD_w,5207
|
192
|
+
novel_downloader/web/pages/search.py,sha256=sybpINlDt-zyRxyVulhbB8kKJuOxkOSZAV2chDxWcFI,10232
|
193
|
+
novel_downloader/web/services/__init__.py,sha256=kLW0uyqudnlHtSsMrrghmL6P1-VDrseggNdB3cR5jLA,316
|
194
|
+
novel_downloader/web/services/client_dialog.py,sha256=JwYV8bjxPxLQsuheC8rk_jaeODolz5X9Wo64MsXZoyc,5679
|
195
|
+
novel_downloader/web/services/cred_broker.py,sha256=_R2Szqg5qRBHrFujTlPxrrMpQsnfNozjLUxJ5HhD8_c,2939
|
196
|
+
novel_downloader/web/services/cred_models.py,sha256=8nXbVoAIz3QokctrCVm-8lSnKgCIFhMM6TuaNq6bFGU,846
|
197
|
+
novel_downloader/web/services/task_manager.py,sha256=tK2Vs5Wnx5Jp8Z8myq_-lPm1NwZ2QxLjaHa9p0Jc_K8,8654
|
198
|
+
novel_downloader-2.0.2.dist-info/licenses/LICENSE,sha256=XgmnH0mBf-qEiizoVAfJQAKzPB9y3rBa-ni7M0Aqv4A,1066
|
199
|
+
novel_downloader-2.0.2.dist-info/METADATA,sha256=eyqsSofixNRuVJ3DASJoP6KdGa56KkCbZAjErOf38M8,6589
|
200
|
+
novel_downloader-2.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
201
|
+
novel_downloader-2.0.2.dist-info/entry_points.txt,sha256=nIgnurS4J6_ce3oIBFV87I1pPwBofuRQvxkoRGn4yEU,112
|
202
|
+
novel_downloader-2.0.2.dist-info/top_level.txt,sha256=hP4jYWM2LTm1jxsW4hqEB8N0dsRvldO2QdhggJT917I,17
|
203
|
+
novel_downloader-2.0.2.dist-info/RECORD,,
|
@@ -1,11 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
novel_downloader.core.exporters.common
|
4
|
-
--------------------------------------
|
5
|
-
|
6
|
-
Shared exporter implementation for producing standard TXT and EPUB outputs.
|
7
|
-
"""
|
8
|
-
|
9
|
-
__all__ = ["CommonExporter"]
|
10
|
-
|
11
|
-
from .main_exporter import CommonExporter
|
@@ -1,198 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
novel_downloader.core.exporters.common.epub
|
4
|
-
-------------------------------------------
|
5
|
-
|
6
|
-
Contains the logic for exporting novel content as a single `.epub` file.
|
7
|
-
"""
|
8
|
-
|
9
|
-
from __future__ import annotations
|
10
|
-
|
11
|
-
from pathlib import Path
|
12
|
-
from typing import TYPE_CHECKING
|
13
|
-
|
14
|
-
from novel_downloader.core.exporters.epub_util import (
|
15
|
-
build_epub_chapter,
|
16
|
-
download_cover,
|
17
|
-
finalize_export,
|
18
|
-
inline_remote_images,
|
19
|
-
prepare_builder,
|
20
|
-
remove_all_images,
|
21
|
-
)
|
22
|
-
from novel_downloader.utils import (
|
23
|
-
download,
|
24
|
-
get_cleaner,
|
25
|
-
)
|
26
|
-
from novel_downloader.utils.constants import DEFAULT_IMAGE_SUFFIX
|
27
|
-
from novel_downloader.utils.epub import (
|
28
|
-
Chapter,
|
29
|
-
Volume,
|
30
|
-
)
|
31
|
-
|
32
|
-
if TYPE_CHECKING:
|
33
|
-
from .main_exporter import CommonExporter
|
34
|
-
|
35
|
-
|
36
|
-
def common_export_as_epub(
|
37
|
-
exporter: CommonExporter,
|
38
|
-
book_id: str,
|
39
|
-
) -> Path | None:
|
40
|
-
"""
|
41
|
-
Export a single novel (identified by `book_id`) to an EPUB file.
|
42
|
-
|
43
|
-
This function will:
|
44
|
-
1. Load `book_info.json` for metadata.
|
45
|
-
2. Generate introductory HTML and optionally include the cover image.
|
46
|
-
3. Initialize the EPUB container.
|
47
|
-
4. Iterate through volumes and chapters in volume-batches, convert each to XHTML.
|
48
|
-
5. Assemble the spine, TOC, CSS and write out the final `.epub`.
|
49
|
-
|
50
|
-
:param exporter: The exporter instance, carrying config and path info.
|
51
|
-
:param book_id: Identifier of the novel (used as subdirectory name).
|
52
|
-
"""
|
53
|
-
TAG = "[exporter]"
|
54
|
-
config = exporter._config
|
55
|
-
|
56
|
-
raw_base = exporter._raw_data_dir / book_id
|
57
|
-
img_dir = raw_base / "images"
|
58
|
-
out_dir = exporter.output_dir
|
59
|
-
|
60
|
-
img_dir.mkdir(parents=True, exist_ok=True)
|
61
|
-
out_dir.mkdir(parents=True, exist_ok=True)
|
62
|
-
|
63
|
-
cleaner = get_cleaner(
|
64
|
-
enabled=config.clean_text,
|
65
|
-
config=config.cleaner_cfg,
|
66
|
-
)
|
67
|
-
|
68
|
-
# --- Load book_info.json ---
|
69
|
-
book_info = exporter._load_book_info(book_id)
|
70
|
-
if not book_info:
|
71
|
-
return None
|
72
|
-
|
73
|
-
book_name = book_info.get("book_name", book_id)
|
74
|
-
book_author = book_info.get("author", "")
|
75
|
-
|
76
|
-
exporter.logger.info(
|
77
|
-
"%s Starting EPUB generation: %s (ID: %s)", TAG, book_name, book_id
|
78
|
-
)
|
79
|
-
|
80
|
-
cover_path = download_cover(
|
81
|
-
book_info.get("cover_url", ""),
|
82
|
-
raw_base,
|
83
|
-
config.include_cover,
|
84
|
-
exporter.logger,
|
85
|
-
TAG,
|
86
|
-
)
|
87
|
-
|
88
|
-
# --- Initialize EPUB ---
|
89
|
-
book, main_css = prepare_builder(
|
90
|
-
site_name=exporter.site,
|
91
|
-
book_id=book_id,
|
92
|
-
title=book_name,
|
93
|
-
author=book_author,
|
94
|
-
description=book_info.get("summary", ""),
|
95
|
-
subject=book_info.get("tags", []),
|
96
|
-
serial_status=book_info.get("serial_status", ""),
|
97
|
-
word_count=book_info.get("word_count", ""),
|
98
|
-
cover_path=cover_path,
|
99
|
-
)
|
100
|
-
|
101
|
-
# --- Compile chapters ---
|
102
|
-
volumes = book_info.get("volumes", [])
|
103
|
-
if not volumes:
|
104
|
-
exporter.logger.warning("%s No volumes found in metadata.", TAG)
|
105
|
-
|
106
|
-
for vol_index, vol in enumerate(volumes, start=1):
|
107
|
-
raw_name = vol.get("volume_name", "")
|
108
|
-
raw_name = cleaner.clean_title(raw_name.replace(book_name, ""))
|
109
|
-
vol_name = raw_name or f"Volume {vol_index}"
|
110
|
-
exporter.logger.info("%s Processing volume %d: %s", TAG, vol_index, vol_name)
|
111
|
-
|
112
|
-
# Batch-fetch chapters for this volume
|
113
|
-
chap_ids = [
|
114
|
-
chap["chapterId"]
|
115
|
-
for chap in vol.get("chapters", [])
|
116
|
-
if chap.get("chapterId")
|
117
|
-
]
|
118
|
-
chap_map = exporter._get_chapters(book_id, chap_ids)
|
119
|
-
|
120
|
-
vol_cover: Path | None = None
|
121
|
-
vol_cover_url = vol.get("volume_cover", "")
|
122
|
-
if vol_cover_url:
|
123
|
-
vol_cover = download(
|
124
|
-
vol_cover_url,
|
125
|
-
img_dir,
|
126
|
-
on_exist="skip",
|
127
|
-
default_suffix=DEFAULT_IMAGE_SUFFIX,
|
128
|
-
)
|
129
|
-
|
130
|
-
curr_vol = Volume(
|
131
|
-
id=f"vol_{vol_index}",
|
132
|
-
title=vol_name,
|
133
|
-
intro=cleaner.clean_content(vol.get("volume_intro", "")),
|
134
|
-
cover=vol_cover,
|
135
|
-
)
|
136
|
-
|
137
|
-
for chap_meta in vol.get("chapters", []):
|
138
|
-
chap_id = chap_meta.get("chapterId")
|
139
|
-
if not chap_id:
|
140
|
-
exporter.logger.warning(
|
141
|
-
"%s Missing chapterId, skipping: %s",
|
142
|
-
TAG,
|
143
|
-
chap_meta,
|
144
|
-
)
|
145
|
-
continue
|
146
|
-
|
147
|
-
chap_title = chap_meta.get("title", "")
|
148
|
-
data = chap_map.get(chap_id)
|
149
|
-
if not data:
|
150
|
-
exporter.logger.info(
|
151
|
-
"%s Missing chapter: %s (%s), skipping.",
|
152
|
-
TAG,
|
153
|
-
chap_title,
|
154
|
-
chap_id,
|
155
|
-
)
|
156
|
-
continue
|
157
|
-
|
158
|
-
title = cleaner.clean_title(data.get("title", chap_title)) or chap_id
|
159
|
-
content = cleaner.clean_content(data.get("content", ""))
|
160
|
-
extra = data.get("extra", {})
|
161
|
-
author_note = cleaner.clean_content(extra.get("author_say", ""))
|
162
|
-
content = (
|
163
|
-
inline_remote_images(book, content, img_dir)
|
164
|
-
if config.include_picture
|
165
|
-
else remove_all_images(content)
|
166
|
-
)
|
167
|
-
extras = {"作者说": author_note} if author_note else {}
|
168
|
-
|
169
|
-
chap_html = build_epub_chapter(
|
170
|
-
title=title,
|
171
|
-
paragraphs=content,
|
172
|
-
extras=extras,
|
173
|
-
)
|
174
|
-
curr_vol.chapters.append(
|
175
|
-
Chapter(
|
176
|
-
id=f"c_{chap_id}",
|
177
|
-
filename=f"c{chap_id}.xhtml",
|
178
|
-
title=title,
|
179
|
-
content=chap_html,
|
180
|
-
css=[main_css],
|
181
|
-
)
|
182
|
-
)
|
183
|
-
|
184
|
-
book.add_volume(curr_vol)
|
185
|
-
|
186
|
-
# --- 5. Finalize EPUB ---
|
187
|
-
out_name = exporter.get_filename(
|
188
|
-
title=book_name,
|
189
|
-
author=book_info.get("author"),
|
190
|
-
ext="epub",
|
191
|
-
)
|
192
|
-
return finalize_export(
|
193
|
-
book=book,
|
194
|
-
out_dir=out_dir,
|
195
|
-
filename=out_name,
|
196
|
-
logger=exporter.logger,
|
197
|
-
tag=TAG,
|
198
|
-
)
|
@@ -1,64 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
novel_downloader.core.exporters.common.main_exporter
|
4
|
-
----------------------------------------------------
|
5
|
-
|
6
|
-
Common exporter implementation for saving novels as TXT and EPUB files.
|
7
|
-
"""
|
8
|
-
|
9
|
-
from pathlib import Path
|
10
|
-
|
11
|
-
from novel_downloader.core.exporters.base import BaseExporter
|
12
|
-
|
13
|
-
from .epub import common_export_as_epub
|
14
|
-
from .txt import common_export_as_txt
|
15
|
-
|
16
|
-
|
17
|
-
class CommonExporter(BaseExporter):
|
18
|
-
"""
|
19
|
-
CommonExporter is a exporter that processes and exports novels.
|
20
|
-
|
21
|
-
It extends the BaseExporter interface and provides
|
22
|
-
logic for exporting full novels as plain text (.txt) files
|
23
|
-
and EPUB (.epub) files.
|
24
|
-
"""
|
25
|
-
|
26
|
-
def export_as_txt(self, book_id: str) -> Path | None:
|
27
|
-
"""
|
28
|
-
Compile and export a complete novel as a single .txt file.
|
29
|
-
|
30
|
-
Processing steps:
|
31
|
-
1. Load book metadata from `book_info.json`, including title,
|
32
|
-
author, summary, and chapter structure.
|
33
|
-
2. Iterate through all volumes and chapters, appending each
|
34
|
-
volume/chapter title and content.
|
35
|
-
3. Combine metadata and content into a final formatted text.
|
36
|
-
4. Save the final result to the output directory using the
|
37
|
-
configured filename template.
|
38
|
-
|
39
|
-
:param book_id: The book identifier (used to locate raw data)
|
40
|
-
"""
|
41
|
-
book_id = self._normalize_book_id(book_id)
|
42
|
-
self._init_chapter_storages(book_id)
|
43
|
-
return common_export_as_txt(self, book_id)
|
44
|
-
|
45
|
-
def export_as_epub(self, book_id: str) -> Path | None:
|
46
|
-
"""
|
47
|
-
Persist the assembled book as a EPUB (.epub) file.
|
48
|
-
|
49
|
-
:param book_id: The book identifier.
|
50
|
-
:raises NotImplementedError: If the method is not overridden.
|
51
|
-
"""
|
52
|
-
book_id = self._normalize_book_id(book_id)
|
53
|
-
self._init_chapter_storages(book_id)
|
54
|
-
return common_export_as_epub(self, book_id)
|
55
|
-
|
56
|
-
@staticmethod
|
57
|
-
def _normalize_book_id(book_id: str) -> str:
|
58
|
-
"""
|
59
|
-
Normalize a book identifier.
|
60
|
-
|
61
|
-
Subclasses may override this method to transform the book ID
|
62
|
-
into their preferred format.
|
63
|
-
"""
|
64
|
-
return book_id.replace("/", "-")
|