novel-downloader 1.5.0__py3-none-any.whl → 2.0.1__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 (248) hide show
  1. novel_downloader/__init__.py +1 -1
  2. novel_downloader/cli/__init__.py +1 -3
  3. novel_downloader/cli/clean.py +21 -88
  4. novel_downloader/cli/config.py +26 -21
  5. novel_downloader/cli/download.py +79 -66
  6. novel_downloader/cli/export.py +17 -21
  7. novel_downloader/cli/main.py +1 -1
  8. novel_downloader/cli/search.py +62 -65
  9. novel_downloader/cli/ui.py +156 -0
  10. novel_downloader/config/__init__.py +8 -5
  11. novel_downloader/config/adapter.py +206 -209
  12. novel_downloader/config/{loader.py → file_io.py} +53 -26
  13. novel_downloader/core/__init__.py +5 -5
  14. novel_downloader/core/archived/deqixs/fetcher.py +115 -0
  15. novel_downloader/core/archived/deqixs/parser.py +132 -0
  16. novel_downloader/core/archived/deqixs/searcher.py +89 -0
  17. novel_downloader/core/{searchers/qidian.py → archived/qidian/searcher.py} +12 -20
  18. novel_downloader/core/archived/wanbengo/searcher.py +98 -0
  19. novel_downloader/core/archived/xshbook/searcher.py +93 -0
  20. novel_downloader/core/downloaders/__init__.py +3 -24
  21. novel_downloader/core/downloaders/base.py +49 -23
  22. novel_downloader/core/downloaders/common.py +191 -137
  23. novel_downloader/core/downloaders/qianbi.py +187 -146
  24. novel_downloader/core/downloaders/qidian.py +187 -141
  25. novel_downloader/core/downloaders/registry.py +4 -2
  26. novel_downloader/core/downloaders/signals.py +46 -0
  27. novel_downloader/core/exporters/__init__.py +3 -20
  28. novel_downloader/core/exporters/base.py +33 -37
  29. novel_downloader/core/exporters/common/__init__.py +1 -2
  30. novel_downloader/core/exporters/common/epub.py +15 -10
  31. novel_downloader/core/exporters/common/main_exporter.py +19 -12
  32. novel_downloader/core/exporters/common/txt.py +17 -12
  33. novel_downloader/core/exporters/epub_util.py +59 -29
  34. novel_downloader/core/exporters/linovelib/__init__.py +1 -0
  35. novel_downloader/core/exporters/linovelib/epub.py +23 -25
  36. novel_downloader/core/exporters/linovelib/main_exporter.py +8 -12
  37. novel_downloader/core/exporters/linovelib/txt.py +20 -14
  38. novel_downloader/core/exporters/qidian.py +2 -8
  39. novel_downloader/core/exporters/registry.py +4 -2
  40. novel_downloader/core/exporters/txt_util.py +7 -7
  41. novel_downloader/core/fetchers/__init__.py +54 -48
  42. novel_downloader/core/fetchers/aaatxt.py +83 -0
  43. novel_downloader/core/fetchers/{biquge/session.py → b520.py} +6 -11
  44. novel_downloader/core/fetchers/{base/session.py → base.py} +37 -46
  45. novel_downloader/core/fetchers/{biquge/browser.py → biquyuedu.py} +12 -17
  46. novel_downloader/core/fetchers/dxmwx.py +110 -0
  47. novel_downloader/core/fetchers/eightnovel.py +139 -0
  48. novel_downloader/core/fetchers/{esjzone/session.py → esjzone.py} +19 -12
  49. novel_downloader/core/fetchers/guidaye.py +85 -0
  50. novel_downloader/core/fetchers/hetushu.py +92 -0
  51. novel_downloader/core/fetchers/{qianbi/browser.py → i25zw.py} +19 -28
  52. novel_downloader/core/fetchers/ixdzs8.py +113 -0
  53. novel_downloader/core/fetchers/jpxs123.py +101 -0
  54. novel_downloader/core/fetchers/lewenn.py +83 -0
  55. novel_downloader/core/fetchers/{linovelib/session.py → linovelib.py} +12 -13
  56. novel_downloader/core/fetchers/piaotia.py +105 -0
  57. novel_downloader/core/fetchers/qbtr.py +101 -0
  58. novel_downloader/core/fetchers/{qianbi/session.py → qianbi.py} +5 -10
  59. novel_downloader/core/fetchers/{qidian/session.py → qidian.py} +56 -64
  60. novel_downloader/core/fetchers/quanben5.py +92 -0
  61. novel_downloader/core/fetchers/{base/rate_limiter.py → rate_limiter.py} +2 -2
  62. novel_downloader/core/fetchers/registry.py +5 -16
  63. novel_downloader/core/fetchers/{sfacg/session.py → sfacg.py} +7 -10
  64. novel_downloader/core/fetchers/shencou.py +106 -0
  65. novel_downloader/core/fetchers/shuhaige.py +84 -0
  66. novel_downloader/core/fetchers/tongrenquan.py +84 -0
  67. novel_downloader/core/fetchers/ttkan.py +95 -0
  68. novel_downloader/core/fetchers/wanbengo.py +83 -0
  69. novel_downloader/core/fetchers/xiaoshuowu.py +106 -0
  70. novel_downloader/core/fetchers/xiguashuwu.py +177 -0
  71. novel_downloader/core/fetchers/xs63b.py +171 -0
  72. novel_downloader/core/fetchers/xshbook.py +85 -0
  73. novel_downloader/core/fetchers/{yamibo/session.py → yamibo.py} +19 -12
  74. novel_downloader/core/fetchers/yibige.py +114 -0
  75. novel_downloader/core/interfaces/__init__.py +1 -9
  76. novel_downloader/core/interfaces/downloader.py +6 -2
  77. novel_downloader/core/interfaces/exporter.py +7 -7
  78. novel_downloader/core/interfaces/fetcher.py +6 -19
  79. novel_downloader/core/interfaces/parser.py +7 -8
  80. novel_downloader/core/interfaces/searcher.py +9 -1
  81. novel_downloader/core/parsers/__init__.py +49 -12
  82. novel_downloader/core/parsers/aaatxt.py +132 -0
  83. novel_downloader/core/parsers/b520.py +116 -0
  84. novel_downloader/core/parsers/base.py +64 -12
  85. novel_downloader/core/parsers/biquyuedu.py +133 -0
  86. novel_downloader/core/parsers/dxmwx.py +162 -0
  87. novel_downloader/core/parsers/eightnovel.py +224 -0
  88. novel_downloader/core/parsers/esjzone.py +64 -69
  89. novel_downloader/core/parsers/guidaye.py +128 -0
  90. novel_downloader/core/parsers/hetushu.py +139 -0
  91. novel_downloader/core/parsers/i25zw.py +137 -0
  92. novel_downloader/core/parsers/ixdzs8.py +186 -0
  93. novel_downloader/core/parsers/jpxs123.py +137 -0
  94. novel_downloader/core/parsers/lewenn.py +142 -0
  95. novel_downloader/core/parsers/linovelib.py +48 -64
  96. novel_downloader/core/parsers/piaotia.py +189 -0
  97. novel_downloader/core/parsers/qbtr.py +136 -0
  98. novel_downloader/core/parsers/qianbi.py +48 -50
  99. novel_downloader/core/parsers/qidian/main_parser.py +756 -48
  100. novel_downloader/core/parsers/qidian/utils/__init__.py +3 -21
  101. novel_downloader/core/parsers/qidian/utils/decryptor_fetcher.py +1 -1
  102. novel_downloader/core/parsers/qidian/utils/node_decryptor.py +4 -4
  103. novel_downloader/core/parsers/quanben5.py +103 -0
  104. novel_downloader/core/parsers/registry.py +5 -16
  105. novel_downloader/core/parsers/sfacg.py +38 -45
  106. novel_downloader/core/parsers/shencou.py +215 -0
  107. novel_downloader/core/parsers/shuhaige.py +111 -0
  108. novel_downloader/core/parsers/tongrenquan.py +116 -0
  109. novel_downloader/core/parsers/ttkan.py +132 -0
  110. novel_downloader/core/parsers/wanbengo.py +191 -0
  111. novel_downloader/core/parsers/xiaoshuowu.py +173 -0
  112. novel_downloader/core/parsers/xiguashuwu.py +429 -0
  113. novel_downloader/core/parsers/xs63b.py +161 -0
  114. novel_downloader/core/parsers/xshbook.py +134 -0
  115. novel_downloader/core/parsers/yamibo.py +87 -131
  116. novel_downloader/core/parsers/yibige.py +166 -0
  117. novel_downloader/core/searchers/__init__.py +34 -3
  118. novel_downloader/core/searchers/aaatxt.py +107 -0
  119. novel_downloader/core/searchers/{biquge.py → b520.py} +29 -28
  120. novel_downloader/core/searchers/base.py +112 -36
  121. novel_downloader/core/searchers/dxmwx.py +105 -0
  122. novel_downloader/core/searchers/eightnovel.py +84 -0
  123. novel_downloader/core/searchers/esjzone.py +43 -25
  124. novel_downloader/core/searchers/hetushu.py +92 -0
  125. novel_downloader/core/searchers/i25zw.py +93 -0
  126. novel_downloader/core/searchers/ixdzs8.py +107 -0
  127. novel_downloader/core/searchers/jpxs123.py +107 -0
  128. novel_downloader/core/searchers/piaotia.py +100 -0
  129. novel_downloader/core/searchers/qbtr.py +106 -0
  130. novel_downloader/core/searchers/qianbi.py +74 -40
  131. novel_downloader/core/searchers/quanben5.py +144 -0
  132. novel_downloader/core/searchers/registry.py +24 -8
  133. novel_downloader/core/searchers/shuhaige.py +124 -0
  134. novel_downloader/core/searchers/tongrenquan.py +110 -0
  135. novel_downloader/core/searchers/ttkan.py +92 -0
  136. novel_downloader/core/searchers/xiaoshuowu.py +122 -0
  137. novel_downloader/core/searchers/xiguashuwu.py +95 -0
  138. novel_downloader/core/searchers/xs63b.py +104 -0
  139. novel_downloader/locales/en.json +34 -85
  140. novel_downloader/locales/zh.json +35 -86
  141. novel_downloader/models/__init__.py +21 -22
  142. novel_downloader/models/book.py +44 -0
  143. novel_downloader/models/config.py +4 -37
  144. novel_downloader/models/login.py +1 -1
  145. novel_downloader/models/search.py +5 -0
  146. novel_downloader/resources/config/settings.toml +8 -70
  147. novel_downloader/resources/json/xiguashuwu.json +718 -0
  148. novel_downloader/utils/__init__.py +13 -24
  149. novel_downloader/utils/chapter_storage.py +5 -5
  150. novel_downloader/utils/constants.py +4 -31
  151. novel_downloader/utils/cookies.py +38 -35
  152. novel_downloader/utils/crypto_utils/__init__.py +7 -0
  153. novel_downloader/utils/crypto_utils/aes_util.py +90 -0
  154. novel_downloader/utils/crypto_utils/aes_v1.py +619 -0
  155. novel_downloader/utils/crypto_utils/aes_v2.py +1143 -0
  156. novel_downloader/utils/crypto_utils/rc4.py +54 -0
  157. novel_downloader/utils/epub/__init__.py +3 -4
  158. novel_downloader/utils/epub/builder.py +6 -6
  159. novel_downloader/utils/epub/constants.py +62 -21
  160. novel_downloader/utils/epub/documents.py +95 -201
  161. novel_downloader/utils/epub/models.py +8 -22
  162. novel_downloader/utils/epub/utils.py +73 -106
  163. novel_downloader/utils/file_utils/__init__.py +2 -23
  164. novel_downloader/utils/file_utils/io.py +53 -188
  165. novel_downloader/utils/file_utils/normalize.py +1 -7
  166. novel_downloader/utils/file_utils/sanitize.py +4 -15
  167. novel_downloader/utils/fontocr/__init__.py +5 -14
  168. novel_downloader/utils/fontocr/core.py +216 -0
  169. novel_downloader/utils/fontocr/loader.py +50 -0
  170. novel_downloader/utils/logger.py +81 -65
  171. novel_downloader/utils/network.py +17 -41
  172. novel_downloader/utils/state.py +4 -90
  173. novel_downloader/utils/text_utils/__init__.py +1 -7
  174. novel_downloader/utils/text_utils/diff_display.py +5 -7
  175. novel_downloader/utils/text_utils/text_cleaner.py +39 -30
  176. novel_downloader/utils/text_utils/truncate_utils.py +3 -14
  177. novel_downloader/utils/time_utils/__init__.py +5 -11
  178. novel_downloader/utils/time_utils/datetime_utils.py +20 -29
  179. novel_downloader/utils/time_utils/sleep_utils.py +55 -49
  180. novel_downloader/web/__init__.py +13 -0
  181. novel_downloader/web/components/__init__.py +11 -0
  182. novel_downloader/web/components/navigation.py +35 -0
  183. novel_downloader/web/main.py +66 -0
  184. novel_downloader/web/pages/__init__.py +17 -0
  185. novel_downloader/web/pages/download.py +78 -0
  186. novel_downloader/web/pages/progress.py +147 -0
  187. novel_downloader/web/pages/search.py +329 -0
  188. novel_downloader/web/services/__init__.py +17 -0
  189. novel_downloader/web/services/client_dialog.py +164 -0
  190. novel_downloader/web/services/cred_broker.py +113 -0
  191. novel_downloader/web/services/cred_models.py +35 -0
  192. novel_downloader/web/services/task_manager.py +264 -0
  193. novel_downloader-2.0.1.dist-info/METADATA +172 -0
  194. novel_downloader-2.0.1.dist-info/RECORD +206 -0
  195. {novel_downloader-1.5.0.dist-info → novel_downloader-2.0.1.dist-info}/entry_points.txt +1 -1
  196. novel_downloader/core/downloaders/biquge.py +0 -29
  197. novel_downloader/core/downloaders/esjzone.py +0 -29
  198. novel_downloader/core/downloaders/linovelib.py +0 -29
  199. novel_downloader/core/downloaders/sfacg.py +0 -29
  200. novel_downloader/core/downloaders/yamibo.py +0 -29
  201. novel_downloader/core/exporters/biquge.py +0 -22
  202. novel_downloader/core/exporters/esjzone.py +0 -22
  203. novel_downloader/core/exporters/qianbi.py +0 -22
  204. novel_downloader/core/exporters/sfacg.py +0 -22
  205. novel_downloader/core/exporters/yamibo.py +0 -22
  206. novel_downloader/core/fetchers/base/__init__.py +0 -14
  207. novel_downloader/core/fetchers/base/browser.py +0 -422
  208. novel_downloader/core/fetchers/biquge/__init__.py +0 -14
  209. novel_downloader/core/fetchers/esjzone/__init__.py +0 -14
  210. novel_downloader/core/fetchers/esjzone/browser.py +0 -209
  211. novel_downloader/core/fetchers/linovelib/__init__.py +0 -14
  212. novel_downloader/core/fetchers/linovelib/browser.py +0 -198
  213. novel_downloader/core/fetchers/qianbi/__init__.py +0 -14
  214. novel_downloader/core/fetchers/qidian/__init__.py +0 -14
  215. novel_downloader/core/fetchers/qidian/browser.py +0 -326
  216. novel_downloader/core/fetchers/sfacg/__init__.py +0 -14
  217. novel_downloader/core/fetchers/sfacg/browser.py +0 -194
  218. novel_downloader/core/fetchers/yamibo/__init__.py +0 -14
  219. novel_downloader/core/fetchers/yamibo/browser.py +0 -234
  220. novel_downloader/core/parsers/biquge.py +0 -139
  221. novel_downloader/core/parsers/qidian/book_info_parser.py +0 -90
  222. novel_downloader/core/parsers/qidian/chapter_encrypted.py +0 -528
  223. novel_downloader/core/parsers/qidian/chapter_normal.py +0 -157
  224. novel_downloader/core/parsers/qidian/chapter_router.py +0 -68
  225. novel_downloader/core/parsers/qidian/utils/helpers.py +0 -114
  226. novel_downloader/models/chapter.py +0 -25
  227. novel_downloader/models/types.py +0 -13
  228. novel_downloader/tui/__init__.py +0 -7
  229. novel_downloader/tui/app.py +0 -32
  230. novel_downloader/tui/main.py +0 -17
  231. novel_downloader/tui/screens/__init__.py +0 -14
  232. novel_downloader/tui/screens/home.py +0 -198
  233. novel_downloader/tui/screens/login.py +0 -74
  234. novel_downloader/tui/styles/home_layout.tcss +0 -79
  235. novel_downloader/tui/widgets/richlog_handler.py +0 -24
  236. novel_downloader/utils/cache.py +0 -24
  237. novel_downloader/utils/crypto_utils.py +0 -71
  238. novel_downloader/utils/fontocr/hash_store.py +0 -280
  239. novel_downloader/utils/fontocr/hash_utils.py +0 -103
  240. novel_downloader/utils/fontocr/model_loader.py +0 -69
  241. novel_downloader/utils/fontocr/ocr_v1.py +0 -315
  242. novel_downloader/utils/fontocr/ocr_v2.py +0 -764
  243. novel_downloader/utils/fontocr/ocr_v3.py +0 -744
  244. novel_downloader-1.5.0.dist-info/METADATA +0 -196
  245. novel_downloader-1.5.0.dist-info/RECORD +0 -164
  246. {novel_downloader-1.5.0.dist-info → novel_downloader-2.0.1.dist-info}/WHEEL +0 -0
  247. {novel_downloader-1.5.0.dist-info → novel_downloader-2.0.1.dist-info}/licenses/LICENSE +0 -0
  248. {novel_downloader-1.5.0.dist-info → novel_downloader-2.0.1.dist-info}/top_level.txt +0 -0
