novel-downloader 1.4.1__py3-none-any.whl → 1.4.3__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.
Files changed (51) hide show
  1. novel_downloader/__init__.py +1 -1
  2. novel_downloader/cli/download.py +70 -11
  3. novel_downloader/config/adapter.py +43 -9
  4. novel_downloader/core/__init__.py +19 -1
  5. novel_downloader/core/downloaders/base.py +26 -29
  6. novel_downloader/core/downloaders/biquge.py +1 -3
  7. novel_downloader/core/downloaders/common.py +41 -7
  8. novel_downloader/core/downloaders/esjzone.py +1 -3
  9. novel_downloader/core/downloaders/linovelib.py +1 -3
  10. novel_downloader/core/downloaders/qianbi.py +1 -3
  11. novel_downloader/core/downloaders/qidian.py +61 -37
  12. novel_downloader/core/downloaders/sfacg.py +1 -3
  13. novel_downloader/core/downloaders/yamibo.py +1 -3
  14. novel_downloader/core/exporters/common/epub.py +153 -68
  15. novel_downloader/core/exporters/epub_util.py +1358 -0
  16. novel_downloader/core/exporters/linovelib/epub.py +147 -190
  17. novel_downloader/core/factory/downloader.py +3 -6
  18. novel_downloader/core/fetchers/base/browser.py +32 -12
  19. novel_downloader/core/fetchers/esjzone/browser.py +8 -6
  20. novel_downloader/core/fetchers/qidian/browser.py +62 -10
  21. novel_downloader/core/fetchers/yamibo/browser.py +3 -3
  22. novel_downloader/core/interfaces/downloader.py +13 -12
  23. novel_downloader/core/parsers/qidian/chapter_encrypted.py +11 -2
  24. novel_downloader/core/parsers/qidian/chapter_normal.py +8 -1
  25. novel_downloader/core/parsers/qidian/main_parser.py +7 -2
  26. novel_downloader/core/parsers/qidian/utils/__init__.py +2 -0
  27. novel_downloader/core/parsers/qidian/utils/helpers.py +9 -0
  28. novel_downloader/locales/en.json +2 -0
  29. novel_downloader/locales/zh.json +2 -0
  30. novel_downloader/models/__init__.py +2 -0
  31. novel_downloader/models/config.py +9 -0
  32. novel_downloader/resources/config/settings.toml +1 -0
  33. novel_downloader/tui/screens/home.py +13 -6
  34. novel_downloader/utils/constants.py +0 -29
  35. novel_downloader/utils/{model_loader.py → fontocr/model_loader.py} +2 -2
  36. novel_downloader/utils/fontocr/ocr_v1.py +2 -1
  37. novel_downloader/utils/fontocr/ocr_v2.py +2 -1
  38. novel_downloader/utils/text_utils/__init__.py +8 -1
  39. novel_downloader/utils/text_utils/text_cleaning.py +51 -0
  40. {novel_downloader-1.4.1.dist-info → novel_downloader-1.4.3.dist-info}/METADATA +5 -2
  41. {novel_downloader-1.4.1.dist-info → novel_downloader-1.4.3.dist-info}/RECORD +45 -50
  42. novel_downloader/core/exporters/epub_utils/__init__.py +0 -40
  43. novel_downloader/core/exporters/epub_utils/css_builder.py +0 -75
  44. novel_downloader/core/exporters/epub_utils/image_loader.py +0 -131
  45. novel_downloader/core/exporters/epub_utils/initializer.py +0 -100
  46. novel_downloader/core/exporters/epub_utils/text_to_html.py +0 -178
  47. novel_downloader/core/exporters/epub_utils/volume_intro.py +0 -60
  48. {novel_downloader-1.4.1.dist-info → novel_downloader-1.4.3.dist-info}/WHEEL +0 -0
  49. {novel_downloader-1.4.1.dist-info → novel_downloader-1.4.3.dist-info}/entry_points.txt +0 -0
  50. {novel_downloader-1.4.1.dist-info → novel_downloader-1.4.3.dist-info}/licenses/LICENSE +0 -0
  51. {novel_downloader-1.4.1.dist-info → novel_downloader-1.4.3.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: novel-downloader
3
- Version: 1.4.1
3
+ Version: 1.4.3
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
@@ -46,7 +46,6 @@ Requires-Dist: aiohttp
46
46
  Requires-Dist: playwright
47
47
  Requires-Dist: lxml
48
48
  Requires-Dist: platformdirs
49
- Requires-Dist: ebooklib
50
49
  Provides-Extra: dev
51
50
  Requires-Dist: black; extra == "dev"
52
51
  Requires-Dist: mypy; extra == "dev"
@@ -55,6 +54,7 @@ Requires-Dist: pytest; extra == "dev"
55
54
  Requires-Dist: pytest-cov; extra == "dev"
56
55
  Requires-Dist: pytest-mock; extra == "dev"
57
56
  Requires-Dist: types-requests; extra == "dev"
57
+ Requires-Dist: types-lxml; extra == "dev"
58
58
  Requires-Dist: types-PyYAML; extra == "dev"
59
59
  Requires-Dist: pre-commit; extra == "dev"
60
60
  Requires-Dist: commitizen; extra == "dev"
@@ -109,6 +109,8 @@ playwright install
109
109
  pip install novel-downloader[font-recovery]
110
110
  ```
111
111
 
112
+ - 详细可见: [安装](https://github.com/BowenZ217/novel-downloader/blob/main/docs/1-installation.md)
113
+
112
114
  ---
113
115
 
114
116
  ### CLI 模式
@@ -180,6 +182,7 @@ pip install .
180
182
  - [CLI 使用示例](https://github.com/BowenZ217/novel-downloader/blob/main/docs/6-cli-usage-examples.md)
181
183
  - [复制 Cookies](https://github.com/BowenZ217/novel-downloader/blob/main/docs/copy-cookies.md)
182
184
  - [文件保存](https://github.com/BowenZ217/novel-downloader/blob/main/docs/file-saving.md)
185
+ - [模块与接口文档](https://github.com/BowenZ217/novel-downloader/blob/main/docs/api/README.md)
183
186
  - [TODO](https://github.com/BowenZ217/novel-downloader/blob/main/docs/todo.md)
184
187
  - [开发](https://github.com/BowenZ217/novel-downloader/blob/main/docs/develop.md)
185
188
  - [项目说明](#项目说明)
@@ -1,55 +1,50 @@
1
- novel_downloader/__init__.py,sha256=nUZvGoS76c8un9BEm7XCbBulkgbGiFZCB87m7L_8gC8,218
1
+ novel_downloader/__init__.py,sha256=JN4ThR5xMeCKx_BPUuZvUrtJJaTH5Tx7ORZZURIY0iY,218
2
2
  novel_downloader/cli/__init__.py,sha256=-2HAut_U1e67MZGdvbpEJ1n5J-bRchzto6L4c-nWeXY,174
3
3
  novel_downloader/cli/clean.py,sha256=hOk8SJQwBCw2oOObTdEI79wpnmZ25uB1s9LQK1-4LNU,4487
4
4
  novel_downloader/cli/config.py,sha256=C6QLfegZLp4legmu8KenqyYKNdrk47bH0z86ujLP0pY,6509
5
- novel_downloader/cli/download.py,sha256=HKCxufqnj4vDzCdM7soH_Y_eiVNRGpV17Mz08ADYwqQ,5279
5
+ novel_downloader/cli/download.py,sha256=wj6wW4osxdB0VA0VeO5Tt2f6HY5CL0Gp8BeoaMzb9Is,6801
6
6
  novel_downloader/cli/export.py,sha256=x9uvyLuvkuaDZGoH212aHZ7XyPT9b2S78AmTN6rkAu4,2283
7
7
  novel_downloader/cli/main.py,sha256=9J8KMuYwL01X6chIaXpQNeS5d3pHnwB9vA9XjKd8RrM,919
8
8
  novel_downloader/config/__init__.py,sha256=2mnf33MQOUnLGCnL1NtNV_rHBejNxBNIbobIGN0tw4E,666
9
- novel_downloader/config/adapter.py,sha256=UYtDlpKFcKmvBBN9ZOI3W7u0a72Fhrpk-DkZmKoKpqk,7281
9
+ novel_downloader/config/adapter.py,sha256=Kp_QOE-ntj5yWBYUnrdNj7ab-R9ZcmBNnMi_dHkv4Gs,8395
10
10
  novel_downloader/config/loader.py,sha256=jo_1rr3UKZRAFFYgO-oHpYLRhF431chmfx4fLGh0MKw,5743
11
11
  novel_downloader/config/site_rules.py,sha256=CJksBSvVAC4sR6cEruf4pM1Jv0zTJb1lcHq0Yn6LPFM,2979
12
- novel_downloader/core/__init__.py,sha256=zzrXjQfBUhfLmBD_95oHTjtTsR81NSRtHcxpYBxQlZ4,654
12
+ novel_downloader/core/__init__.py,sha256=sYwhveDjNQu0oKfS9obWVJGmbxyN8lIWIRiGvGOBZRI,989
13
13
  novel_downloader/core/downloaders/__init__.py,sha256=AK5zeetVXOn_irgHp-NORPYW65UJM4CsF8ysxf2vKD4,1064
14
- novel_downloader/core/downloaders/base.py,sha256=H3Y9NnSv4lQA6ilKCd7HqAX24R79wXBMkLG5StK8znc,6420
15
- novel_downloader/core/downloaders/biquge.py,sha256=PTm8eeaHVyw_nvtnuRpZ2hT7hLs2LEPV1Drd2O6idNM,651
16
- novel_downloader/core/downloaders/common.py,sha256=1YNo-e5tuK5bGvuzX3eVmEJznD7f5JMo7a_abIdmEkM,15504
17
- novel_downloader/core/downloaders/esjzone.py,sha256=GBFJ3fIPov483QxkOTaKBU2wd2f8T4GdvzSbRaU9hDI,655
18
- novel_downloader/core/downloaders/linovelib.py,sha256=Cd43_70SKbKM8_C8c4qev3pLUgyziW9413qrA8EcStY,663
19
- novel_downloader/core/downloaders/qianbi.py,sha256=ARuk1xABOGCjlD_ct5hOKMgWloU187rUJBbICJ2yvkY,651
20
- novel_downloader/core/downloaders/qidian.py,sha256=YrX5HdJDopEjc1kvEJRjMc1S4iR049IGvzUNtgE-LPE,12590
21
- novel_downloader/core/downloaders/sfacg.py,sha256=ShlkIIR6OW_x2FhNDi79S_3AL2CWId2upQmRkApee_E,647
22
- novel_downloader/core/downloaders/yamibo.py,sha256=9L0m5Zq0o1y44tCQ4ZRHHqdO3YresJkRAVvCtsQwouk,651
14
+ novel_downloader/core/downloaders/base.py,sha256=aZECG_HkCPNOGoGY6n8hEue769J2tlAqHz5LHGSwwNw,6525
15
+ novel_downloader/core/downloaders/biquge.py,sha256=u1HkO3UvIq9lrQGJrU8UCBEqMnqPstL_AnfTRcK0J3c,583
16
+ novel_downloader/core/downloaders/common.py,sha256=TAojiAhVGXDaIxbCpAvB4FecLh1TSj8oQDuY9tNynC4,16259
17
+ novel_downloader/core/downloaders/esjzone.py,sha256=rRT2zMft-js2aOMxL71tsWR-to9FIIzua48DzKVwpgM,587
18
+ novel_downloader/core/downloaders/linovelib.py,sha256=tMRuZPRBBt-w0Te7A0Kc2Jjqz-Y_c3TmLhHxJSdxGXo,595
19
+ novel_downloader/core/downloaders/qianbi.py,sha256=ZuwRjMW-2VZRxJxUg3n3168hyhX779cLRC3VSlUYZBU,583
20
+ novel_downloader/core/downloaders/qidian.py,sha256=Zix-9dLMgt2kuMSOPbl9zdZ-TMawfOV5VkGRIrM6-T8,13003
21
+ novel_downloader/core/downloaders/sfacg.py,sha256=kEp3N4ycXJFNh3XqLfIV8MJzy9zi5OOH9XYlXDOO3nY,579
22
+ novel_downloader/core/downloaders/yamibo.py,sha256=oV4VpwCMtvWdEfDUijozId-LRZPlZkLlnkyyLx7_ZuM,583
23
23
  novel_downloader/core/exporters/__init__.py,sha256=ATkkdh6RUIaM19mG1XjFiaMnGRgFFGT3ixsqVkU13Q0,867
24
24
  novel_downloader/core/exporters/base.py,sha256=duIdLnj9kKNZ9r2aJV0Rzl-rnQCP8olk12uzduT9PtE,6146
25
25
  novel_downloader/core/exporters/biquge.py,sha256=SJCChYtDLJKrOpwDCT8IeR0v1LoiUQuTTejfGmRnxX8,462
26
+ novel_downloader/core/exporters/epub_util.py,sha256=uSMB_55v6xKJcKyFjJZghl0ZgCFsdGbJJHH22G-BkeQ,37377
26
27
  novel_downloader/core/exporters/esjzone.py,sha256=UP9gtTOv6komWjgvwXkttqDYJJPjjbJdiG3yz9RxHSQ,467
27
28
  novel_downloader/core/exporters/qianbi.py,sha256=x841MNIxpS5eY8u91ODC0cpIhpT-ENnFqs_Yx6HwtdM,462
28
29
  novel_downloader/core/exporters/qidian.py,sha256=ecaZcgqXyLvJtT2J5QXw4qS9gY3d72mgUnV-0frJvhQ,724
29
30
  novel_downloader/core/exporters/sfacg.py,sha256=j4_H-ixvDxd_OJfIvD4Lbs24LaiFjaYqhvhZcks-ItI,457
30
31
  novel_downloader/core/exporters/yamibo.py,sha256=QaY13llqpyxIgmMnMVFtR5yFMIpyMHHdCmVDW4Dq-bo,462
31
32
  novel_downloader/core/exporters/common/__init__.py,sha256=qIOZ_TgnnQZ6p45YQsxpTcB69e0Jq9XMG3IY0NBVsTM,274
32
- novel_downloader/core/exporters/common/epub.py,sha256=1BhaZCZLehX-v8Z7spatyizhHoMfCF08ZfZGpPfB5Kw,6331
33
+ novel_downloader/core/exporters/common/epub.py,sha256=_hFoc3aVRf7xxrWCvukN7Iv5ulYbkSq53nQMfaZb75E,8833
33
34
  novel_downloader/core/exporters/common/main_exporter.py,sha256=-MRZEpAdsfdRt3VxIv4krMaw2UJnrvCnyj5Jde93zuA,3926
34
35
  novel_downloader/core/exporters/common/txt.py,sha256=b5cNvH0hrjaBO89Uddn1IUY1BFhkHJdTd7WjSWk4ndk,4719
35
- novel_downloader/core/exporters/epub_utils/__init__.py,sha256=cPtuQDtuJZPgOHRf_T5sgkQE13jZnOyPoK9hHJeMEEo,993
36
- novel_downloader/core/exporters/epub_utils/css_builder.py,sha256=qvVgHnyoILgqSUoVsHv-cHzIdtfsqxA8WHt9_89puic,2145
37
- novel_downloader/core/exporters/epub_utils/image_loader.py,sha256=hbxoPvXkBIZnoZSIlHwIUx4zWR8QVppWiH1KotMrBXg,3953
38
- novel_downloader/core/exporters/epub_utils/initializer.py,sha256=TGueFff1ydRLdJYBEJnqIkoVCV57ZiR3dGu_c5Hrp8g,3364
39
- novel_downloader/core/exporters/epub_utils/text_to_html.py,sha256=VSYbm33PrwxFmcT-2f_U2j3kuHzdcSMR7PRqOWvZICU,5617
40
- novel_downloader/core/exporters/epub_utils/volume_intro.py,sha256=cwHMVwJeK8TzXnOw4MYWXvbZGt4iWFjdesDm4n_V-Tk,1830
41
36
  novel_downloader/core/exporters/linovelib/__init__.py,sha256=zD7A7OhluipwICssnp27c_oenYozevZH9g0Qj5WOMWY,195
42
- novel_downloader/core/exporters/linovelib/epub.py,sha256=wxfNxOX6kxSaove-YlDlNw1cmsBJFwysk6bS6Gsk8Cw,14503
37
+ novel_downloader/core/exporters/linovelib/epub.py,sha256=yVqv-lnc7Nh-COd4POvQ0vbsAw18NJ8oFO88-zKedb4,13048
43
38
  novel_downloader/core/exporters/linovelib/main_exporter.py,sha256=cHkAp_jdF6uji5Avu1l8z6mR0nSrWYgX6ETDEezkjoE,3700
44
39
  novel_downloader/core/exporters/linovelib/txt.py,sha256=ALlZUl5nNtg4OmYlurMC0acjmTOBV7G8c13DPrxbG4w,4407
45
40
  novel_downloader/core/factory/__init__.py,sha256=_IY3N35onhWD_nw_TyxKOxa6e7Uak9Cv0bp4pK9yb0M,464
46
- novel_downloader/core/factory/downloader.py,sha256=hNCp3IlZQzeTSLBMuO_Y_EzrAn9_-8SLBHcUwMw8ijM,2060
41
+ novel_downloader/core/factory/downloader.py,sha256=M3yGIdHhthYdvUmXP-jJiVojmBcOf293q5YftgjWzfg,1923
47
42
  novel_downloader/core/factory/exporter.py,sha256=CjDJGnWBDk-S1zYntIDAEo1hLM2q55tlJOjTXKn0hAI,1533
48
43
  novel_downloader/core/factory/fetcher.py,sha256=stfRJnh5ZXLqRsDtQC1BDeTe0yaZI-mgm3Qx03nWUP4,2402
49
44
  novel_downloader/core/factory/parser.py,sha256=0PXepJhlE6aGs9_t81vyho1eCw84-6XRBGb98_phvSQ,2237
50
45
  novel_downloader/core/fetchers/__init__.py,sha256=C1OykEdCzj3fpLRRhVrvwClpzz-pzTzTilH306crgYg,1440
51
46
  novel_downloader/core/fetchers/base/__init__.py,sha256=p9be-q2YjiHcQhv4_KMeZmHgaAYYyUDWoBo6Gvwughc,224
52
- novel_downloader/core/fetchers/base/browser.py,sha256=oR3ZMw71_LJrgTZXduVtZuXEkr7PZ9nxlS5ZlYavN_0,11153
47
+ novel_downloader/core/fetchers/base/browser.py,sha256=6bXhCLc4hxzQgCoEoMspAY1Hn3TT1hjQNIJX0CSNzgw,11927
53
48
  novel_downloader/core/fetchers/base/rate_limiter.py,sha256=zUYH_PjnKfUzJpcbUPtMkwXxIlF0SH-ZTFlbCUrq060,2724
54
49
  novel_downloader/core/fetchers/base/session.py,sha256=Elfpov2cqojunCrLaaSL9ZgWLNVanUDZvgOoIfk5sSc,13251
55
50
  novel_downloader/core/fetchers/biquge/__init__.py,sha256=9EW4eerGeob4QGoDr11A8Mv7xvcfWVFU57M3VT9vzPI,236
@@ -59,7 +54,7 @@ novel_downloader/core/fetchers/common/__init__.py,sha256=ur_zQHrmJdPsFvpyC8AWjsZ
59
54
  novel_downloader/core/fetchers/common/browser.py,sha256=RgNOizfgi_59Xaee6lTlpfiCMGjz_4luNDlHLQqUpl0,2289
60
55
  novel_downloader/core/fetchers/common/session.py,sha256=Ydtwun9lPN4VEIIEIA7Skm6_GOiF_9VDUPkjGQQTdtM,2299
61
56
  novel_downloader/core/fetchers/esjzone/__init__.py,sha256=Cr30WpKEnCrG_vVqttfI9T0zdkwDsLFOnCxQz4EAQQA,242
62
- novel_downloader/core/fetchers/esjzone/browser.py,sha256=SPvbKURw2DkUAlOBLbklmRCFvDoI4tAUDwmBRo2Kuc8,6224
57
+ novel_downloader/core/fetchers/esjzone/browser.py,sha256=bs9o97FRbtx8VSp1AfS0sljD0Izc16JDWqB_EL6GHT4,6278
63
58
  novel_downloader/core/fetchers/esjzone/session.py,sha256=hwvS9LMWm5PYHTTZqYkBgWqkVqkrCfQcaFh6NBICt1Q,7218
64
59
  novel_downloader/core/fetchers/linovelib/__init__.py,sha256=sMNXSBvn8gaZxNX5x4Ork8RzXxL7PhuigquWx6zQ6A4,254
65
60
  novel_downloader/core/fetchers/linovelib/browser.py,sha256=9rQzmJwtu_FHDDQvgDrVIZdwHA7CjnBkIgdyBuy7X50,6086
@@ -68,16 +63,16 @@ novel_downloader/core/fetchers/qianbi/__init__.py,sha256=h4Rve7fO1GcSJ-DlNC5zw7f
68
63
  novel_downloader/core/fetchers/qianbi/browser.py,sha256=1EmrSwpqSYhEO_ID3RJbUaAOhcqvVnMnch6iOafXbTA,3162
69
64
  novel_downloader/core/fetchers/qianbi/session.py,sha256=c3pJcgi9C1x9QYTBihvazHcgT7XTp2HBYfStTn6gSEg,3141
70
65
  novel_downloader/core/fetchers/qidian/__init__.py,sha256=2LshlX82lFpWZMV6yujHsfue9KM0-F1O3HvMCopIv9M,236
71
- novel_downloader/core/fetchers/qidian/browser.py,sha256=JuFncpirI4HLyfIkR0xZmHL6AZZy7tQOzkzsC24b9ss,8578
66
+ novel_downloader/core/fetchers/qidian/browser.py,sha256=cUgJMrFe_MITHh4MGrDI2-a-MCqXSsoeJsbDus0l2LY,10448
72
67
  novel_downloader/core/fetchers/qidian/session.py,sha256=WrHsov15PoRDYbb1ZRaScJQGRZv6axz9_hVEC1Wt1PM,9746
73
68
  novel_downloader/core/fetchers/sfacg/__init__.py,sha256=bQAIwERsX9XOKrP2LteFKX8Jlhw4oeUNwpZTHXn5RRg,230
74
69
  novel_downloader/core/fetchers/sfacg/browser.py,sha256=15PVS75PxEKR5W7mQbqVxoN0d4V1XVYVF0l1yy_sv_Y,5681
75
70
  novel_downloader/core/fetchers/sfacg/session.py,sha256=9K4emQCRq45vzYn-ZDX549tK2F92x2CBMp4ODohNOjc,5085
76
71
  novel_downloader/core/fetchers/yamibo/__init__.py,sha256=5ds6DNNvpo6F6U5dboEaIsJoKSPorkPte_HWVnXMdXo,236
77
- novel_downloader/core/fetchers/yamibo/browser.py,sha256=7YRrWbA8_cOcT_z-VjMWP6FUg30TwV6eLW4zJZ_UxSE,7249
72
+ novel_downloader/core/fetchers/yamibo/browser.py,sha256=rkLgIIxLeFV2r4oAT0pOgiKgnp9HJ6X_fwfQIShhgj0,7265
78
73
  novel_downloader/core/fetchers/yamibo/session.py,sha256=434EArdKgEYIBZkb1nMub3PQXdRTS-Ov2_1u9MESjOs,7212
79
74
  novel_downloader/core/interfaces/__init__.py,sha256=hB1SjBzuN7qnZx_h3RV4w_roj3ZwShbIG3CV9jGMB14,602
80
- novel_downloader/core/interfaces/downloader.py,sha256=XozFf-7OOtBQDlWNs3IRcBjwTPGFWwseFLGta-sZZmU,1560
75
+ novel_downloader/core/interfaces/downloader.py,sha256=H0S4o5MW22JcvNVECv1bCdwAN0drBwHY31IbvVHn-X0,1557
81
76
  novel_downloader/core/interfaces/exporter.py,sha256=zwIaJ5FXo_JmKYg2UZV9FTWX7xZ2e0QuL4RTNGRtI04,1610
82
77
  novel_downloader/core/interfaces/fetcher.py,sha256=XlP3d-Q_xvuVextZCdLOxDf8BwBbx799L_WLJx0WTB8,4096
83
78
  novel_downloader/core/interfaces/parser.py,sha256=iZeUgNl-zE-wsf1eW4GVCPjEaLSvQrNJi_mVEOU9ulY,1353
@@ -96,29 +91,29 @@ novel_downloader/core/parsers/qianbi/__init__.py,sha256=CNmoER8U2u4-ix5S0DDq-pHT
96
91
  novel_downloader/core/parsers/qianbi/main_parser.py,sha256=kMjGew_dmqjI9oIThyHgxThZZgS3IaESB_tNf1nkCKk,5069
97
92
  novel_downloader/core/parsers/qidian/__init__.py,sha256=fWWFeyythX0gpDCJ-2AslrRl2hq4vW2bx9hHh1W7mAw,173
98
93
  novel_downloader/core/parsers/qidian/book_info_parser.py,sha256=h5oAVJOOSZMV4U2GnSezVHPJOEUKUic_oD2gl94mEPQ,3721
99
- novel_downloader/core/parsers/qidian/chapter_encrypted.py,sha256=VhPDERJq1ROJaBlaJuCXJGffisOxkeYFDUKXHo31HfU,18263
100
- novel_downloader/core/parsers/qidian/chapter_normal.py,sha256=6mD86OalpxiCDhjzUjcfFYsgmnTRU_rMIgFN8_Ceu50,4453
94
+ novel_downloader/core/parsers/qidian/chapter_encrypted.py,sha256=uIVmRH96O_G0hcvg2nufUQDrZzq_XRhfvB_8YRW22g8,18532
95
+ novel_downloader/core/parsers/qidian/chapter_normal.py,sha256=CClt6zVph7qjZ0HaiYzMPYlcFgnPIY783-SLVIXNL7E,4738
101
96
  novel_downloader/core/parsers/qidian/chapter_router.py,sha256=foVMlWtE-qUOvJD_4EDiuAVaNkFdeV_ZTCvS5IL7Orc,1957
102
- novel_downloader/core/parsers/qidian/main_parser.py,sha256=SPU6sUO8e4Gp_1q2WypuUQYEyHhoXM7OiRsthhFT6SM,4396
103
- novel_downloader/core/parsers/qidian/utils/__init__.py,sha256=HfjXrGAwH_ceRSE4m88Dl9qb7vHMGcPFxxTU3qrTld8,548
97
+ novel_downloader/core/parsers/qidian/main_parser.py,sha256=jeo7Ypnf-tsBGucjBYBdPzXGd8N4N2eOERuHREloT0o,4504
98
+ novel_downloader/core/parsers/qidian/utils/__init__.py,sha256=-7-nNMtX-KONSN3Q6-f3Yaxt9Oc3Y63kg5ZvNl6xlkY,588
104
99
  novel_downloader/core/parsers/qidian/utils/decryptor_fetcher.py,sha256=8ytJnAfiJIxj0wlke9UwYA6vngUyLxVZt8PbfkNUhss,4687
105
- novel_downloader/core/parsers/qidian/utils/helpers.py,sha256=-7vd1BMu5pVFCRySfPWyrItVbZ2wrHPNY8iAQEP7T_8,3264
100
+ novel_downloader/core/parsers/qidian/utils/helpers.py,sha256=v64zTDQ6qbKnGXM7MPzCsS7yQ-w730vPVrDD19Bgx4Q,3514
106
101
  novel_downloader/core/parsers/qidian/utils/node_decryptor.py,sha256=gjqirr5RECScFw0C6DET7ZMaLTcqGcPOmlkwFUJbTHQ,5965
107
102
  novel_downloader/core/parsers/sfacg/__init__.py,sha256=O2nscvtOweMXHMONdvySTsLSy1ulhv53WTp4r6J47tI,169
108
103
  novel_downloader/core/parsers/sfacg/main_parser.py,sha256=yW18MALAZisJdFO-7peI1h-4XVloEDXeCJvXUz5hJ1A,5899
109
104
  novel_downloader/core/parsers/yamibo/__init__.py,sha256=KJ_fCcakoQrsG36OOd0paXXB1cAIwMirKaA8ZLUKUKI,173
110
105
  novel_downloader/core/parsers/yamibo/main_parser.py,sha256=9sNXsDR2iDVyTYupP_7PyE7BXf2po3sZLq1XEFA8DrI,6554
111
- novel_downloader/locales/en.json,sha256=-bKxndkwJCTCt7ZZGRRKzNaulC7z8XB6Tu7T1SR-1S8,6840
112
- novel_downloader/locales/zh.json,sha256=xzbUsKtkdQvQkehTgIURlQMPepOSWbQBgzTJ4SSJNZc,6699
113
- novel_downloader/models/__init__.py,sha256=G5fYGdaFquJBcllFJ7-YgqkvP4vD3xVEI9MeYcrCr_s,1068
106
+ novel_downloader/locales/en.json,sha256=mcGv24zHS2FFimwCYRLMD8CYzAzngTv1tODZP64GWvY,7002
107
+ novel_downloader/locales/zh.json,sha256=7kkKGt1fudSC9LvmFyAgXfyCC512XfCoyf5by8Egqnc,6849
108
+ novel_downloader/models/__init__.py,sha256=5aQ24IeU8OJDhBZdZ8Ov-xWoLlZm6Qg24r5FPyLTa6Q,1102
114
109
  novel_downloader/models/browser.py,sha256=ly-jM7izQ77yTIG-oau51HJofDpBfrXpIJZJjoQyad8,435
115
110
  novel_downloader/models/chapter.py,sha256=bdAQUDZIuuTVxoYjoOJrbS2u81b1B2mkuZkTSf0m2HQ,492
116
- novel_downloader/models/config.py,sha256=d5G8sob9oNA8rr1N7BvDEJRVSCKJUtD_QBcvWZvGMyw,2792
111
+ novel_downloader/models/config.py,sha256=mFrGZALhZzalWn9wtgRdwGnmgwh6xE0dXAaO7mFIrRc,3013
117
112
  novel_downloader/models/login.py,sha256=sY2Jom6PLpA9Z3Uy7plZKhda3Gq7awKOOIIaQ79PpWs,371
118
113
  novel_downloader/models/site_rules.py,sha256=kzDB5F8lf4udAO0WVUrgBOR7ave3jsMBxt7cEoG0bnI,2721
119
114
  novel_downloader/models/tasks.py,sha256=e4DYEXQQQewgQyCCHfc0UYnkPJ96LafmhG3oO5MQP0Q,465
120
115
  novel_downloader/models/types.py,sha256=q1KDuGW0SVxQILKKoPXKRecfaKe2m8jUM0nyaeDJ6dE,394
121
- novel_downloader/resources/config/settings.toml,sha256=A2B_EMh0zjTLi6UBCjhX__igz7xLCXnCqDzJMhiZn8E,4491
116
+ novel_downloader/resources/config/settings.toml,sha256=gp5RrnSHJmnvrx75QwFxadKZVLWh8mnCy99aCwqirdQ,4580
122
117
  novel_downloader/resources/css_styles/main.css,sha256=WM6GePwdOGgM86fbbOxQ0_0oerTBDZeQHt8zRVfcJp8,1617
123
118
  novel_downloader/resources/css_styles/volume-intro.css,sha256=6gaUnNKkrb2w8tYJRq1BGD1FwbhT1I5W2GI_Zelo9G4,1156
124
119
  novel_downloader/resources/images/volume_border.png,sha256=2dEVimnTHKOfLMhi7bhkh_5joWNnrqg8duomLSNOZx4,28613
@@ -130,21 +125,20 @@ novel_downloader/tui/__init__.py,sha256=8RB8tBrPcoBzm1tpQlgZqnOZXrdHmlzMRxuk9wsN
130
125
  novel_downloader/tui/app.py,sha256=ytV1u15nGCRj_ff_GeAL3W1XlU6r5Lh_k3HBcAjPRx0,731
131
126
  novel_downloader/tui/main.py,sha256=MBP8SrwEYTpGQm-V9W_4rKnTeslneORfkzFsU3Xj2yA,256
132
127
  novel_downloader/tui/screens/__init__.py,sha256=QsUM5cUEKm7nluQh9acEt37xRWbkZU3vqIpBduepDCU,203
133
- novel_downloader/tui/screens/home.py,sha256=ximy5vwHGrkUD88U6Gr9h3kT-wtOMMLBzB9aEZPuA5w,6716
128
+ novel_downloader/tui/screens/home.py,sha256=nH3pRuCOFcSvNV4AYC6RRkWpphmRgY1bNK36OkSVfCg,6994
134
129
  novel_downloader/tui/screens/login.py,sha256=eEVmQFZKQX8mCt_qp96QK8t2pB15FeUrk_oV3jm_Mz4,2224
135
130
  novel_downloader/tui/styles/home_layout.tcss,sha256=VNJs339qiwNUuqwwdK6VkYThCdsqlw-2mEoZVCspdrw,974
136
131
  novel_downloader/tui/widgets/richlog_handler.py,sha256=bhFb0E7Z7-dRS07y_vMjxjPeCic9AD59MFPLhef_R5g,572
137
132
  novel_downloader/utils/__init__.py,sha256=4iUXNUzxeAnGmpGWsB4K_jckUYEW0u_LqWp_OM7mtK8,78
138
133
  novel_downloader/utils/cache.py,sha256=_jVEWAaMGY86kWVnAuuIvJA_hA8dH2ClI7o3p99mEvE,618
139
134
  novel_downloader/utils/chapter_storage.py,sha256=wXXIzNjs1GfPPoqgYYPnQ9Two23McW6ZZNDmhfSC9aY,9831
140
- novel_downloader/utils/constants.py,sha256=1emMOmGRuat0yX8ozZMM1pAUGdU0kYBhDVNW_6dDtps,5700
135
+ novel_downloader/utils/constants.py,sha256=EaxQllQ_dIce5_eRTgAJ-OXRtEk3cMhLUbOKA359198,4435
141
136
  novel_downloader/utils/cookies.py,sha256=WuPBt_z7cF4n7QPIw1julATWt6dbDRCbNdgXHSikmjo,2042
142
137
  novel_downloader/utils/crypto_utils.py,sha256=BRlVR9Nvbu8TQXocJb3po1-kD5HkbCV0yyT84nq_XtI,2052
143
138
  novel_downloader/utils/hash_store.py,sha256=HfzthzcKbHbVaHNpqjaAs2wDeq7iIeY8Mzkt_4v80jQ,9388
144
139
  novel_downloader/utils/hash_utils.py,sha256=7eC7WsO_kl25OnRYWzIXbCXsewxvCcvRCzetsf-wbTo,3023
145
140
  novel_downloader/utils/i18n.py,sha256=pdAcSIA5Tp-uPEBwNByHL7C1NayTnpOsl7zFv9p2G1k,1033
146
141
  novel_downloader/utils/logger.py,sha256=9h1iFS8_auiquNgOBd-Q2pbbcnAhAKL39yf3PKadu00,3339
147
- novel_downloader/utils/model_loader.py,sha256=JKgRFrr4HlAW9zuDUBAuuo_Kk_T_g9dWiU8E3zYk0vo,1996
148
142
  novel_downloader/utils/network.py,sha256=W0SVr55MSUjTmMPkUvvkH10SRgFx3GWrCN_fDavfk4A,9143
149
143
  novel_downloader/utils/state.py,sha256=FcNJ85GvBu7uEIjy0QHGr4sXMbHPEMkCjwUKNg5EabI,5132
150
144
  novel_downloader/utils/file_utils/__init__.py,sha256=zvOm2qSEmWd_mRGJceGBZb5MYMSDAlWYjS5MkVQNZgI,1159
@@ -152,19 +146,20 @@ novel_downloader/utils/file_utils/io.py,sha256=AZ3NUe6lifGsYt3iYyXyQ2BO41WV8j013
152
146
  novel_downloader/utils/file_utils/normalize.py,sha256=MrsCq4FqmskKRkHRV_J0z0dmn69OerMum-9sqx2XOGM,2023
153
147
  novel_downloader/utils/file_utils/sanitize.py,sha256=rE-u4vpDL10zH8FT8d9wqwWsz-7dR6PJ-LE45K8VaeE,2112
154
148
  novel_downloader/utils/fontocr/__init__.py,sha256=fe-04om3xxBvFKt5BBCApXCzv-Z0K_AY7lv9IB1jEHM,543
155
- novel_downloader/utils/fontocr/ocr_v1.py,sha256=bwkvqKXUcKsgBCrag8jHuIl8AOM_MbV28ZSQ_aO_X6s,11245
156
- novel_downloader/utils/fontocr/ocr_v2.py,sha256=OJ_egORHa9KwVJX4kEABR25D7RRF0jVCRV4WgHUal7M,27307
157
- novel_downloader/utils/text_utils/__init__.py,sha256=JQtEnJ22K9o_syY5PV4Bf_p4BKZonX5g9-A5eqlxpZs,806
149
+ novel_downloader/utils/fontocr/model_loader.py,sha256=aBPZlwZ-rx2tDsWtN3BnB15vceqNkqTEBX1h2pMZf3E,2012
150
+ novel_downloader/utils/fontocr/ocr_v1.py,sha256=S8GAuDUiVv3mciQvgHEibAhJ2DIow6bHs_ZSYvboC4c,11224
151
+ novel_downloader/utils/fontocr/ocr_v2.py,sha256=XiTHNeRcCw4Q441Tfdox6Sq91dHPfUYg5MecO8qfcB8,27286
152
+ novel_downloader/utils/text_utils/__init__.py,sha256=tAO8oCryMAwQoCCpTKaLJagQ6UK8tJXU55MYomWI-6c,913
158
153
  novel_downloader/utils/text_utils/chapter_formatting.py,sha256=WAAEAcI7zI_uIeARDybZfXDdMvGio3VIkANFrK8-8Os,1378
159
154
  novel_downloader/utils/text_utils/diff_display.py,sha256=aUvjMcYO-1_P8ZYiYbmYbJOByKo2bWoBV_ifRuAqwb8,2528
160
155
  novel_downloader/utils/text_utils/font_mapping.py,sha256=Aos5skBhowDdPgnYmK0bpLtNm2hZg3RolNlTkxC9kO8,865
161
- novel_downloader/utils/text_utils/text_cleaning.py,sha256=_Nahr8iv3341IyDXW-KpTn4XNG2hB-HajSM52pysPu8,1630
156
+ novel_downloader/utils/text_utils/text_cleaning.py,sha256=zufXt0pc0vnUwgSHD_8LAef3ffqmX9rJ11YzW4rgwLA,2940
162
157
  novel_downloader/utils/time_utils/__init__.py,sha256=725vY2PvqFhjbAz0hCOuIuhSCK8HrEqQ_k3YwvubmXo,624
163
158
  novel_downloader/utils/time_utils/datetime_utils.py,sha256=1eyX8lTEqkQ-rEej_GrhbUpaIR5tsFdVSKT-q8s9X-g,4927
164
159
  novel_downloader/utils/time_utils/sleep_utils.py,sha256=C4XYeAtxoVZC9Ju6vhhP9sbOrSpdZG2Nm-x1IYO_OFA,3233
165
- novel_downloader-1.4.1.dist-info/licenses/LICENSE,sha256=XgmnH0mBf-qEiizoVAfJQAKzPB9y3rBa-ni7M0Aqv4A,1066
166
- novel_downloader-1.4.1.dist-info/METADATA,sha256=ZhGsQDAL7bnxkiKs8lUsToC24ueLKshwK0e2KImvduU,7027
167
- novel_downloader-1.4.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
168
- novel_downloader-1.4.1.dist-info/entry_points.txt,sha256=u1Ns5xI_QJyL4HAFCgJvJdib9ugu7M9I2tnQwZjJxrk,112
169
- novel_downloader-1.4.1.dist-info/top_level.txt,sha256=hP4jYWM2LTm1jxsW4hqEB8N0dsRvldO2QdhggJT917I,17
170
- novel_downloader-1.4.1.dist-info/RECORD,,
160
+ novel_downloader-1.4.3.dist-info/licenses/LICENSE,sha256=XgmnH0mBf-qEiizoVAfJQAKzPB9y3rBa-ni7M0Aqv4A,1066
161
+ novel_downloader-1.4.3.dist-info/METADATA,sha256=MiScyRXyeXncWbjtBIZsFDJqGfL925DraPy7v6TvakQ,7253
162
+ novel_downloader-1.4.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
163
+ novel_downloader-1.4.3.dist-info/entry_points.txt,sha256=u1Ns5xI_QJyL4HAFCgJvJdib9ugu7M9I2tnQwZjJxrk,112
164
+ novel_downloader-1.4.3.dist-info/top_level.txt,sha256=hP4jYWM2LTm1jxsW4hqEB8N0dsRvldO2QdhggJT917I,17
165
+ novel_downloader-1.4.3.dist-info/RECORD,,
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- novel_downloader.core.exporters.epub_utils
4
- ------------------------------------------
5
-
6
- This package provides utility functions for constructing EPUB files,
7
- including:
8
-
9
- - CSS inclusion (css_builder)
10
- - Image embedding (image_loader)
11
- - EPUB book initialization (initializer)
12
- - Chapter text-to-HTML conversion (text_to_html)
13
- - Volume intro HTML generation (volume_intro)
14
- """
15
-
16
- from .css_builder import create_css_items
17
- from .image_loader import (
18
- add_images_from_dir,
19
- add_images_from_dirs,
20
- add_images_from_list,
21
- )
22
- from .initializer import init_epub
23
- from .text_to_html import (
24
- chapter_txt_to_html,
25
- generate_book_intro_html,
26
- inline_remote_images,
27
- )
28
- from .volume_intro import create_volume_intro
29
-
30
- __all__ = [
31
- "create_css_items",
32
- "add_images_from_dir",
33
- "add_images_from_dirs",
34
- "add_images_from_list",
35
- "init_epub",
36
- "chapter_txt_to_html",
37
- "create_volume_intro",
38
- "generate_book_intro_html",
39
- "inline_remote_images",
40
- ]
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- novel_downloader.core.exporters.epub_utils.css_builder
4
- ------------------------------------------------------
5
-
6
- Reads local CSS files and wraps them into epub.EpubItem objects,
7
- returning a list ready to be added to the EPUB.
8
- """
9
-
10
- import logging
11
- from importlib.abc import Traversable
12
- from typing import TypedDict
13
-
14
- from ebooklib import epub
15
-
16
- from novel_downloader.utils.constants import (
17
- CSS_MAIN_PATH,
18
- CSS_VOLUME_INTRO_PATH,
19
- )
20
-
21
- logger = logging.getLogger(__name__)
22
-
23
-
24
- class CssConfig(TypedDict):
25
- include: bool
26
- path: Traversable
27
- uid: str
28
- file_name: str
29
-
30
-
31
- def create_css_items(
32
- include_main: bool = True,
33
- include_volume: bool = True,
34
- ) -> list[epub.EpubItem]:
35
- """
36
- :param include_main: Whether to load the main stylesheet.
37
- :param include_volume: Whether to load the “volume intro” stylesheet.
38
- :returns: A list of epub.EpubItem ready to add to the book.
39
- """
40
- css_config: list[CssConfig] = [
41
- {
42
- "include": include_main,
43
- "path": CSS_MAIN_PATH,
44
- "uid": "style",
45
- "file_name": "Styles/main.css",
46
- },
47
- {
48
- "include": include_volume,
49
- "path": CSS_VOLUME_INTRO_PATH,
50
- "uid": "volume_style",
51
- "file_name": "Styles/volume-intro.css",
52
- },
53
- ]
54
- css_items: list[epub.EpubItem] = []
55
-
56
- for css in css_config:
57
- if css["include"]:
58
- path = css["path"]
59
- try:
60
- content: str = path.read_text(encoding="utf-8")
61
- content_bytes: bytes = content.encode("utf-8")
62
- css_items.append(
63
- epub.EpubItem(
64
- uid=css["uid"],
65
- file_name=css["file_name"],
66
- media_type="text/css",
67
- content=content_bytes,
68
- )
69
- )
70
- except FileNotFoundError:
71
- logger.info(f"[epub] CSS 文件不存在: {css['path']}")
72
- except UnicodeDecodeError:
73
- logger.info(f"[epub] 无法解码文件: {css['path']}")
74
-
75
- return css_items
@@ -1,131 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- novel_downloader.core.exporters.epub_utils.image_loader
4
- -------------------------------------------------------
5
-
6
- Utilities for embedding image files into an EpubBook.
7
- """
8
-
9
- import logging
10
- from collections.abc import Iterable, Sequence
11
- from pathlib import Path
12
-
13
- from ebooklib import epub
14
-
15
- from novel_downloader.utils.constants import EPUB_IMAGE_FOLDER
16
-
17
- logger = logging.getLogger(__name__)
18
-
19
- _SUPPORTED_IMAGE_MEDIA_TYPES: dict[str, str] = {
20
- "png": "image/png",
21
- "jpg": "image/jpeg",
22
- "jpeg": "image/jpeg",
23
- "gif": "image/gif",
24
- "svg": "image/svg+xml",
25
- "webp": "image/webp",
26
- }
27
- _DEFAULT_IMAGE_MEDIA_TYPE = "image/jpeg"
28
-
29
-
30
- def add_images_from_list(
31
- book: epub.EpubBook,
32
- image_list: Sequence[str | Path],
33
- ) -> epub.EpubBook:
34
- """
35
- Add a list of image files to the EPUB's image folder.
36
-
37
- :param book: The EpubBook object to modify.
38
- :param image_list: List of paths to image files.
39
- :return: The same EpubBook instance, with images added.
40
- """
41
- for img_path in image_list:
42
- img_path = Path(img_path)
43
- if not img_path.is_file():
44
- continue
45
-
46
- suffix = img_path.suffix.lower().lstrip(".")
47
- media_type = _SUPPORTED_IMAGE_MEDIA_TYPES.get(suffix)
48
- if media_type is None:
49
- media_type = _DEFAULT_IMAGE_MEDIA_TYPE
50
- logger.warning(
51
- "Unknown image suffix '%s' - defaulting media_type to %s",
52
- suffix,
53
- media_type,
54
- )
55
-
56
- try:
57
- content = img_path.read_bytes()
58
- item = epub.EpubItem(
59
- uid=f"img_{img_path.stem}",
60
- file_name=f"{EPUB_IMAGE_FOLDER}/{img_path.name}",
61
- media_type=media_type,
62
- content=content,
63
- )
64
- book.add_item(item)
65
- logger.debug("Embedded image: %s", img_path.name)
66
- except Exception:
67
- logger.exception("Failed to embed image %s", img_path)
68
-
69
- return book
70
-
71
-
72
- def add_images_from_dir(
73
- book: epub.EpubBook,
74
- image_dir: str | Path,
75
- ) -> epub.EpubBook:
76
- """
77
- Load every file in `image_dir` into the EPUB's image folder.
78
-
79
- :param book: The EpubBook object to modify.
80
- :param image_dir: Path to the directory containing image files.
81
- :return: The same EpubBook instance, with images added.
82
- """
83
- image_dir = Path(image_dir)
84
- if not image_dir.is_dir():
85
- logger.warning("Image directory not found or not a directory: %s", image_dir)
86
- return book
87
-
88
- for img_path in image_dir.iterdir():
89
- if not img_path.is_file():
90
- continue
91
-
92
- suffix = img_path.suffix.lower().lstrip(".")
93
- media_type = _SUPPORTED_IMAGE_MEDIA_TYPES.get(suffix)
94
- if media_type is None:
95
- media_type = _DEFAULT_IMAGE_MEDIA_TYPE
96
- logger.warning(
97
- "Unknown image suffix '%s' - defaulting media_type to %s",
98
- suffix,
99
- media_type,
100
- )
101
-
102
- try:
103
- content = img_path.read_bytes()
104
- item = epub.EpubItem(
105
- uid=f"img_{img_path.stem}",
106
- file_name=f"{EPUB_IMAGE_FOLDER}/{img_path.name}",
107
- media_type=media_type,
108
- content=content,
109
- )
110
- book.add_item(item)
111
- logger.debug("Embedded image: %s", img_path.name)
112
- except Exception:
113
- logger.exception("Failed to embed image %s", img_path)
114
-
115
- return book
116
-
117
-
118
- def add_images_from_dirs(
119
- book: epub.EpubBook,
120
- image_dirs: Iterable[str | Path],
121
- ) -> epub.EpubBook:
122
- """
123
- Add all images from multiple directories into the given EpubBook.
124
-
125
- :param book: The EpubBook object to modify.
126
- :param image_dirs: An iterable of directory paths to scan for images.
127
- :return: The same EpubBook instance, with all images added.
128
- """
129
- for img_dir in image_dirs:
130
- book = add_images_from_dir(book, img_dir)
131
- return book
@@ -1,100 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- novel_downloader.core.exporters.epub_utils.initializer
4
- ------------------------------------------------------
5
-
6
- Initializes an epub.EpubBook object, sets metadata
7
- (identifier, title, author, language, description),
8
- adds a cover, and prepares the initial spine and TOC entries.
9
- """
10
-
11
- import logging
12
- from pathlib import Path
13
- from typing import Any
14
-
15
- from ebooklib import epub
16
-
17
- from novel_downloader.utils.constants import (
18
- EPUB_IMAGE_FOLDER,
19
- EPUB_TEXT_FOLDER,
20
- VOLUME_BORDER_IMAGE_PATH,
21
- )
22
-
23
- logger = logging.getLogger(__name__)
24
-
25
-
26
- def init_epub(
27
- book_info: dict[str, Any],
28
- book_id: str,
29
- intro_html: str,
30
- book_cover_path: Path | None = None,
31
- include_toc: bool = False,
32
- ) -> tuple[epub.EpubBook, list[Any], list[Any]]:
33
- """
34
- Initialize an EPUB book with metadata, optional cover, and intro page.
35
-
36
- :param book_info: Dict with keys 'book_name', 'author', 'summary'.
37
- :param book_id: Book identifier (numeric or string).
38
- :param intro_html: Intro content in XHTML format.
39
- :param book_cover_path: Optional Path to the cover image file.
40
- :param include_toc: Whether to include the <nav> item in the spine.
41
- :return: (book, spine, toc_list)
42
- """
43
- book = epub.EpubBook()
44
- book.set_identifier(str(book_id))
45
- book_name = book_info.get("book_name") or book_info.get("volume_name", "未找到书名")
46
- book.set_title(book_name)
47
- book.set_language("zh-CN")
48
- book.add_author(book_info.get("author", "未找到作者"))
49
- desc = book_info.get("summary") or book_info.get("volume_intro", "未找到作品简介")
50
- book.add_metadata("DC", "description", desc)
51
-
52
- spine = []
53
-
54
- # cover
55
- if book_cover_path:
56
- try:
57
- cover_bytes = book_cover_path.read_bytes()
58
- ext = book_cover_path.suffix.lower()
59
- ext = ext if ext in [".jpg", ".jpeg", ".png"] else ".jpeg"
60
- filename = f"{EPUB_IMAGE_FOLDER}/cover{ext}"
61
- book.set_cover(filename, cover_bytes)
62
- spine.append("cover")
63
- except FileNotFoundError:
64
- logger.info(f"[epub] 封面图片不存在: {book_cover_path}")
65
- except Exception as e:
66
- logger.info(f"[epub] 读取封面失败: {book_cover_path},错误:{e}")
67
-
68
- # 导航菜单
69
- if include_toc:
70
- spine.append("nav")
71
-
72
- # 简介页面
73
- intro = epub.EpubHtml(
74
- title="书籍简介",
75
- file_name=f"{EPUB_TEXT_FOLDER}/intro.xhtml",
76
- lang="zh-CN",
77
- uid="intro",
78
- )
79
- intro.content = intro_html
80
- intro.add_link(href="../Styles/main.css", rel="stylesheet", type="text/css")
81
- book.add_item(intro)
82
- spine.append(intro)
83
-
84
- # 添加卷边框图像 (volume_border.png)
85
- try:
86
- border_bytes = VOLUME_BORDER_IMAGE_PATH.read_bytes()
87
- border_item = epub.EpubItem(
88
- uid="volume-border",
89
- file_name=f"{EPUB_IMAGE_FOLDER}/volume_border.png",
90
- media_type="image/png",
91
- content=border_bytes,
92
- )
93
- book.add_item(border_item)
94
- except FileNotFoundError:
95
- logger.info(f"[epub] 卷边框图片不存在: {VOLUME_BORDER_IMAGE_PATH}")
96
- except Exception as e:
97
- logger.info(f"[epub] 读取卷边框失败: {VOLUME_BORDER_IMAGE_PATH}: {e}")
98
-
99
- toc_list = [epub.Link(intro.file_name, "书籍简介", intro.id)]
100
- return book, spine, toc_list