novel-downloader 1.4.5__py3-none-any.whl → 2.0.0__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 (276) hide show
  1. novel_downloader/__init__.py +1 -1
  2. novel_downloader/cli/__init__.py +2 -4
  3. novel_downloader/cli/clean.py +21 -88
  4. novel_downloader/cli/config.py +27 -104
  5. novel_downloader/cli/download.py +78 -66
  6. novel_downloader/cli/export.py +20 -21
  7. novel_downloader/cli/main.py +3 -1
  8. novel_downloader/cli/search.py +120 -0
  9. novel_downloader/cli/ui.py +156 -0
  10. novel_downloader/config/__init__.py +10 -14
  11. novel_downloader/config/adapter.py +195 -99
  12. novel_downloader/config/{loader.py → file_io.py} +53 -27
  13. novel_downloader/core/__init__.py +14 -13
  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/archived/qidian/searcher.py +79 -0
  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 +8 -30
  21. novel_downloader/core/downloaders/base.py +182 -30
  22. novel_downloader/core/downloaders/common.py +217 -384
  23. novel_downloader/core/downloaders/qianbi.py +332 -4
  24. novel_downloader/core/downloaders/qidian.py +250 -290
  25. novel_downloader/core/downloaders/registry.py +69 -0
  26. novel_downloader/core/downloaders/signals.py +46 -0
  27. novel_downloader/core/exporters/__init__.py +8 -26
  28. novel_downloader/core/exporters/base.py +107 -31
  29. novel_downloader/core/exporters/common/__init__.py +3 -4
  30. novel_downloader/core/exporters/common/epub.py +92 -171
  31. novel_downloader/core/exporters/common/main_exporter.py +14 -67
  32. novel_downloader/core/exporters/common/txt.py +90 -86
  33. novel_downloader/core/exporters/epub_util.py +184 -1327
  34. novel_downloader/core/exporters/linovelib/__init__.py +3 -2
  35. novel_downloader/core/exporters/linovelib/epub.py +165 -222
  36. novel_downloader/core/exporters/linovelib/main_exporter.py +10 -71
  37. novel_downloader/core/exporters/linovelib/txt.py +76 -66
  38. novel_downloader/core/exporters/qidian.py +15 -11
  39. novel_downloader/core/exporters/registry.py +55 -0
  40. novel_downloader/core/exporters/txt_util.py +67 -0
  41. novel_downloader/core/fetchers/__init__.py +57 -56
  42. novel_downloader/core/fetchers/aaatxt.py +83 -0
  43. novel_downloader/core/fetchers/{biquge/session.py → b520.py} +10 -10
  44. novel_downloader/core/fetchers/{base/session.py → base.py} +63 -47
  45. novel_downloader/core/fetchers/biquyuedu.py +83 -0
  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} +23 -11
  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} +22 -26
  52. novel_downloader/core/fetchers/ixdzs8.py +113 -0
  53. novel_downloader/core/fetchers/jpxs123.py +101 -0
  54. novel_downloader/core/fetchers/{biquge/browser.py → lewenn.py} +15 -15
  55. novel_downloader/core/fetchers/{linovelib/session.py → linovelib.py} +16 -12
  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} +9 -9
  59. novel_downloader/core/fetchers/{qidian/session.py → qidian.py} +55 -40
  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 +60 -0
  63. novel_downloader/core/fetchers/{sfacg/session.py → sfacg.py} +11 -9
  64. novel_downloader/core/fetchers/shencou.py +106 -0
  65. novel_downloader/core/fetchers/{common/browser.py → shuhaige.py} +24 -19
  66. novel_downloader/core/fetchers/tongrenquan.py +84 -0
  67. novel_downloader/core/fetchers/ttkan.py +95 -0
  68. novel_downloader/core/fetchers/{common/session.py → wanbengo.py} +21 -17
  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} +23 -11
  74. novel_downloader/core/fetchers/yibige.py +114 -0
  75. novel_downloader/core/interfaces/__init__.py +8 -14
  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 +4 -17
  79. novel_downloader/core/interfaces/parser.py +5 -6
  80. novel_downloader/core/interfaces/searcher.py +26 -0
  81. novel_downloader/core/parsers/__init__.py +58 -22
  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 +63 -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/main_parser.py → esjzone.py} +67 -67
  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/main_parser.py → linovelib.py} +54 -65
  96. novel_downloader/core/parsers/piaotia.py +189 -0
  97. novel_downloader/core/parsers/qbtr.py +136 -0
  98. novel_downloader/core/parsers/{qianbi/main_parser.py → qianbi.py} +54 -51
  99. novel_downloader/core/parsers/qidian/__init__.py +2 -2
  100. novel_downloader/core/parsers/qidian/book_info_parser.py +58 -59
  101. novel_downloader/core/parsers/qidian/chapter_encrypted.py +290 -346
  102. novel_downloader/core/parsers/qidian/chapter_normal.py +25 -56
  103. novel_downloader/core/parsers/qidian/main_parser.py +19 -57
  104. novel_downloader/core/parsers/qidian/utils/__init__.py +12 -11
  105. novel_downloader/core/parsers/qidian/utils/decryptor_fetcher.py +6 -7
  106. novel_downloader/core/parsers/qidian/utils/fontmap_recover.py +143 -0
  107. novel_downloader/core/parsers/qidian/utils/helpers.py +0 -4
  108. novel_downloader/core/parsers/qidian/utils/node_decryptor.py +2 -2
  109. novel_downloader/core/parsers/quanben5.py +103 -0
  110. novel_downloader/core/parsers/registry.py +57 -0
  111. novel_downloader/core/parsers/{sfacg/main_parser.py → sfacg.py} +46 -48
  112. novel_downloader/core/parsers/shencou.py +215 -0
  113. novel_downloader/core/parsers/shuhaige.py +111 -0
  114. novel_downloader/core/parsers/tongrenquan.py +116 -0
  115. novel_downloader/core/parsers/ttkan.py +132 -0
  116. novel_downloader/core/parsers/wanbengo.py +191 -0
  117. novel_downloader/core/parsers/xiaoshuowu.py +173 -0
  118. novel_downloader/core/parsers/xiguashuwu.py +435 -0
  119. novel_downloader/core/parsers/xs63b.py +161 -0
  120. novel_downloader/core/parsers/xshbook.py +134 -0
  121. novel_downloader/core/parsers/yamibo.py +155 -0
  122. novel_downloader/core/parsers/yibige.py +166 -0
  123. novel_downloader/core/searchers/__init__.py +51 -0
  124. novel_downloader/core/searchers/aaatxt.py +107 -0
  125. novel_downloader/core/searchers/b520.py +84 -0
  126. novel_downloader/core/searchers/base.py +168 -0
  127. novel_downloader/core/searchers/dxmwx.py +105 -0
  128. novel_downloader/core/searchers/eightnovel.py +84 -0
  129. novel_downloader/core/searchers/esjzone.py +102 -0
  130. novel_downloader/core/searchers/hetushu.py +92 -0
  131. novel_downloader/core/searchers/i25zw.py +93 -0
  132. novel_downloader/core/searchers/ixdzs8.py +107 -0
  133. novel_downloader/core/searchers/jpxs123.py +107 -0
  134. novel_downloader/core/searchers/piaotia.py +100 -0
  135. novel_downloader/core/searchers/qbtr.py +106 -0
  136. novel_downloader/core/searchers/qianbi.py +165 -0
  137. novel_downloader/core/searchers/quanben5.py +144 -0
  138. novel_downloader/core/searchers/registry.py +79 -0
  139. novel_downloader/core/searchers/shuhaige.py +124 -0
  140. novel_downloader/core/searchers/tongrenquan.py +110 -0
  141. novel_downloader/core/searchers/ttkan.py +92 -0
  142. novel_downloader/core/searchers/xiaoshuowu.py +122 -0
  143. novel_downloader/core/searchers/xiguashuwu.py +95 -0
  144. novel_downloader/core/searchers/xs63b.py +104 -0
  145. novel_downloader/locales/en.json +36 -79
  146. novel_downloader/locales/zh.json +37 -80
  147. novel_downloader/models/__init__.py +23 -50
  148. novel_downloader/models/book.py +44 -0
  149. novel_downloader/models/config.py +16 -43
  150. novel_downloader/models/login.py +1 -1
  151. novel_downloader/models/search.py +21 -0
  152. novel_downloader/resources/config/settings.toml +39 -74
  153. novel_downloader/resources/css_styles/intro.css +83 -0
  154. novel_downloader/resources/css_styles/main.css +30 -89
  155. novel_downloader/resources/json/xiguashuwu.json +718 -0
  156. novel_downloader/utils/__init__.py +43 -0
  157. novel_downloader/utils/chapter_storage.py +247 -226
  158. novel_downloader/utils/constants.py +5 -50
  159. novel_downloader/utils/cookies.py +6 -18
  160. novel_downloader/utils/crypto_utils/__init__.py +13 -0
  161. novel_downloader/utils/crypto_utils/aes_util.py +90 -0
  162. novel_downloader/utils/crypto_utils/aes_v1.py +619 -0
  163. novel_downloader/utils/crypto_utils/aes_v2.py +1143 -0
  164. novel_downloader/utils/{crypto_utils.py → crypto_utils/rc4.py} +3 -10
  165. novel_downloader/utils/epub/__init__.py +34 -0
  166. novel_downloader/utils/epub/builder.py +377 -0
  167. novel_downloader/utils/epub/constants.py +118 -0
  168. novel_downloader/utils/epub/documents.py +297 -0
  169. novel_downloader/utils/epub/models.py +120 -0
  170. novel_downloader/utils/epub/utils.py +179 -0
  171. novel_downloader/utils/file_utils/__init__.py +5 -30
  172. novel_downloader/utils/file_utils/io.py +9 -150
  173. novel_downloader/utils/file_utils/normalize.py +2 -2
  174. novel_downloader/utils/file_utils/sanitize.py +2 -7
  175. novel_downloader/utils/fontocr.py +207 -0
  176. novel_downloader/utils/i18n.py +2 -0
  177. novel_downloader/utils/logger.py +10 -16
  178. novel_downloader/utils/network.py +111 -252
  179. novel_downloader/utils/state.py +5 -90
  180. novel_downloader/utils/text_utils/__init__.py +16 -21
  181. novel_downloader/utils/text_utils/diff_display.py +6 -9
  182. novel_downloader/utils/text_utils/numeric_conversion.py +253 -0
  183. novel_downloader/utils/text_utils/text_cleaner.py +179 -0
  184. novel_downloader/utils/text_utils/truncate_utils.py +62 -0
  185. novel_downloader/utils/time_utils/__init__.py +6 -12
  186. novel_downloader/utils/time_utils/datetime_utils.py +23 -33
  187. novel_downloader/utils/time_utils/sleep_utils.py +5 -10
  188. novel_downloader/web/__init__.py +13 -0
  189. novel_downloader/web/components/__init__.py +11 -0
  190. novel_downloader/web/components/navigation.py +35 -0
  191. novel_downloader/web/main.py +66 -0
  192. novel_downloader/web/pages/__init__.py +17 -0
  193. novel_downloader/web/pages/download.py +78 -0
  194. novel_downloader/web/pages/progress.py +147 -0
  195. novel_downloader/web/pages/search.py +329 -0
  196. novel_downloader/web/services/__init__.py +17 -0
  197. novel_downloader/web/services/client_dialog.py +164 -0
  198. novel_downloader/web/services/cred_broker.py +113 -0
  199. novel_downloader/web/services/cred_models.py +35 -0
  200. novel_downloader/web/services/task_manager.py +264 -0
  201. novel_downloader-2.0.0.dist-info/METADATA +171 -0
  202. novel_downloader-2.0.0.dist-info/RECORD +210 -0
  203. {novel_downloader-1.4.5.dist-info → novel_downloader-2.0.0.dist-info}/entry_points.txt +1 -1
  204. novel_downloader/config/site_rules.py +0 -94
  205. novel_downloader/core/downloaders/biquge.py +0 -25
  206. novel_downloader/core/downloaders/esjzone.py +0 -25
  207. novel_downloader/core/downloaders/linovelib.py +0 -25
  208. novel_downloader/core/downloaders/sfacg.py +0 -25
  209. novel_downloader/core/downloaders/yamibo.py +0 -25
  210. novel_downloader/core/exporters/biquge.py +0 -25
  211. novel_downloader/core/exporters/esjzone.py +0 -25
  212. novel_downloader/core/exporters/qianbi.py +0 -25
  213. novel_downloader/core/exporters/sfacg.py +0 -25
  214. novel_downloader/core/exporters/yamibo.py +0 -25
  215. novel_downloader/core/factory/__init__.py +0 -20
  216. novel_downloader/core/factory/downloader.py +0 -73
  217. novel_downloader/core/factory/exporter.py +0 -58
  218. novel_downloader/core/factory/fetcher.py +0 -96
  219. novel_downloader/core/factory/parser.py +0 -86
  220. novel_downloader/core/fetchers/base/__init__.py +0 -14
  221. novel_downloader/core/fetchers/base/browser.py +0 -403
  222. novel_downloader/core/fetchers/biquge/__init__.py +0 -14
  223. novel_downloader/core/fetchers/common/__init__.py +0 -14
  224. novel_downloader/core/fetchers/esjzone/__init__.py +0 -14
  225. novel_downloader/core/fetchers/esjzone/browser.py +0 -204
  226. novel_downloader/core/fetchers/linovelib/__init__.py +0 -14
  227. novel_downloader/core/fetchers/linovelib/browser.py +0 -193
  228. novel_downloader/core/fetchers/qianbi/__init__.py +0 -14
  229. novel_downloader/core/fetchers/qidian/__init__.py +0 -14
  230. novel_downloader/core/fetchers/qidian/browser.py +0 -318
  231. novel_downloader/core/fetchers/sfacg/__init__.py +0 -14
  232. novel_downloader/core/fetchers/sfacg/browser.py +0 -189
  233. novel_downloader/core/fetchers/yamibo/__init__.py +0 -14
  234. novel_downloader/core/fetchers/yamibo/browser.py +0 -229
  235. novel_downloader/core/parsers/biquge/__init__.py +0 -10
  236. novel_downloader/core/parsers/biquge/main_parser.py +0 -134
  237. novel_downloader/core/parsers/common/__init__.py +0 -13
  238. novel_downloader/core/parsers/common/helper.py +0 -323
  239. novel_downloader/core/parsers/common/main_parser.py +0 -106
  240. novel_downloader/core/parsers/esjzone/__init__.py +0 -10
  241. novel_downloader/core/parsers/linovelib/__init__.py +0 -10
  242. novel_downloader/core/parsers/qianbi/__init__.py +0 -10
  243. novel_downloader/core/parsers/sfacg/__init__.py +0 -10
  244. novel_downloader/core/parsers/yamibo/__init__.py +0 -10
  245. novel_downloader/core/parsers/yamibo/main_parser.py +0 -194
  246. novel_downloader/models/browser.py +0 -21
  247. novel_downloader/models/chapter.py +0 -25
  248. novel_downloader/models/site_rules.py +0 -99
  249. novel_downloader/models/tasks.py +0 -33
  250. novel_downloader/models/types.py +0 -15
  251. novel_downloader/resources/css_styles/volume-intro.css +0 -56
  252. novel_downloader/resources/json/replace_word_map.json +0 -4
  253. novel_downloader/resources/text/blacklist.txt +0 -22
  254. novel_downloader/tui/__init__.py +0 -7
  255. novel_downloader/tui/app.py +0 -32
  256. novel_downloader/tui/main.py +0 -17
  257. novel_downloader/tui/screens/__init__.py +0 -14
  258. novel_downloader/tui/screens/home.py +0 -198
  259. novel_downloader/tui/screens/login.py +0 -74
  260. novel_downloader/tui/styles/home_layout.tcss +0 -79
  261. novel_downloader/tui/widgets/richlog_handler.py +0 -24
  262. novel_downloader/utils/cache.py +0 -24
  263. novel_downloader/utils/fontocr/__init__.py +0 -22
  264. novel_downloader/utils/fontocr/model_loader.py +0 -69
  265. novel_downloader/utils/fontocr/ocr_v1.py +0 -303
  266. novel_downloader/utils/fontocr/ocr_v2.py +0 -752
  267. novel_downloader/utils/hash_store.py +0 -279
  268. novel_downloader/utils/hash_utils.py +0 -103
  269. novel_downloader/utils/text_utils/chapter_formatting.py +0 -46
  270. novel_downloader/utils/text_utils/font_mapping.py +0 -28
  271. novel_downloader/utils/text_utils/text_cleaning.py +0 -107
  272. novel_downloader-1.4.5.dist-info/METADATA +0 -196
  273. novel_downloader-1.4.5.dist-info/RECORD +0 -165
  274. {novel_downloader-1.4.5.dist-info → novel_downloader-2.0.0.dist-info}/WHEEL +0 -0
  275. {novel_downloader-1.4.5.dist-info → novel_downloader-2.0.0.dist-info}/licenses/LICENSE +0 -0
  276. {novel_downloader-1.4.5.dist-info → novel_downloader-2.0.0.dist-info}/top_level.txt +0 -0