@@ -1,110 +1,59 @@
1
1
  {
2
- "cli_help": "Novel Downloader CLI tool.",
2
+ "help_cli": "Novel Downloader CLI tool.",
3
3
  "help_config": "Path to config file",
4
- "help_download": "Download novels",
4
+ "help_download": "Download full novels by book IDs.",
5
5
  "help_clean": "Clean cache and configuration files",
6
6
  "help_export": "Export downloaded novels",
7
+ "help_search": "search for a book on one or more sites",
7
8
 
8
- "settings_help": "Configure downloader settings.",
9
- "settings_set_lang_help": "Switch language between Chinese and English.",
10
- "settings_set_config_help": "Set and save a custom YAML configuration file.",
11
- "settings_init_help": "Initialize default config and rule files in the current directory.",
12
- "settings_init_force_help": "Force overwrite if file already exists.",
13
- "settings_init_exists": "File already exists: {filename}",
14
- "settings_init_confirm_overwrite": "Do you want to overwrite {filename}?",
15
- "settings_init_skip": "Skipped: {filename}",
16
- "settings_init_copy": "Copied: {filename}",
17
- "settings_init_overwrite": "Overwriting existing file: {filename}",
18
- "settings_init_error": "Failed to copy {filename}: {err}",
19
- "settings_set_lang": "Language switched to {lang}",
20
- "settings_set_config": "Configuration file saved from {path}",
21
- "settings_set_config_fail": "Failed to save config file: {err}",
22
- "settings_set_cookies_help": "Set cookies for a specific site.",
23
- "settings_set_cookies_prompt_site": "Site identifier (e.g. 'qidian')",
24
- "settings_set_cookies_prompt_payload": "Cookie payload (JSON or 'k=v; k2=v2')",
25
- "settings_set_cookies_success": "Cookies for site '{site}' have been updated.",
26
- "settings_set_cookies_fail": "Failed to set cookies: {err}",
27
- "settings_add_hash_help": "Add image hashes manually or from file",
28
- "settings_add_hash_path_help": "JSON path mapping image to label",
29
- "settings_add_hash_prompt_img": "Image path",
30
- "settings_add_hash_prompt_label": "Label for image",
31
- "settings_add_hash_prompt_tip": "Enter image path and label. Leave blank or type 'exit' to finish.",
32
- "settings_add_hash_path_invalid": "Path does not exist. Try again.",
33
- "settings_add_hash_added": "Added image '{img}' under label '{label}'",
34
- "settings_add_hash_failed": "Failed to add image: {err}",
35
- "settings_add_hash_loaded": "Added images from mapping file: {path}",
36
- "settings_add_hash_load_fail": "Failed to load image map: {err}",
37
- "settings_add_hash_saved": "Image hash store saved",
38
-
39
- "interactive_help": "Interactive mode for novel selection and preview.",
40
- "interactive_option_download": "Download novels",
41
- "interactive_browse_help": "Browse available novels interactively.",
42
- "interactive_prompt_book_ids": "Enter book IDs to download, separated by spaces",
43
- "interactive_preview_help": "Preview chapters before downloading.",
44
- "interactive_no_sub": "No subcommand provided. Please select an action:",
45
- "interactive_option_browse": "Browse novels",
46
- "interactive_option_preview": "Preview chapters",
47
- "interactive_option_exit": "Exit",
48
- "interactive_prompt_choice": "Enter your choice",
49
- "interactive_browse_start": "Starting interactive browser...",
50
- "interactive_preview_start": "Previewing chapters...",
51
- "interactive_exit": "Exiting.",
9
+ "config_set_lang_help": "Switch language between Chinese and English.",
10
+ "config_set_config_help": "Set and save a custom YAML configuration file.",
11
+ "config_init_help": "Initialize default config and rule files in the current directory.",
12
+ "config_init_force_help": "Force overwrite if file already exists.",
13
+ "config_init_exists": "File already exists: {filename}",
14
+ "config_init_confirm_overwrite": "Do you want to overwrite {filename}?",
15
+ "config_init_skip": "Skipped: {filename}",
16
+ "config_init_copy": "Copied: {filename}",
17
+ "config_init_overwrite": "Overwriting existing file: {filename}",
18
+ "config_init_error": "Failed to copy {filename}: {err}",
19
+ "config_set_lang": "Language switched to {lang}",
20
+ "config_set_config": "Configuration file saved from {path}",
21
+ "config_set_config_fail": "Failed to save config file: {err}",
52
22
 
53
- "download_help": "Download full novels by book IDs.",
54
- "download_short_help": "Download novels",
23
+ "download_progress_prefix": "Download progress",
55
24
  "download_option_site": "Website source, default is '{default}'.",
56
- "download_using_config": "Using config: {path}",
57
25
  "download_site_info": "Site: {site}",
58
- "download_site_mode": "Mode: {mode}",
59
26
  "download_no_ids": "No book IDs provided. Exiting.",
60
27
  "download_fail_get_ids": "Failed to get book IDs from config: {err}",
61
28
  "download_config_load_fail": "Failed to load config: {err}",
62
29
  "download_only_example": "Only example book IDs found (e.g. '{example}').",
63
30
  "download_edit_config": "Please edit your config and replace them with real book IDs.",
64
31
  "download_downloading": "Downloading book {book_id} from {site}...",
65
- "download_prompt_parse": "Parse...",
66
32
  "download_login_failed": "Download login failed: please check your cookies or account credentials and try again.",
67
33
  "download_book_ids": "One or more book IDs to process",
68
34
  "download_option_start": "Start chapter ID (applies to the first book ID only)",
69
35
  "download_option_end": "End chapter ID (applies to the first book ID only)",
36
+ "download_option_no_export": "Do not export after download; download only.",
37
+ "download_export_skipped": "Download-only mode: export step will be skipped.",
38
+
70
39
  "login_description": "Description",
71
40
  "login_hint": "Hint",
72
- "login_manual_prompt": ">> Please complete login in your browser and press Enter to continue...",
73
41
  "login_use_config": "Using value from config.",
74
- "login_enter_password": "Enter password: ",
75
- "login_enter_cookie": "Enter cookies: ",
76
- "login_enter_value": "Enter value: ",
42
+ "login_enter_password": "Enter password",
43
+ "login_enter_cookie": "Enter cookies",
44
+ "login_enter_value": "Enter value",
77
45
  "login_required_field": "This field is required. Please enter a value.",
78
46
 
79
- "login_prompt_intro": "Manual login is required. Please switch to the browser and log in.",
80
- "login_prompt_press_enter": "Attempt {attempt}/{max_retries}: Press Enter after completing login in the browser...",
81
-
82
- "session_login_prompt_intro": "Failed to restore login from saved cookies. Please log in via browser, then paste the cookie string below.",
83
- "session_login_prompt_paste_cookie": "Attempt {attempt}/{max_retries}: Paste your browser cookie string and press Enter:",
84
- "session_login_prompt_invalid_cookie": "Invalid cookie. Please copy and paste again.",
85
- "session_login_failed": "Login to {site} failed. Please check your credentials or try again later.",
86
-
87
47
  "clean_logs": "Clean log directory",
88
48
  "clean_cache": "Clean scripts and browser cache",
89
- "clean_state": "Clean state files (state.json)",
90
- "clean_data": "Clean data files (e.g. image hashes, browser data)",
91
- "clean_config": "Clean config files (e.g. settings.toml, site rules)",
92
- "clean_models": "Clean downloaded model cache",
93
- "clean_hf_cache": "Clear Hugging Face model cache",
94
- "clean_hf_cache_done": "Hugging Face cache cleared",
95
- "clean_hf_cache_fail": "Failed to clear Hugging Face cache: {err}",
96
- "clean_hf_model": "Clear cached model from Hugging Face",
97
- "clean_hf_model_done": "Cache for model '{repo}' has been cleared",
98
- "clean_hf_model_not_found": "No local cache found for model '{repo}'",
99
- "clean_hf_model_fail": "Failed to clear model cache: {err}",
100
- "clean_hf_cache_all": "Clear all Hugging Face model and dataset cache",
101
- "clean_hf_cache_all_done": "All Hugging Face cache cleared",
102
- "clean_hf_cache_all_fail": "Failed to clear Hugging Face cache: {err}",
49
+ "clean_data": "Clean data files",
50
+ "clean_config": "Clean config files",
103
51
  "clean_all": "Clean all settings, cache, and state files",
104
52
  "clean_yes": "Skip confirmation prompt",
105
- "clean_confirm": "Are you sure you want to delete all local data? (y/N)",
53
+ "clean_confirm": "Are you sure you want to delete all local data?",
106
54
  "clean_nothing": "No clean option specified",
107
55
  "clean_deleted": "Deleted",
56
+ "clean_failed": "Failed to delete: {path}",
108
57
  "clean_not_found": "Not found",
109
58
  "clean_cancelled": "Clean operation cancelled",
110
59
 
@@ -115,12 +64,12 @@
115
64
  "export_success_epub": "Successfully exported {book_id} as EPUB.",
116
65
  "export_failed_epub": "Failed to export {book_id} as EPUB: {err}",
117
66
 
118
- "help_search": "search for a book on one or more sites",
119
- "help_search_sites": "which site keys to search (default: all)",
120
- "help_search_keyword": "keyword to look for",
121
- "help_search_limit": "Maximum number of search results",
122
- "help_search_site_limit": "Maximum number of search results per site",
67
+ "search_sites_help": "which site keys to search (default: all)",
68
+ "search_keyword_help": "keyword to look for",
69
+ "search_limit_help": "Maximum number of search results",
70
+ "search_site_limit_help": "Maximum number of search results per site",
71
+ "search_timeout_help": "Per-request timeout in seconds (default: {secs})",
72
+
123
73
  "no_results": "No results found.",
124
- "prompt_select_index": "Select a result by number (or press Enter to cancel): ",
125
- "invalid_selection": "Invalid choice, please try again."
74
+ "prompt_select_index": "Select a book by number (or press Enter to cancel)"
126
75
  }
