novel-downloader 1.3.2__py3-none-any.whl → 1.4.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 (213) hide show
  1. novel_downloader/__init__.py +1 -1
  2. novel_downloader/cli/clean.py +97 -78
  3. novel_downloader/cli/config.py +177 -0
  4. novel_downloader/cli/download.py +132 -87
  5. novel_downloader/cli/export.py +77 -0
  6. novel_downloader/cli/main.py +21 -28
  7. novel_downloader/config/__init__.py +1 -25
  8. novel_downloader/config/adapter.py +32 -31
  9. novel_downloader/config/loader.py +3 -3
  10. novel_downloader/config/site_rules.py +1 -2
  11. novel_downloader/core/__init__.py +3 -6
  12. novel_downloader/core/downloaders/__init__.py +10 -13
  13. novel_downloader/core/downloaders/base.py +233 -0
  14. novel_downloader/core/downloaders/biquge.py +27 -0
  15. novel_downloader/core/downloaders/common.py +414 -0
  16. novel_downloader/core/downloaders/esjzone.py +27 -0
  17. novel_downloader/core/downloaders/linovelib.py +27 -0
  18. novel_downloader/core/downloaders/qianbi.py +27 -0
  19. novel_downloader/core/downloaders/qidian.py +352 -0
  20. novel_downloader/core/downloaders/sfacg.py +27 -0
  21. novel_downloader/core/downloaders/yamibo.py +27 -0
  22. novel_downloader/core/exporters/__init__.py +37 -0
  23. novel_downloader/core/{savers → exporters}/base.py +73 -44
  24. novel_downloader/core/exporters/biquge.py +25 -0
  25. novel_downloader/core/exporters/common/__init__.py +12 -0
  26. novel_downloader/core/{savers → exporters}/common/epub.py +40 -52
  27. novel_downloader/core/{savers/common/main_saver.py → exporters/common/main_exporter.py} +36 -39
  28. novel_downloader/core/{savers → exporters}/common/txt.py +20 -24
  29. novel_downloader/core/exporters/epub_utils/__init__.py +40 -0
  30. novel_downloader/core/{savers → exporters}/epub_utils/css_builder.py +2 -1
  31. novel_downloader/core/exporters/epub_utils/image_loader.py +131 -0
  32. novel_downloader/core/{savers → exporters}/epub_utils/initializer.py +6 -3
  33. novel_downloader/core/{savers → exporters}/epub_utils/text_to_html.py +49 -2
  34. novel_downloader/core/{savers → exporters}/epub_utils/volume_intro.py +2 -1
  35. novel_downloader/core/exporters/esjzone.py +25 -0
  36. novel_downloader/core/exporters/linovelib/__init__.py +10 -0
  37. novel_downloader/core/exporters/linovelib/epub.py +449 -0
  38. novel_downloader/core/exporters/linovelib/main_exporter.py +127 -0
  39. novel_downloader/core/exporters/linovelib/txt.py +129 -0
  40. novel_downloader/core/exporters/qianbi.py +25 -0
  41. novel_downloader/core/{savers → exporters}/qidian.py +8 -8
  42. novel_downloader/core/exporters/sfacg.py +25 -0
  43. novel_downloader/core/exporters/yamibo.py +25 -0
  44. novel_downloader/core/factory/__init__.py +5 -17
  45. novel_downloader/core/factory/downloader.py +24 -126
  46. novel_downloader/core/factory/exporter.py +58 -0
  47. novel_downloader/core/factory/fetcher.py +96 -0
  48. novel_downloader/core/factory/parser.py +17 -12
  49. novel_downloader/core/{requesters → fetchers}/__init__.py +22 -15
  50. novel_downloader/core/{requesters → fetchers}/base/__init__.py +2 -4
  51. novel_downloader/core/fetchers/base/browser.py +383 -0
  52. novel_downloader/core/fetchers/base/rate_limiter.py +86 -0
  53. novel_downloader/core/fetchers/base/session.py +419 -0
  54. novel_downloader/core/fetchers/biquge/__init__.py +14 -0
  55. novel_downloader/core/{requesters/biquge/async_session.py → fetchers/biquge/browser.py} +18 -6
  56. novel_downloader/core/{requesters → fetchers}/biquge/session.py +23 -30
  57. novel_downloader/core/fetchers/common/__init__.py +14 -0
  58. novel_downloader/core/fetchers/common/browser.py +79 -0
  59. novel_downloader/core/{requesters/common/async_session.py → fetchers/common/session.py} +8 -25
  60. novel_downloader/core/fetchers/esjzone/__init__.py +14 -0
  61. novel_downloader/core/fetchers/esjzone/browser.py +202 -0
  62. novel_downloader/core/{requesters/esjzone/async_session.py → fetchers/esjzone/session.py} +62 -42
  63. novel_downloader/core/fetchers/linovelib/__init__.py +14 -0
  64. novel_downloader/core/fetchers/linovelib/browser.py +178 -0
  65. novel_downloader/core/fetchers/linovelib/session.py +178 -0
  66. novel_downloader/core/fetchers/qianbi/__init__.py +14 -0
  67. novel_downloader/core/{requesters/qianbi/session.py → fetchers/qianbi/browser.py} +30 -48
  68. novel_downloader/core/{requesters/qianbi/async_session.py → fetchers/qianbi/session.py} +18 -6
  69. novel_downloader/core/fetchers/qidian/__init__.py +14 -0
  70. novel_downloader/core/fetchers/qidian/browser.py +266 -0
  71. novel_downloader/core/fetchers/qidian/session.py +326 -0
  72. novel_downloader/core/fetchers/sfacg/__init__.py +14 -0
  73. novel_downloader/core/fetchers/sfacg/browser.py +189 -0
  74. novel_downloader/core/{requesters/sfacg/async_session.py → fetchers/sfacg/session.py} +43 -73
  75. novel_downloader/core/fetchers/yamibo/__init__.py +14 -0
  76. novel_downloader/core/fetchers/yamibo/browser.py +229 -0
  77. novel_downloader/core/{requesters/yamibo/async_session.py → fetchers/yamibo/session.py} +62 -44
  78. novel_downloader/core/interfaces/__init__.py +8 -12
  79. novel_downloader/core/interfaces/downloader.py +54 -0
  80. novel_downloader/core/interfaces/{saver.py → exporter.py} +12 -12
  81. novel_downloader/core/interfaces/fetcher.py +162 -0
  82. novel_downloader/core/interfaces/parser.py +6 -7
  83. novel_downloader/core/parsers/__init__.py +5 -6
  84. novel_downloader/core/parsers/base.py +9 -13
  85. novel_downloader/core/parsers/biquge/main_parser.py +12 -13
  86. novel_downloader/core/parsers/common/helper.py +3 -3
  87. novel_downloader/core/parsers/common/main_parser.py +39 -34
  88. novel_downloader/core/parsers/esjzone/main_parser.py +24 -17
  89. novel_downloader/core/parsers/linovelib/__init__.py +10 -0
  90. novel_downloader/core/parsers/linovelib/main_parser.py +210 -0
  91. novel_downloader/core/parsers/qianbi/main_parser.py +21 -15
  92. novel_downloader/core/parsers/qidian/__init__.py +2 -11
  93. novel_downloader/core/parsers/qidian/book_info_parser.py +113 -0
  94. novel_downloader/core/parsers/qidian/{browser/chapter_encrypted.py → chapter_encrypted.py} +162 -135
  95. novel_downloader/core/parsers/qidian/chapter_normal.py +150 -0
  96. novel_downloader/core/parsers/qidian/{session/chapter_router.py → chapter_router.py} +15 -15
  97. novel_downloader/core/parsers/qidian/{browser/main_parser.py → main_parser.py} +49 -40
  98. novel_downloader/core/parsers/qidian/utils/__init__.py +27 -0
  99. novel_downloader/core/parsers/qidian/utils/decryptor_fetcher.py +145 -0
  100. novel_downloader/core/parsers/qidian/{shared → utils}/helpers.py +41 -68
  101. novel_downloader/core/parsers/qidian/{session → utils}/node_decryptor.py +64 -50
  102. novel_downloader/core/parsers/sfacg/main_parser.py +12 -12
  103. novel_downloader/core/parsers/yamibo/main_parser.py +10 -10
  104. novel_downloader/locales/en.json +18 -2
  105. novel_downloader/locales/zh.json +18 -2
  106. novel_downloader/models/__init__.py +64 -0
  107. novel_downloader/models/browser.py +21 -0
  108. novel_downloader/models/chapter.py +25 -0
  109. novel_downloader/models/config.py +100 -0
  110. novel_downloader/models/login.py +20 -0
  111. novel_downloader/models/site_rules.py +99 -0
  112. novel_downloader/models/tasks.py +33 -0
  113. novel_downloader/models/types.py +15 -0
  114. novel_downloader/resources/config/settings.toml +31 -25
  115. novel_downloader/resources/json/linovelib_font_map.json +3573 -0
  116. novel_downloader/tui/__init__.py +7 -0
  117. novel_downloader/tui/app.py +32 -0
  118. novel_downloader/tui/main.py +17 -0
  119. novel_downloader/tui/screens/__init__.py +14 -0
  120. novel_downloader/tui/screens/home.py +191 -0
  121. novel_downloader/tui/screens/login.py +74 -0
  122. novel_downloader/tui/styles/home_layout.tcss +79 -0
  123. novel_downloader/tui/widgets/richlog_handler.py +24 -0
  124. novel_downloader/utils/__init__.py +6 -0
  125. novel_downloader/utils/chapter_storage.py +25 -38
  126. novel_downloader/utils/constants.py +15 -5
  127. novel_downloader/utils/cookies.py +66 -0
  128. novel_downloader/utils/crypto_utils.py +1 -74
  129. novel_downloader/utils/file_utils/io.py +1 -1
  130. novel_downloader/utils/fontocr/ocr_v1.py +2 -1
  131. novel_downloader/utils/fontocr/ocr_v2.py +2 -2
  132. novel_downloader/utils/hash_store.py +10 -18
  133. novel_downloader/utils/hash_utils.py +3 -2
  134. novel_downloader/utils/logger.py +2 -3
  135. novel_downloader/utils/network.py +53 -39
  136. novel_downloader/utils/text_utils/chapter_formatting.py +6 -1
  137. novel_downloader/utils/text_utils/font_mapping.py +1 -1
  138. novel_downloader/utils/text_utils/text_cleaning.py +1 -1
  139. novel_downloader/utils/time_utils/datetime_utils.py +3 -3
  140. novel_downloader/utils/time_utils/sleep_utils.py +3 -3
  141. {novel_downloader-1.3.2.dist-info → novel_downloader-1.4.0.dist-info}/METADATA +72 -38
  142. novel_downloader-1.4.0.dist-info/RECORD +170 -0
  143. {novel_downloader-1.3.2.dist-info → novel_downloader-1.4.0.dist-info}/WHEEL +1 -1
  144. {novel_downloader-1.3.2.dist-info → novel_downloader-1.4.0.dist-info}/entry_points.txt +1 -0
  145. novel_downloader/cli/interactive.py +0 -66
  146. novel_downloader/cli/settings.py +0 -177
  147. novel_downloader/config/models.py +0 -187
  148. novel_downloader/core/downloaders/base/__init__.py +0 -14
  149. novel_downloader/core/downloaders/base/base_async.py +0 -153
  150. novel_downloader/core/downloaders/base/base_sync.py +0 -208
  151. novel_downloader/core/downloaders/biquge/__init__.py +0 -14
  152. novel_downloader/core/downloaders/biquge/biquge_async.py +0 -27
  153. novel_downloader/core/downloaders/biquge/biquge_sync.py +0 -27
  154. novel_downloader/core/downloaders/common/__init__.py +0 -14
  155. novel_downloader/core/downloaders/common/common_async.py +0 -218
  156. novel_downloader/core/downloaders/common/common_sync.py +0 -210
  157. novel_downloader/core/downloaders/esjzone/__init__.py +0 -14
  158. novel_downloader/core/downloaders/esjzone/esjzone_async.py +0 -27
  159. novel_downloader/core/downloaders/esjzone/esjzone_sync.py +0 -27
  160. novel_downloader/core/downloaders/qianbi/__init__.py +0 -14
  161. novel_downloader/core/downloaders/qianbi/qianbi_async.py +0 -27
  162. novel_downloader/core/downloaders/qianbi/qianbi_sync.py +0 -27
  163. novel_downloader/core/downloaders/qidian/__init__.py +0 -10
  164. novel_downloader/core/downloaders/qidian/qidian_sync.py +0 -227
  165. novel_downloader/core/downloaders/sfacg/__init__.py +0 -14
  166. novel_downloader/core/downloaders/sfacg/sfacg_async.py +0 -27
  167. novel_downloader/core/downloaders/sfacg/sfacg_sync.py +0 -27
  168. novel_downloader/core/downloaders/yamibo/__init__.py +0 -14
  169. novel_downloader/core/downloaders/yamibo/yamibo_async.py +0 -27
  170. novel_downloader/core/downloaders/yamibo/yamibo_sync.py +0 -27
  171. novel_downloader/core/factory/requester.py +0 -144
  172. novel_downloader/core/factory/saver.py +0 -56
  173. novel_downloader/core/interfaces/async_downloader.py +0 -36
  174. novel_downloader/core/interfaces/async_requester.py +0 -84
  175. novel_downloader/core/interfaces/sync_downloader.py +0 -36
  176. novel_downloader/core/interfaces/sync_requester.py +0 -82
  177. novel_downloader/core/parsers/qidian/browser/__init__.py +0 -12
  178. novel_downloader/core/parsers/qidian/browser/chapter_normal.py +0 -93
  179. novel_downloader/core/parsers/qidian/browser/chapter_router.py +0 -71
  180. novel_downloader/core/parsers/qidian/session/__init__.py +0 -12
  181. novel_downloader/core/parsers/qidian/session/chapter_encrypted.py +0 -443
  182. novel_downloader/core/parsers/qidian/session/chapter_normal.py +0 -115
  183. novel_downloader/core/parsers/qidian/session/main_parser.py +0 -128
  184. novel_downloader/core/parsers/qidian/shared/__init__.py +0 -37
  185. novel_downloader/core/parsers/qidian/shared/book_info_parser.py +0 -150
  186. novel_downloader/core/requesters/base/async_session.py +0 -410
  187. novel_downloader/core/requesters/base/browser.py +0 -337
  188. novel_downloader/core/requesters/base/session.py +0 -378
  189. novel_downloader/core/requesters/biquge/__init__.py +0 -14
  190. novel_downloader/core/requesters/common/__init__.py +0 -17
  191. novel_downloader/core/requesters/common/session.py +0 -113
  192. novel_downloader/core/requesters/esjzone/__init__.py +0 -13
  193. novel_downloader/core/requesters/esjzone/session.py +0 -235
  194. novel_downloader/core/requesters/qianbi/__init__.py +0 -13
  195. novel_downloader/core/requesters/qidian/__init__.py +0 -21
  196. novel_downloader/core/requesters/qidian/broswer.py +0 -307
  197. novel_downloader/core/requesters/qidian/session.py +0 -290
  198. novel_downloader/core/requesters/sfacg/__init__.py +0 -13
  199. novel_downloader/core/requesters/sfacg/session.py +0 -242
  200. novel_downloader/core/requesters/yamibo/__init__.py +0 -13
  201. novel_downloader/core/requesters/yamibo/session.py +0 -237
  202. novel_downloader/core/savers/__init__.py +0 -34
  203. novel_downloader/core/savers/biquge.py +0 -25
  204. novel_downloader/core/savers/common/__init__.py +0 -12
  205. novel_downloader/core/savers/epub_utils/__init__.py +0 -26
  206. novel_downloader/core/savers/esjzone.py +0 -25
  207. novel_downloader/core/savers/qianbi.py +0 -25
  208. novel_downloader/core/savers/sfacg.py +0 -25
  209. novel_downloader/core/savers/yamibo.py +0 -25
  210. novel_downloader/resources/config/rules.toml +0 -196
  211. novel_downloader-1.3.2.dist-info/RECORD +0 -165
  212. {novel_downloader-1.3.2.dist-info → novel_downloader-1.4.0.dist-info}/licenses/LICENSE +0 -0
  213. {novel_downloader-1.3.2.dist-info → novel_downloader-1.4.0.dist-info}/top_level.txt +0 -0
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- novel_downloader.core.interfaces.sync_downloader
4
- ------------------------------------------------
5
-
6
- This module defines the SyncDownloaderProtocol, a structural interface
7
- that outlines the expected behavior of any downloader class.
8
- """
9
-
10
- from typing import Protocol
11
-
12
-
13
- class SyncDownloaderProtocol(Protocol):
14
- """
15
- Protocol for downloader classes.
16
-
17
- Defines the expected interface for any downloader implementation,
18
- including both batch and single book downloads,
19
- as well as optional pre-download hooks.
20
- """
21
-
22
- def download(self, book_ids: list[str]) -> None:
23
- """
24
- Batch download entry point.
25
-
26
- :param book_ids: List of book IDs to download.
27
- """
28
- ...
29
-
30
- def download_one(self, book_id: str) -> None:
31
- """
32
- Download logic for a single book.
33
-
34
- :param book_id: The identifier of the book.
35
- """
36
- ...
@@ -1,82 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- novel_downloader.core.interfaces.sync_requester
4
- -----------------------------------------------
5
-
6
- Defines the RequesterProtocol interface for fetching raw HTML or JSON
7
- for book info pages, individual chapters, managing request lifecycle,
8
- and optionally retrieving a user's authenticated bookcase.
9
- """
10
-
11
- from typing import Any, Literal, Protocol, runtime_checkable
12
-
13
-
14
- @runtime_checkable
15
- class SyncRequesterProtocol(Protocol):
16
- """
17
- A requester must be able to fetch raw HTML/data for:
18
- - a book's info page,
19
- - a specific chapter page.
20
- """
21
-
22
- def is_async(self) -> Literal[False]:
23
- ...
24
-
25
- def login(
26
- self,
27
- username: str = "",
28
- password: str = "",
29
- manual_login: bool = False,
30
- **kwargs: Any,
31
- ) -> bool:
32
- """
33
- Attempt to log in
34
- """
35
- ...
36
-
37
- def get_book_info(
38
- self,
39
- book_id: str,
40
- **kwargs: Any,
41
- ) -> list[str]:
42
- """
43
- Fetch the raw HTML (or JSON) of the book info page.
44
-
45
- :param book_id: The book identifier.
46
- :return: The page content as a string.
47
- """
48
- ...
49
-
50
- def get_book_chapter(
51
- self,
52
- book_id: str,
53
- chapter_id: str,
54
- **kwargs: Any,
55
- ) -> list[str]:
56
- """
57
- Fetch the raw HTML (or JSON) of a single chapter.
58
-
59
- :param book_id: The book identifier.
60
- :param chapter_id: The chapter identifier.
61
- :return: The chapter content as a string.
62
- """
63
- ...
64
-
65
- def get_bookcase(
66
- self,
67
- page: int = 1,
68
- **kwargs: Any,
69
- ) -> list[str]:
70
- """
71
- Optional: Retrieve the HTML content of the authenticated user's bookcase page.
72
-
73
- :param page: Page idx
74
- :return: The HTML markup of the bookcase page.
75
- """
76
- ...
77
-
78
- def close(self) -> None:
79
- """
80
- Shutdown and cleans up resources.
81
- """
82
- ...
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- novel_downloader.core.parsers.qidian.browser
4
- --------------------------------------------
5
-
6
- This package provides parsing components for handling Qidian
7
- pages that have been rendered by a browser engine.
8
- """
9
-
10
- from .main_parser import QidianBrowserParser
11
-
12
- __all__ = ["QidianBrowserParser"]
@@ -1,93 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- novel_downloader.core.parsers.qidian.browser.chapter_normal
4
- -----------------------------------------------------------
5
-
6
- Parser logic for extracting readable text from Qidian chapters
7
- that use plain (non-encrypted) browser-rendered HTML.
8
- """
9
-
10
- import logging
11
-
12
- from bs4 import BeautifulSoup
13
-
14
- from novel_downloader.utils.chapter_storage import ChapterDict
15
-
16
- from ..shared import (
17
- extract_chapter_info,
18
- find_ssr_page_context,
19
- )
20
-
21
- logger = logging.getLogger(__name__)
22
-
23
-
24
- def parse_normal_chapter(
25
- soup: BeautifulSoup,
26
- chapter_id: str,
27
- ) -> ChapterDict | None:
28
- """
29
- Extract and format the chapter text from a normal Qidian page.
30
- Returns empty string if VIP/encrypted.
31
-
32
- This method performs the following steps:
33
- 1. Parses HTML into soup.
34
- 2. Skips parsing if VIP or encrypted.
35
- 3. Locates main content container.
36
- 4. Extracts SSR-rendered chapter info (title, author note).
37
- 5. Removes review spans.
38
- 6. Extracts paragraph texts and formats them.
39
-
40
- :param html_str: Raw HTML content of the chapter page.
41
- :return: Formatted chapter text or empty string if not parsable.
42
- """
43
- try:
44
- main = soup.select_one("div#app div#reader-content main")
45
- if not main:
46
- logger.warning("[Parser] Main content not found for chapter")
47
- return None
48
-
49
- ssr_data = find_ssr_page_context(soup)
50
- chapter_info = extract_chapter_info(ssr_data)
51
- if not chapter_info:
52
- logger.warning(
53
- "[Parser] ssr_chapterInfo not found for chapter '%s'", chapter_id
54
- )
55
- return None
56
-
57
- title = chapter_info.get("chapterName", "Untitled")
58
- chapter_id = chapter_info.get("chapterId", "")
59
- author_say = chapter_info.get("authorSay", "")
60
- update_time = chapter_info.get("updateTime", "")
61
- update_timestamp = chapter_info.get("updateTimestamp", 0)
62
- modify_time = chapter_info.get("modifyTime", 0)
63
- word_count = chapter_info.get("wordsCount", 0)
64
- seq = chapter_info.get("seq", None)
65
- volume = chapter_info.get("extra", {}).get("volumeName", "")
66
-
67
- # remove review spans
68
- for span in main.select("span.review"):
69
- span.decompose()
70
-
71
- paras = [p.get_text(strip=True) for p in main.find_all("p")]
72
- chapter_text = "\n\n".join(paras)
73
-
74
- return {
75
- "id": str(chapter_id),
76
- "title": title,
77
- "content": chapter_text,
78
- "extra": {
79
- "author_say": author_say.strip() if author_say else "",
80
- "updated_at": update_time,
81
- "update_timestamp": update_timestamp,
82
- "modify_time": modify_time,
83
- "word_count": word_count,
84
- "seq": seq,
85
- "volume": volume,
86
- },
87
- }
88
-
89
- except Exception as e:
90
- logger.warning(
91
- "[Parser] parse error for normal chapter '%s': %s", chapter_id, e
92
- )
93
- return None
@@ -1,71 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- novel_downloader.core.parsers.qidian.browser.chapter_router
4
- -----------------------------------------------------------
5
-
6
- Routing logic for selecting the correct chapter parser for Qidian browser pages.
7
-
8
- This module acts as a dispatcher that analyzes a chapter's HTML content and
9
- routes the parsing task to either the encrypted or normal chapter parser.
10
- """
11
-
12
- from __future__ import annotations
13
-
14
- import logging
15
- from typing import TYPE_CHECKING
16
-
17
- from novel_downloader.utils.chapter_storage import ChapterDict
18
-
19
- from ..shared import (
20
- can_view_chapter,
21
- html_to_soup,
22
- is_encrypted,
23
- )
24
- from .chapter_normal import parse_normal_chapter
25
-
26
- if TYPE_CHECKING:
27
- from .main_parser import QidianBrowserParser
28
-
29
- logger = logging.getLogger(__name__)
30
-
31
-
32
- def parse_chapter(
33
- parser: QidianBrowserParser,
34
- html_str: str,
35
- chapter_id: str,
36
- ) -> ChapterDict | None:
37
- """
38
- Extract and return the formatted textual content of chapter.
39
-
40
- :param parser: Instance of QidianBrowserParser.
41
- :param html_str: Raw HTML content of the chapter page.
42
- :param chapter_id: Identifier of the chapter being parsed.
43
- :return: Formatted chapter text or empty string if not parsable.
44
- """
45
- try:
46
- soup = html_to_soup(html_str)
47
-
48
- if not can_view_chapter(soup):
49
- logger.warning(
50
- "[Parser] Chapter '%s' is not purchased or inaccessible.", chapter_id
51
- )
52
- return None
53
-
54
- if is_encrypted(soup):
55
- if not parser._decode_font:
56
- return None
57
- try:
58
- from .chapter_encrypted import parse_encrypted_chapter
59
-
60
- return parse_encrypted_chapter(parser, soup, chapter_id)
61
- except ImportError:
62
- logger.warning(
63
- "[Parser] Encrypted chapter '%s' requires extra dependencies.",
64
- chapter_id,
65
- )
66
- return None
67
-
68
- return parse_normal_chapter(soup, chapter_id)
69
- except Exception as e:
70
- logger.warning("[Parser] parse error for chapter '%s': %s", chapter_id, e)
71
- return None
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- novel_downloader.core.parsers.qidian.session
4
- --------------------------------------------
5
-
6
- This package provides parsing components for handling Qidian
7
- pages that have been rendered by a session.
8
- """
9
-
10
- from .main_parser import QidianSessionParser
11
-
12
- __all__ = ["QidianSessionParser"]