@@ -5,27 +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
- from dataclasses import dataclass
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
- StorageBackend,
27
- )
28
-
29
13
 
30
14
  @dataclass
31
15
  class FetcherConfig:
@@ -33,16 +17,12 @@ class FetcherConfig:
33
17
  retry_times: int = 3
34
18
  backoff_factor: float = 2.0
35
19
  timeout: float = 30.0
36
- headless: bool = False
37
- disable_images: bool = False
38
- mode: ModeType = "session"
39
20
  max_connections: int = 10
40
- max_rps: float | None = None # Maximum requests per second
41
- proxy: str | None = None
21
+ max_rps: float = 1000.0
42
22
  user_agent: str | None = None
43
23
  headers: dict[str, str] | None = None
44
- browser_type: BrowserType = "chromium"
45
24
  verify_ssl: bool = True
25
+ locale_style: str = "simplified"
46
26
 
47
27
 
48
28
  @dataclass
@@ -52,17 +32,11 @@ class DownloaderConfig:
52
32
  backoff_factor: float = 2.0
53
33
  raw_data_dir: str = "./raw_data"
54
34
  cache_dir: str = "./novel_cache"
55
- download_workers: int = 4
56
- parser_workers: int = 4
35
+ workers: int = 4
57
36
  skip_existing: bool = True