@@ -1,61 +1,28 @@
1
1
  {
2
- "cli_help": "小说下载器 CLI 工具",
2
+ "help_cli": "小说下载器 CLI 工具",
3
3
  "help_config": "配置文件路径",
4
- "help_download": "下载小说",
4
+ "help_download": "按书籍 ID 下载小说",
5
5
  "help_clean": "清理缓存和配置文件",
6
6
  "help_export": "导出已下载的小说",
7
+ "help_search": "在一个或多个站点搜索书籍",
7
8
 
8
- "settings_help": "配置下载器设置",
9
- "settings_set_lang_help": "在中文和英文之间切换语言",
10
- "settings_set_config_help": "设置并保存自定义 YAML 配置文件",
11
- "settings_init_help": "在当前目录初始化默认配置和规则文件",
12
- "settings_init_force_help": "如果文件已存在则强制覆盖",
13
- "settings_init_exists": "文件已存在: {filename}",
14
- "settings_init_confirm_overwrite": "你确定要覆盖 {filename} 吗?",
15
- "settings_init_skip": "文件已存在: {filename}, 已跳过",
16
- "settings_init_copy": "已复制默认文件: {filename}",
17
- "settings_init_overwrite": "已覆盖现有文件: {filename}",
18
- "settings_init_error": "复制 {filename} 失败: {err}",
19
- "settings_set_lang": "语言已切换为 {lang}",
20
- "settings_set_config": "已从 {path} 保存配置文件",
21
- "settings_set_config_fail": "保存配置文件失败: {err}",
22
- "settings_set_cookies_help": "为特定站点设置 Cookie",
23
- "settings_set_cookies_prompt_site": "站点标识 (例如 'qidian')",
24
- "settings_set_cookies_prompt_payload": "Cookie 内容 (JSON 或 'k=v; k2=v2')",
25
- "settings_set_cookies_success": "已更新站点 '{site}' 的 Cookie",
26
- "settings_set_cookies_fail": "设置 Cookie 失败: {err}",
27
- "settings_add_hash_help": "手动或通过文件添加图像哈希",
28
- "settings_add_hash_path_help": "映射图片路径到标签的 JSON 文件路径",
29
- "settings_add_hash_prompt_img": "图片路径",
30
- "settings_add_hash_prompt_label": "该图片对应的标签",
31
- "settings_add_hash_prompt_tip": "请输入图片路径和标签, 输入空行或 'exit' 退出",
32
- "settings_add_hash_path_invalid": "路径不存在, 请重试",
33
- "settings_add_hash_added": "已添加图片 '{img}', 标签为 '{label}'",
34
- "settings_add_hash_failed": "添加图片失败: {err}",
35
- "settings_add_hash_loaded": "已从映射文件导入图片: {path}",
36
- "settings_add_hash_load_fail": "加载映射文件失败: {err}",
37
- "settings_add_hash_saved": "图像哈希库已保存",
38
-
39
- "interactive_help": "小说选择和预览的交互式模式",
40
- "interactive_option_download": "下载小说",
41
- "interactive_browse_help": "以交互方式浏览可用小说",
42
- "interactive_prompt_book_ids": "请输入要下载的书籍 ID, 用空格分隔",
43
- "interactive_preview_help": "下载前预览章节",
44
- "interactive_no_sub": "未提供子命令请选择一项操作:",
45
- "interactive_option_browse": "浏览小说",
46
- "interactive_option_preview": "预览章节",
47
- "interactive_option_exit": "退出",
48
- "interactive_prompt_choice": "请输入你的选择",
49
- "interactive_browse_start": "启动交互式浏览器...",
50
- "interactive_preview_start": "正在预览章节...",
51
- "interactive_exit": "正在退出",
9
+ "config_set_lang_help": "在中文和英文之间切换语言",
10
+ "config_set_config_help": "设置并保存自定义 YAML 配置文件",
11
+ "config_init_help": "在当前目录初始化默认配置和规则文件",
12
+ "config_init_force_help": "如果文件已存在则强制覆盖",
13
+ "config_init_exists": "文件已存在: {filename}",
14
+ "config_init_confirm_overwrite": "你确定要覆盖 {filename} 吗?",
15
+ "config_init_skip": "文件已存在: {filename}, 已跳过",
16
+ "config_init_copy": "已复制默认文件: {filename}",
17
+ "config_init_overwrite": "已覆盖现有文件: {filename}",
18
+ "config_init_error": "复制 {filename} 失败: {err}",
19
+ "config_set_lang": "语言已切换为 {lang}",
20
+ "config_set_config": "已从 {path} 保存配置文件",
21
+ "config_set_config_fail": "保存配置文件失败: {err}",
52
22
 
53
- "download_help": "按书籍 ID 下载完整小说",
54
- "download_short_help": "下载小说",
23
+ "download_progress_prefix": "下载进度",
55
24
  "download_option_site": "网站来源, 默认为 '{default}'",
56
- "download_using_config": "使用配置: {path}",
57
25
  "download_site_info": "站点: {site}",
58
- "download_site_mode": "使用模式: {mode}",
59
26
  "download_no_ids": "未提供书籍 ID, 正在退出",
60
27
  "download_fail_get_ids": "从配置获取书籍 ID 失败: {err}",
61
28
  "download_config_load_fail": "加载配置失败: {err}",
@@ -63,46 +30,28 @@
63
30
  "download_edit_config": "请编辑配置并将示例 ID 替换为真实书籍 ID",
64
31
  "download_downloading": "正在从 {site} 下载书籍 {book_id}...",
65
32
  "download_login_failed": "登录失败: 请检查您的 Cookie 或账户信息后重试",
66
- "download_prompt_parse": "结束...",
67
33
  "download_book_ids": "要处理的一个或多个小说 ID",
68
34
  "download_option_start": "起始章节 ID (仅用于第一个书籍 ID)",
69
35
  "download_option_end": "结束章节 ID (仅用于第一个书籍 ID)",
36
+ "download_option_no_export": "仅下载 (不进行导出)",
37
+ "download_export_skipped": "仅下载模式: 将跳过导出步骤",
38
+
70
39
  "login_description": "说明",
71
40
  "login_hint": "提示",
72
- "login_manual_prompt": ">> 请在浏览器中完成登录后按回车继续...",
73
41
  "login_use_config": "使用配置中的默认值",
74
- "login_enter_password": "请输入密码: ",
75
- "login_enter_cookie": "请输入 Cookie: ",
76
- "login_enter_value": "请输入值: ",
42
+ "login_enter_password": "请输入密码",
43
+ "login_enter_cookie": "请输入 Cookie",
44
+ "login_enter_value": "请输入值",
77
45
  "login_required_field": "该字段是必填项, 请重新输入",
78
46
 
79
- "login_prompt_intro": "需要手动登录, 请切换到浏览器窗口完成登录",
80
- "login_prompt_press_enter": "第 {attempt}/{max_retries} 次尝试: 请在浏览器中完成登录后按回车键...",
81
-
82
- "session_login_prompt_intro": "尝试使用历史 Cookie 恢复登录失败, 请在浏览器登录后从开发者工具复制 Cookie 粘贴至下方",
83
- "session_login_prompt_paste_cookie": "第 {attempt}/{max_retries} 次尝试, 请粘贴 Cookie 字符串并回车:",
84
- "session_login_prompt_invalid_cookie": "Cookie 格式不正确, 请重新复制粘贴",
85
- "session_login_failed": "登录 {site} 失败, 请检查账号或稍后再试",
86
-
47
+ "clean_failed": "删除失败: {path}",
87
48
  "clean_logs": "清理日志目录",
88
49
  "clean_cache": "清理脚本和浏览器缓存",
89
- "clean_state": "清理状态文件 (state.json)",
90
- "clean_data": "清理数据文件 (如 image hashes, 浏览器数据)",
91
- "clean_config": "清理配置文件 (如 settings.toml 和规则)",
92
- "clean_models": "清理模型缓存目录",
93
- "clean_hf_cache": "清理 Hugging Face 下载缓存",
94
- "clean_hf_cache_done": "已清除 Hugging Face 本地缓存",
95
- "clean_hf_cache_fail": "清除 Hugging Face 缓存失败: {err}",
96
- "clean_hf_model": "清理 Hugging Face 中模型缓存",
97
- "clean_hf_model_done": "已清除模型 '{repo}' 的缓存",
98
- "clean_hf_model_not_found": "未发现模型 '{repo}' 的本地缓存",
99
- "clean_hf_model_fail": "清理模型缓存失败: {err}",
100
- "clean_hf_cache_all": "清理所有 Hugging Face 模型与数据集缓存",
101
- "clean_hf_cache_all_done": "已清除所有 Hugging Face 缓存",
102
- "clean_hf_cache_all_fail": "清除 Hugging Face 缓存失败: {err}",
50
+ "clean_data": "清理数据文件",
51
+ "clean_config": "清理配置文件",
103
52
  "clean_all": "清理所有配置, 缓存与状态",
104
53
  "clean_yes": "跳过确认提示",
105
- "clean_confirm": "确认要删除所有本地数据? (y/N)",
54
+ "clean_confirm": "确认要删除所有本地数据?",
106
55
  "clean_nothing": "未指定任何要清理的内容",
107
56
  "clean_deleted": "已删除",
108
57
  "clean_not_found": "未找到",
@@ -110,17 +59,17 @@
110
59
 
111
60
  "export_format_help": "导出格式: txt、epub 或 all",
112
61
  "export_processing": "正在导出小说 {book_id}, 格式: {format}",
113
- "export_success_txt": "成功将 {book_id} 导出为 TXT",
62
+ "export_success_txt": "成功将 {book_id} 导出为 TXT",
114
63
  "export_failed_txt": "导出 {book_id} 为 TXT 失败: {err}",
115
64
  "export_success_epub": "成功将 {book_id} 导出为 EPUB",
116
65
  "export_failed_epub": "导出 {book_id} 为 EPUB 失败: {err}",
117
66
 
118
- "help_search": "在一个或多个站点搜索书籍",
119
- "help_search_sites": "要搜索的站点键 (默认为全部)",
120
- "help_search_keyword": "要搜索的关键字",
121
- "help_search_limit": "总体搜索结果数量上限",
122
- "help_search_site_limit": "单站点搜索结果数量上限",
67
+ "search_sites_help": "要搜索的站点键 (默认为全部)",
68
+ "search_keyword_help": "要搜索的关键字",
69
+ "search_limit_help": "总体搜索结果数量上限",
70
+ "search_site_limit_help": "单站点搜索结果数量上限",
71
+ "search_timeout_help": "每次请求的超时时间 (秒) (默认:{secs})",
72
+
123
73
  "no_results": "未找到结果",
124
- "prompt_select_index": "通过编号选择结果 (或按回车取消): ",
125
- "invalid_selection": "无效选择, 请重试。"
74
+ "prompt_select_index": "通过编号选择书籍 (或按回车取消)"
126
75
  }
@@ -3,26 +3,9 @@
3
3
  novel_downloader.models
4
4
  -----------------------
5
5
 
6
+ Data models and configuration classes.
6
7
  """
7
8
 
8
- from .chapter import ChapterDict
9
- from .config import (
10
- BookConfig,
11
- DownloaderConfig,
12
- ExporterConfig,
13
- FetcherConfig,
14
- ParserConfig,
15
- TextCleanerConfig,
16
- )
17
- from .login import LoginField
18
- from .search import SearchResult
19
- from .types import (
20
- BrowserType,
21
- LogLevel,
22
- ModeType,
23
- SplitMode,
24
- )
25
-
26
9
  __all__ = [
27
10
  "BookConfig",
28
11
  "DownloaderConfig",
@@ -30,11 +13,27 @@ __all__ = [
30
13
  "FetcherConfig",
31
14
  "ExporterConfig",
32
15
  "TextCleanerConfig",
16
+ "BookInfoDict",
33
17
  "ChapterDict",
18
+ "ChapterInfoDict",
19
+ "VolumeInfoDict",
34
20
  "LoginField",
35
21
  "SearchResult",
36
- "BrowserType",
37
- "ModeType",
38
- "SplitMode",
39
- "LogLevel",
40
22
  ]
23
+
24
+ from .book import (
25
+ BookInfoDict,
26
+ ChapterDict,
27
+ ChapterInfoDict,
28
+ VolumeInfoDict,
29
+ )
30
+ from .config import (
31
+ BookConfig,
32
+ DownloaderConfig,
33
+ ExporterConfig,
34
+ FetcherConfig,
35
+ ParserConfig,
36
+ TextCleanerConfig,
37
+ )
38
+ from .login import LoginField
39
+ from .search import SearchResult
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ novel_downloader.models.book
4
+ ----------------------------
5
+
6
+ """
7
+
8
+ from typing import Any, NotRequired, TypedDict
9
+
10
+
11
+ class ChapterDict(TypedDict):
12
+ id: str
13
+ title: str
14
+ content: str
15
+ extra: dict[str, Any]
16
+
17
+
18
+ class ChapterInfoDict(TypedDict):
19
+ title: str
20
+ url: str
21
+ chapterId: str
22
+
23
+
24
+ class VolumeInfoDict(TypedDict):
25
+ volume_name: str
26
+ volume_cover: NotRequired[str]
27
+ update_time: NotRequired[str]
28
+ word_count: NotRequired[str]
29
+ volume_intro: NotRequired[str]
30
+ chapters: list[ChapterInfoDict]
31
+
32
+
33
+ class BookInfoDict(TypedDict):
34
+ book_name: str
35
+ author: str
36
+ cover_url: str
37
+ update_time: str
38
+ summary: str
39
+ extra: dict[str, Any]
40
+ volumes: list[VolumeInfoDict]
41
+ tags: NotRequired[list[str]]
42
+ word_count: NotRequired[str]
43
+ serial_status: NotRequired[str]
44
+ summary_brief: NotRequired[str]
@@ -5,26 +5,11 @@ novel_downloader.models.config
5
5
 