58
37
  login_required: bool = False
59
38
  save_html: bool = False
60
- mode: ModeType = "session"
61
- storage_backend: StorageBackend = "json"
62
39
  storage_batch_size: int = 1
63
- username: str = ""
64
- password: str = ""
65
- cookies: str = ""
66
40
 
67
41
 
68
42
  @dataclass
@@ -70,17 +44,17 @@ class ParserConfig:
70
44
  cache_dir: str = "./novel_cache"
71
45
  use_truncation: bool = True
72
46
  decode_font: bool = False
73
- use_freq: bool = False
74
- use_ocr: bool = True
75
- use_vec: bool = False
76
- ocr_version: str = "v1.0"
77
47
  batch_size: int = 32
78
- gpu_mem: int = 500
79
- gpu_id: int | None = None
80
- ocr_weight: float = 0.6
81
- vec_weight: float = 0.4
82
48
  save_font_debug: bool = False
83
- mode: ModeType = "session"
49
+
50
+
51
+ @dataclass
52
+ class TextCleanerConfig:
53
+ remove_invisible: bool = True
54
+ title_remove_patterns: list[str] = field(default_factory=list)
55
+ title_replacements: dict[str, str] = field(default_factory=dict)
56
+ content_remove_patterns: list[str] = field(default_factory=list)
57
+ content_replacements: dict[str, str] = field(default_factory=dict)
84
58
 
85
59
 
86
60
  @dataclass
@@ -88,7 +62,6 @@ class ExporterConfig:
88
62
  cache_dir: str = "./novel_cache"
89
63
  raw_data_dir: str = "./raw_data"
90
64
  output_dir: str = "./downloads"
91
- storage_backend: StorageBackend = "json"
92
65
  clean_text: bool = True
93
66
  make_txt: bool = True
94
67
  make_epub: bool = False
@@ -97,9 +70,9 @@ class ExporterConfig:
97
70
  append_timestamp: bool = True
98
71
  filename_template: str = "{title}_{author}"
99
72
  include_cover: bool = True
100
- include_toc: bool = False
101
- include_picture: bool = False
102
- split_mode: SplitMode = "book"
73
+ include_picture: bool = True
74
+ split_mode: str = "book"
75
+ cleaner_cfg: TextCleanerConfig = field(default_factory=TextCleanerConfig)
103
76
 
104
77
 
105
78
  class BookConfig(TypedDict):
@@ -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 = ""
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ novel_downloader.models.search
4
+ ------------------------------
5
+
6
+ """
7
+
8
+ from typing import TypedDict
9
+
10
+
11
+ class SearchResult(TypedDict, total=True):
12
+ site: str
13
+ book_id: str
14
+ book_url: str
15
+ cover_url: str
16
+ title: str
17
+ author: str
18
+ latest_chapter: str
19
+ update_date: str
20
+ word_count: str
21
+ priority: int
@@ -1,31 +1,18 @@
1
- # 网络请求层设置
2
- [requests]
1
+ # 全局通用设置
2
+ [general]
3
3
  retry_times = 3 # 请求失败重试次数
4
4
  backoff_factor = 2.0
5
5
  timeout = 30.0 # 页面加载超时时间 (秒)
6
6
  max_connections = 10 # 并发连接的最大数
7
- max_rps = 1.0 # 最大请求速率 (requests per second), 如不设置则请注释掉或删掉本行
8
- # proxy = "http://127.0.0.1:1080" # 如需使用代理, 填写完整的代理地址
9
- # user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
10
- # headers = {}
11
- browser_type = "chromium"
12
- verify_ssl = true
13
-
14
- # 浏览器设置
15
- headless = false # 是否以无头模式启动浏览器
16
- disable_images = false # 是否禁用图片加载 (加速)
17
-
18
- # 全局通用设置
19
- [general]
7
+ max_rps = 1.0 # 最大请求速率 (requests per second), 如不设置则请设置一个较大的数或负数
20
8
  request_interval = 2.0 # 同一本书各章节请求间隔 (秒)
21
9
  raw_data_dir = "./raw_data" # 原始章节 JSON/DB 存放目录
22
10
  output_dir = "./downloads" # 最终输出文件存放目录
23
11
  cache_dir = "./novel_cache" # 本地缓存目录 (字体 / 图片等)
24
- download_workers = 2 # 并发下载线程数
25
- parser_workers = 2 # 并发解析线程数
12
+ workers = 2 # 工作协程数
26
13
  skip_existing = true # 是否跳过已存在章节
27
- storage_backend = "sqlite" # 章节储存方法: json / sqlite
28
- storage_batch_size = 30 # SQLite 批量提交的章节数量
14
+ storage_batch_size = 1 # SQLite 批量提交的章节数量
15
+ locale_style = "simplified" # simplified / traditional
29
16
 
30
17
  [general.debug]
31
18
  save_html = false # 是否将抓取到的原始 HTML 保留到磁盘
@@ -33,16 +20,8 @@ log_level = "INFO" # 日志级别: DEBUG, INFO, WARNING, ERROR
33
20
 
34
21
  [general.font_ocr]
35
22
  decode_font = false # 是否尝试本地解码混淆字体
36
- use_freq = false # 是否使用频率分析
37
- ocr_version = "v2.0" # "v1.0" / "v2.0"
38
- use_ocr = true # 是否使用 OCR 辅助识别文本
39
- use_vec = false # 是否使用 Vector 辅助识别文本
40
- save_font_debug = false # 是否保存字体解码调试数据
41
23
  batch_size = 32
42
- gpu_mem = 500 # GPU 显存限制 (MB)
43
- # gpu_id = # 使用哪个 GPU
44
- ocr_weight = 0.5
45
- vec_weight = 0.5
24
+ save_font_debug = false # 是否保存字体解码调试数据
46
25
 
47
26
  # 各站点的特定配置
48
27
  [sites.qidian] # 起点中文网
@@ -50,76 +29,33 @@ book_ids = [
50
29
  "0000000000",
51
30
  "0000000000"
52
31
  ]
53
- mode = "session" # browser / session
54
32
  login_required = true # 是否需要登录才能访问
55
33
  use_truncation = true # 是否基于章节长度截断以避免重复内容
56
34
 
57
- [sites.biquge] # 笔趣阁
58
- book_ids = [
59
- "0000000000",
60
- "0000000000"
61
- ]
62
- mode = "session" # browser / session
63
- login_required = false
64
-
65
- [sites.qianbi] # 铅笔小说
66
- book_ids = [
67
- "0000000000",
68
- "0000000000"
69
- ]
70
- mode = "session" # browser / session
71
- login_required = false
72
-
73
- [sites.sfacg] # SF轻小说
74
- book_ids = [
75
- "0000000000",
76
- "0000000000"
77
- ]
78
- mode = "session" # browser / session
79
- login_required = false
80
-
81
35
  [sites.esjzone] # ESJ Zone
82
36
  book_ids = [
83
37
  "0000000000",
84
38
  "0000000000"
85
39
  ]
86
- mode = "session" # browser / session
87
40
  login_required = true
88
41
  # username = "youremail@domain.com" # 登录邮箱
89
42
  # password = "yourpassword" # 登录密码
90
43
 
91
- [sites.yamibo] # 百合会
92
- book_ids = [
93
- "0000000000",
94
- "0000000000"
95
- ]
96
- mode = "session" # browser / session
97
- login_required = false
98
- # username = "yourusername" # 登录账户
99
- # password = "yourpassword" # 登录密码
100
-
101
44
  [sites.linovelib] # 哔哩轻小说
102
45
  book_ids = [
103
46
  "0000000000",
104
47
  "0000000000"
105
48
  ]
106
- mode = "session"
107
49
  split_mode = "book" # 导出方式: book / volume
108
50
  login_required = false
109
51
 
110
52
  [sites.common]
111
- mode = "session" # browser / session
112
53
  login_required = false
113
54
 
114
55
  # 输出文件格式及相关选项
115
- [output]
116
- clean_text = true # 是否对章节文本做清理
117
-
118
56
  [output.formats]
119
57
  make_txt = true # 是否生成完整 TXT 文件
120
- make_epub = false # 是否生成 EPUB
121
- make_md = false # 是否生成 Markdown (未实现)
122
- make_pdf = false # 可能支持 PDF 输出 (未实现)
58
+ make_epub = true # 是否生成 EPUB
123
59
 
124
60
  [output.naming]
125
61
  append_timestamp = false # 在文件名中追加时间戳
@@ -127,5 +63,34 @@ filename_template = "{title}_{author}" # 文件命名规则
127
63
 
128
64
  [output.epub]
129
65
  include_cover = true # 是否在 EPUB 中包含封面
130
- include_toc = false # 是否自动生成目录
131
- include_picture = false # 是否下载章节图片 (体积较大)
66
+ include_picture = true # 是否下载章节图片 (体积较大)
67
+
68
+ [cleaner]
69
+ clean_text = false # 是否对章节文本做清理
70
+ remove_invisible = true
71
+
72
+ [cleaner.title]
73
+ remove_patterns = [
74
+ '【[^】]*?】',
75
+ '[((][^()()]*?求票[^()()]*?[))]',
76
+ ]
77
+
78
+ [cleaner.title.replace]
79
+ ':' = ':'
80
+
81
+ [cleaner.title.external]
82
+ enabled = false
83
+ remove_patterns = "path/to/title-remove.json"
84
+ replace = "path/to/title-replace.json"
85
+
86
+ [cleaner.content]
87
+ remove_patterns = []
88
+
89
+ [cleaner.content.replace]
90
+ 'li子' = '例子'
91
+ 'pinbi词' = '屏蔽词'
92
+
93
+ [cleaner.content.external]
94
+ enabled = false
95
+ remove_patterns = "path/to/content-remove.json"
96
+ replace = "path/to/content-replace.json"
@@ -0,0 +1,83 @@
1
+ body {
2
+ font-family: serif;
3
+ line-height: 1.5;
4
+ height: 95%;
5
+ margin: 2em;
6
+ }
7
+
8
+ h1 {
9
+ font-size: 2em;
10
+ text-align: center;
11
+ margin-bottom: 1em;
12
+ }
13
+
14
+ p.new-page-after {
15
+ page-break-after: always;
16
+ margin: 0;
17
+ padding: 0;
18
+ }
19
+
20
+ .intro-info {
21
+ list-style: none;
22
+ padding: 0;
23
+ margin: 0 0 2em;
24
+ }
25
+ .intro-info li {
26
+ margin: 0.5em 0;
27
+ font-size: 1.1em;
28
+ }
29
+
30
+ .intro-summary {
31
+ margin-top: 1em;
32
+ font-size: 1em;
33
+ }
34
+
35
+ .vol-header {
36
+ display: flex;
37
+ flex-direction: column;
38
+ justify-content: center;
39
+ align-items: center;
40
+ margin: 0;
41
+ }
42
+
43
+ .vol-border {
44
+ width: 100%;
45
+ text-align: center;
46
+ margin: 0 auto 0 auto;
47
+ text-indent: 0em;
48
+ }
49
+ .vol-border.flip {
50
+ transform: rotate(180deg);
51
+ -ms-transform: rotate(180deg);
52
+ -moz-transform: rotate(180deg);
53
+ -webkit-transform: rotate(180deg);
54
+ -o-transform: rotate(180deg);
55
+ }
56
+
57
+ .vol-title-main,
58
+ .vol-title-sub {
59
+ font-weight: bold;
60
+ text-align: center;
61
+ text-indent: 0em;
62
+ color: #6e471c;
63
+ margin: 0.25em 0;
64
+ display: block;
65
+ color: #6e471c;
66
+ text-shadow: 1px 1px 2px rgba(255,255,255,0.8);
67
+ }
68
+ .vol-title-main {
69
+ font-size: 1.25rem;
70
+ }
71
+ .vol-title-sub {
72
+ font-size: 1rem;
73
+ }
74
+
75
+ .volume-intro-text {
76
+ margin: 1em 0;
77
+ padding: 0 1em;
78
+ text-align: justify;
79
+ }
80
+ .volume-intro-text p {
81
+ margin: 0.5em 0;
82
+ line-height: 1.6;
83
+ }
@@ -1,104 +1,45 @@
1
- html, body {
2
- height: 95%;
3
- padding: 0.5em;
1
+ body {
2
+ font-family: serif;
3
+ height: 95%;
4
+ line-height: 1.6;
5
+ margin: 1em;
4
6
  }
5
7
 
6
- .images img {
7
- width:100%; /*自适应*/
8
- }
9
- .color .images {
10
- margin:0 0 1.5em;
11
- }
12
- .article .images {
13
- margin:1.0em 0;
14
- border:1px solid #000
15
- }
16
-
17
- .new-page-after {
18
- page-break-after:always;
19
- }
20
-
21
- .cover {
22
- width:100%;
23
- padding:0px;
24
- }
25
- .center {
26
- text-align: center;
27
- margin-left: 0%;
28
- margin-right: 0%;
29
- }
30
- .left {
31
- text-align: center;
32
- margin-left: 0%;
33
- margin-right: 0%;
34
- }
35
- .right {
36
- text-align: right;
37
- margin-left: 0%;
38
- margin-right: 0%;
8
+ h2 {
9
+ font-size: 1.5em;
10
+ margin: 1.5em 0 0.75em;
11
+ text-align: center;
39
12
  }
40
13
 
41
- hr {
42
- margin: 0;
43
- border-style: dotted;
44
- border-width: 1px 0 0 0;
45
- margin-top: 0.5em;
46
- margin-bottom: 0.5em;
47
- }
48
-
49
- h1 {
50
- text-indent: 0;
51
- duokan-text-indent: 0;
52
- line-height: 110%;
53
- text-align: center;
54
- font-size: 1.2em;
55
- margin-top: 0.4em;
56
- margin-bottom: 0.4em;
57
- }
58
-
59
- h2, h3, h4, h5, h6 {
60
- text-indent: 0;
61
- duokan-text-indent: 0;
62
- line-height: 110%;
63
- font-size: 1.1em;
64
- margin-top: 0.4em;
65
- margin-bottom: 0.4em;
14
+ p {
15
+ text-indent: 2em;
16
+ margin: 0.5em 0;
66
17
  }
67
18
 
68
- p {
69
- text-align: justify; /* 让文本两端对齐 */
70
- text-indent: 2em;
71
- duokan-text-indent: 2em;
72
- line-height: 100%;
73
- margin-top: 0.4em;
74
- margin-bottom: 0.4em;
19
+ p.new-page-after {
20
+ margin: 0;
21
+ padding: 0;
22
+ page-break-after: always;
75
23
  }
76
24
 
77
- div.list {
78
- text-align: left;
79
- font-size: 0.85em;
80
- line-height: 130%;
25
+ .duokan-image-single {
26
+ text-align: center;
27
+ margin: 1em 0;
81
28
  }
82
29
 
83
- span {
84
- text-indent: 0;
85
- duokan-text-indent: 0;
86
- text-align: left;
87
- font-size: 1em;
30
+ .duokan-image-single img {
31
+ max-width: 100%;
32
+ height: auto;
33
+ display: inline-block;
88
34
  }
89
35
 
90
- ol {
91
- text-align: left;
92
- margin-top: 1.2em;
93
- margin-bottom: 1.2em;
94
- margin-left: 0;
95
- list-style-type: none;
36
+ hr {
37
+ border: none;
38
+ border-top: 1px solid #ccc;
39
+ margin: 1.5em 0;
96
40
  }
97
41
 
98
- li {
99
- text-align: left;
100
- margin-top: 0.4em;
101
- margin-bottom: 0.4em;
102
- margin-left: 0;
103
- list-style-type: none;
42
+ h3 {
43
+ font-size: 1.2em;
44
+ margin: 1em 0 0.5em;
104
45
  }