6
6
  Defines structured configuration models using dataclasses for each
7
7
  major component in the novel_downloader pipeline.
8
-
9
- Each config section corresponds to a specific stage of the pipeline:
10
- - RequesterConfig: network settings for requests and DrissionPage
11
- - DownloaderConfig: chapter download behavior and local raw data paths
12
- - ParserConfig: font decoding, cache handling, and debug options
13
- - SaverConfig: output formatting, export formats, and filename templates
14
-
15
- These models are used to map loaded YAML or JSON config data into
16
- strongly typed Python objects for safer and cleaner access.
17
8
  """
18
9
 
19
10
  from dataclasses import dataclass, field
20
11
  from typing import NotRequired, TypedDict
21
12
 
22
- from .types import (
23
- BrowserType,
24
- ModeType,
25
- SplitMode,
26
- )
27
-
28
13
 
29
14
  @dataclass
30
15
  class FetcherConfig:
@@ -32,16 +17,12 @@ class FetcherConfig:
32
17
  retry_times: int = 3
33
18
  backoff_factor: float = 2.0
34
19
  timeout: float = 30.0
35
- headless: bool = False
36
- disable_images: bool = False
37
- mode: ModeType = "session"
38
20
  max_connections: int = 10
39
- max_rps: float | None = None # Maximum requests per second
40
- proxy: str | None = None
21
+ max_rps: float = 1000.0
41
22
  user_agent: str | None = None
42
23
  headers: dict[str, str] | None = None
43
- browser_type: BrowserType = "chromium"
44
24
  verify_ssl: bool = True
25
+ locale_style: str = "simplified"
45
26
 
46
27
 
47
28
  @dataclass
@@ -55,11 +36,7 @@ class DownloaderConfig:
55
36
  skip_existing: bool = True
56
37
  login_required: bool = False
57
38
  save_html: bool = False
58
- mode: ModeType = "session"
59
39
  storage_batch_size: int = 1
60
- username: str = ""
61
- password: str = ""
62
- cookies: str = ""
63
40
 
64
41
 
65
42
  @dataclass
@@ -67,17 +44,8 @@ class ParserConfig:
67
44
  cache_dir: str = "./novel_cache"
68
45
  use_truncation: bool = True
69
46
  decode_font: bool = False
70
- use_freq: bool = False
71
- use_ocr: bool = True
72
- use_vec: bool = False
73
- ocr_version: str = "v1.0"
74
47
  batch_size: int = 32
75
- gpu_mem: int = 500
76
- gpu_id: int | None = None
77
- ocr_weight: float = 0.6
78
- vec_weight: float = 0.4
79
48
  save_font_debug: bool = False
80
- mode: ModeType = "session"
81
49
 
82
50
 
83
51
  @dataclass
@@ -102,9 +70,8 @@ class ExporterConfig:
102
70
  append_timestamp: bool = True
103
71
  filename_template: str = "{title}_{author}"
104
72
  include_cover: bool = True
105
- include_toc: bool = False
106
- include_picture: bool = False
107
- split_mode: SplitMode = "book"
73
+ include_picture: bool = True
74
+ split_mode: str = "book"
108
75
  cleaner_cfg: TextCleanerConfig = field(default_factory=TextCleanerConfig)
109
76
 
110
77
 
@@ -13,7 +13,7 @@ from typing import Literal
13
13
  class LoginField:
14
14
  name: str
15
15
  label: str
16
- type: Literal["text", "password", "cookie", "manual_login"]
16
+ type: Literal["text", "password", "cookie"]
17
17
  required: bool
18
18
  default: str = ""
19
19
  placeholder: str = ""
@@ -11,6 +11,11 @@ from typing import TypedDict
11
11
  class SearchResult(TypedDict, total=True):
12
12
  site: str
13
13
  book_id: str
14
+ book_url: str
15
+ cover_url: str
14
16
  title: str
15
17
  author: str
18
+ latest_chapter: str
19
+ update_date: str
20
+ word_count: str
16
21
  priority: int