jmcomic 2.5.6__tar.gz → 2.5.7__tar.gz
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.
- {jmcomic-2.5.6/src/jmcomic.egg-info → jmcomic-2.5.7}/PKG-INFO +31 -18
- {jmcomic-2.5.6 → jmcomic-2.5.7}/README.md +30 -17
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/__init__.py +1 -1
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/api.py +3 -2
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/jm_client_interface.py +6 -8
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/jm_config.py +16 -15
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/jm_downloader.py +45 -11
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/jm_option.py +31 -5
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/jm_plugin.py +3 -3
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/jm_toolkit.py +5 -5
- {jmcomic-2.5.6 → jmcomic-2.5.7/src/jmcomic.egg-info}/PKG-INFO +31 -18
- {jmcomic-2.5.6 → jmcomic-2.5.7}/LICENSE +0 -0
- {jmcomic-2.5.6 → jmcomic-2.5.7}/setup.cfg +0 -0
- {jmcomic-2.5.6 → jmcomic-2.5.7}/setup.py +0 -0
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/cl.py +0 -0
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/jm_client_impl.py +0 -0
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/jm_entity.py +0 -0
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic/jm_exception.py +0 -0
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic.egg-info/SOURCES.txt +0 -0
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic.egg-info/dependency_links.txt +0 -0
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic.egg-info/entry_points.txt +0 -0
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic.egg-info/requires.txt +0 -0
- {jmcomic-2.5.6 → jmcomic-2.5.7}/src/jmcomic.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: jmcomic
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.7
|
|
4
4
|
Summary: Python API For JMComic (禁漫天堂)
|
|
5
5
|
Home-page: https://github.com/hect0x7/JMComic-Crawler-Python
|
|
6
6
|
Author: hect0x7
|
|
@@ -42,16 +42,26 @@ Requires-Dist: pycryptodome
|
|
|
42
42
|
|
|
43
43
|
本项目的核心功能是下载本子,基于此,设计了一套方便使用、便于扩展,能满足一些特殊下载需求的框架。
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
目前核心功能实现较为稳定,项目也处于维护阶段。
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
除了下载功能以外,也实现了其他的一些禁漫接口,按需实现,具体如下。
|
|
48
|
+
|
|
49
|
+
### 已实现的禁漫API:
|
|
50
|
+
|
|
51
|
+
- 登录
|
|
52
|
+
- 搜本
|
|
53
|
+
- 分类 (排行榜)
|
|
54
|
+
- 本子章节详情
|
|
55
|
+
- 图片下载解码
|
|
56
|
+
- 收藏夹
|
|
57
|
+
- 移动端接口加解密
|
|
48
58
|
|
|
49
59
|
## 安装教程
|
|
50
60
|
|
|
51
61
|
* 通过pip官方源安装(推荐,并且更新也是这个命令)
|
|
52
62
|
|
|
53
63
|
```shell
|
|
54
|
-
pip install jmcomic -i https://pypi.org/project
|
|
64
|
+
pip install jmcomic -i https://pypi.org/project -U
|
|
55
65
|
```
|
|
56
66
|
* 通过源代码安装
|
|
57
67
|
|
|
@@ -75,6 +85,21 @@ jmcomic.download_album('422866') # 传入要下载的album的id,即可下载
|
|
|
75
85
|
$ jmcomic 422866
|
|
76
86
|
```
|
|
77
87
|
|
|
88
|
+
## 进阶使用
|
|
89
|
+
|
|
90
|
+
文档网站:[jmcomic.readthedocs.io](https://jmcomic.readthedocs.io/en/latest)
|
|
91
|
+
|
|
92
|
+
进阶使用可以参考:[jmcomic常用类和方法演示](assets/docs/sources/tutorial/0_demo.md)
|
|
93
|
+
|
|
94
|
+
下面列出的是一些常用的文档:
|
|
95
|
+
|
|
96
|
+
* [jmcomic常用类和方法演示](assets/docs/sources/tutorial/0_demo.md)
|
|
97
|
+
* [option配置文件语法(包含插件配置)](./assets/docs/sources/option_file_syntax.md)
|
|
98
|
+
* [GitHub Actions使用教程](./assets/docs/sources/tutorial/1_github_actions.md)
|
|
99
|
+
* [命令行使用教程](assets/docs/sources/tutorial/2_command_line.md)
|
|
100
|
+
* [插件机制](assets/docs/sources/tutorial/6_plugin.md)
|
|
101
|
+
* [下载过滤器机制](assets/docs/sources/tutorial/5_filter.md)
|
|
102
|
+
|
|
78
103
|
## 项目特点
|
|
79
104
|
|
|
80
105
|
- **绕过Cloudflare的反爬虫**
|
|
@@ -111,19 +136,6 @@ $ jmcomic 422866
|
|
|
111
136
|
- `jpg图片合成为一个pdf插件`
|
|
112
137
|
- `导出收藏夹为csv文件插件`
|
|
113
138
|
|
|
114
|
-
## 进阶使用
|
|
115
|
-
|
|
116
|
-
进阶使用请查阅文档:[文档](https://jmcomic.readthedocs.io/en/latest)
|
|
117
|
-
|
|
118
|
-
下面列出一些常用的文档链接:
|
|
119
|
-
|
|
120
|
-
* [option配置文件语法(包含插件配置)](./assets/docs/sources/option_file_syntax.md)
|
|
121
|
-
* [常用类和方法演示(下载本子、获取实体类、搜索本子)](assets/docs/sources/tutorial/3_demo.md)
|
|
122
|
-
* [命令行使用教程](assets/docs/sources/tutorial/2_command_line.md)
|
|
123
|
-
* [GitHub Actions使用教程](./assets/docs/sources/tutorial/1_github_actions.md)
|
|
124
|
-
* [插件机制](assets/docs/sources/tutorial/6_plugin.md)
|
|
125
|
-
* [下载过滤器机制](assets/docs/sources/tutorial/5_filter.md)
|
|
126
|
-
|
|
127
139
|
## 使用小说明
|
|
128
140
|
|
|
129
141
|
* Python >= 3.7
|
|
@@ -131,10 +143,11 @@ $ jmcomic 422866
|
|
|
131
143
|
|
|
132
144
|
## 项目文件夹介绍
|
|
133
145
|
|
|
146
|
+
* .github:GitHub Actions配置文件
|
|
134
147
|
* assets:存放一些非代码的资源文件
|
|
135
148
|
|
|
136
|
-
* config:存放配置文件
|
|
137
149
|
* docs:项目文档
|
|
150
|
+
* option:存放配置文件
|
|
138
151
|
|
|
139
152
|
* src:存放源代码
|
|
140
153
|
|
|
@@ -14,16 +14,26 @@
|
|
|
14
14
|
|
|
15
15
|
本项目的核心功能是下载本子,基于此,设计了一套方便使用、便于扩展,能满足一些特殊下载需求的框架。
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
目前核心功能实现较为稳定,项目也处于维护阶段。
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
除了下载功能以外,也实现了其他的一些禁漫接口,按需实现,具体如下。
|
|
20
|
+
|
|
21
|
+
### 已实现的禁漫API:
|
|
22
|
+
|
|
23
|
+
- 登录
|
|
24
|
+
- 搜本
|
|
25
|
+
- 分类 (排行榜)
|
|
26
|
+
- 本子章节详情
|
|
27
|
+
- 图片下载解码
|
|
28
|
+
- 收藏夹
|
|
29
|
+
- 移动端接口加解密
|
|
20
30
|
|
|
21
31
|
## 安装教程
|
|
22
32
|
|
|
23
33
|
* 通过pip官方源安装(推荐,并且更新也是这个命令)
|
|
24
34
|
|
|
25
35
|
```shell
|
|
26
|
-
pip install jmcomic -i https://pypi.org/project
|
|
36
|
+
pip install jmcomic -i https://pypi.org/project -U
|
|
27
37
|
```
|
|
28
38
|
* 通过源代码安装
|
|
29
39
|
|
|
@@ -47,6 +57,21 @@ jmcomic.download_album('422866') # 传入要下载的album的id,即可下载
|
|
|
47
57
|
$ jmcomic 422866
|
|
48
58
|
```
|
|
49
59
|
|
|
60
|
+
## 进阶使用
|
|
61
|
+
|
|
62
|
+
文档网站:[jmcomic.readthedocs.io](https://jmcomic.readthedocs.io/en/latest)
|
|
63
|
+
|
|
64
|
+
进阶使用可以参考:[jmcomic常用类和方法演示](assets/docs/sources/tutorial/0_demo.md)
|
|
65
|
+
|
|
66
|
+
下面列出的是一些常用的文档:
|
|
67
|
+
|
|
68
|
+
* [jmcomic常用类和方法演示](assets/docs/sources/tutorial/0_demo.md)
|
|
69
|
+
* [option配置文件语法(包含插件配置)](./assets/docs/sources/option_file_syntax.md)
|
|
70
|
+
* [GitHub Actions使用教程](./assets/docs/sources/tutorial/1_github_actions.md)
|
|
71
|
+
* [命令行使用教程](assets/docs/sources/tutorial/2_command_line.md)
|
|
72
|
+
* [插件机制](assets/docs/sources/tutorial/6_plugin.md)
|
|
73
|
+
* [下载过滤器机制](assets/docs/sources/tutorial/5_filter.md)
|
|
74
|
+
|
|
50
75
|
## 项目特点
|
|
51
76
|
|
|
52
77
|
- **绕过Cloudflare的反爬虫**
|
|
@@ -83,19 +108,6 @@ $ jmcomic 422866
|
|
|
83
108
|
- `jpg图片合成为一个pdf插件`
|
|
84
109
|
- `导出收藏夹为csv文件插件`
|
|
85
110
|
|
|
86
|
-
## 进阶使用
|
|
87
|
-
|
|
88
|
-
进阶使用请查阅文档:[文档](https://jmcomic.readthedocs.io/en/latest)
|
|
89
|
-
|
|
90
|
-
下面列出一些常用的文档链接:
|
|
91
|
-
|
|
92
|
-
* [option配置文件语法(包含插件配置)](./assets/docs/sources/option_file_syntax.md)
|
|
93
|
-
* [常用类和方法演示(下载本子、获取实体类、搜索本子)](assets/docs/sources/tutorial/3_demo.md)
|
|
94
|
-
* [命令行使用教程](assets/docs/sources/tutorial/2_command_line.md)
|
|
95
|
-
* [GitHub Actions使用教程](./assets/docs/sources/tutorial/1_github_actions.md)
|
|
96
|
-
* [插件机制](assets/docs/sources/tutorial/6_plugin.md)
|
|
97
|
-
* [下载过滤器机制](assets/docs/sources/tutorial/5_filter.md)
|
|
98
|
-
|
|
99
111
|
## 使用小说明
|
|
100
112
|
|
|
101
113
|
* Python >= 3.7
|
|
@@ -103,10 +115,11 @@ $ jmcomic 422866
|
|
|
103
115
|
|
|
104
116
|
## 项目文件夹介绍
|
|
105
117
|
|
|
118
|
+
* .github:GitHub Actions配置文件
|
|
106
119
|
* assets:存放一些非代码的资源文件
|
|
107
120
|
|
|
108
|
-
* config:存放配置文件
|
|
109
121
|
* docs:项目文档
|
|
122
|
+
* option:存放配置文件
|
|
110
123
|
|
|
111
124
|
* src:存放源代码
|
|
112
125
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
from .jm_downloader import *
|
|
2
2
|
|
|
3
|
+
__DOWNLOAD_API_RET = Tuple[JmAlbumDetail, JmDownloader]
|
|
3
4
|
|
|
4
5
|
def download_batch(download_api,
|
|
5
6
|
jm_id_iter: Union[Iterable, Generator],
|
|
6
7
|
option=None,
|
|
7
8
|
downloader=None,
|
|
8
|
-
) -> Set[
|
|
9
|
+
) -> Set[__DOWNLOAD_API_RET]:
|
|
9
10
|
"""
|
|
10
11
|
批量下载 album / photo
|
|
11
12
|
|
|
@@ -46,7 +47,7 @@ def download_album(jm_album_id,
|
|
|
46
47
|
option=None,
|
|
47
48
|
downloader=None,
|
|
48
49
|
callback=None,
|
|
49
|
-
):
|
|
50
|
+
) -> Union[__DOWNLOAD_API_RET, Set[__DOWNLOAD_API_RET]]:
|
|
50
51
|
"""
|
|
51
52
|
下载一个本子(album),包含其所有的章节(photo)
|
|
52
53
|
|
|
@@ -6,8 +6,6 @@ Response Entity
|
|
|
6
6
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
DictModel = AdvancedEasyAccessDict
|
|
10
|
-
|
|
11
9
|
|
|
12
10
|
class JmResp:
|
|
13
11
|
|
|
@@ -87,11 +85,11 @@ class JmJsonResp(JmResp):
|
|
|
87
85
|
def json(self) -> Dict:
|
|
88
86
|
try:
|
|
89
87
|
return self.resp.json()
|
|
90
|
-
except Exception:
|
|
91
|
-
ExceptionTool.raises_resp('json
|
|
88
|
+
except Exception as e:
|
|
89
|
+
ExceptionTool.raises_resp(f'json解析失败: {e}', self, JsonResolveFailException)
|
|
92
90
|
|
|
93
|
-
def model(self) ->
|
|
94
|
-
return
|
|
91
|
+
def model(self) -> AdvancedEasyAccessDict:
|
|
92
|
+
return AdvancedEasyAccessDict(self.json())
|
|
95
93
|
|
|
96
94
|
|
|
97
95
|
class JmApiResp(JmJsonResp):
|
|
@@ -120,9 +118,9 @@ class JmApiResp(JmJsonResp):
|
|
|
120
118
|
return loads(self.decoded_data)
|
|
121
119
|
|
|
122
120
|
@property
|
|
123
|
-
def model_data(self) ->
|
|
121
|
+
def model_data(self) -> AdvancedEasyAccessDict:
|
|
124
122
|
self.require_success()
|
|
125
|
-
return
|
|
123
|
+
return AdvancedEasyAccessDict(self.res_data)
|
|
126
124
|
|
|
127
125
|
|
|
128
126
|
# album-comment
|
|
@@ -2,8 +2,8 @@ from common import time_stamp, str_to_list, field_cache, ProxyBuilder
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
def default_jm_logging(topic: str, msg: str):
|
|
5
|
-
from common import format_ts
|
|
6
|
-
print(
|
|
5
|
+
from common import format_ts, current_thread
|
|
6
|
+
print('[{}] [{}]:【{}】{}'.format(format_ts(), current_thread().name, topic, msg))
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
# 禁漫常量
|
|
@@ -24,17 +24,18 @@ class JmMagicConstants:
|
|
|
24
24
|
TIME_MONTH = 'm'
|
|
25
25
|
TIME_ALL = 'a'
|
|
26
26
|
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
# 分类参数API接口的category
|
|
28
|
+
CATEGORY_ALL = '0' # 全部
|
|
29
|
+
CATEGORY_DOUJIN = 'doujin' # 同人
|
|
30
|
+
CATEGORY_SINGLE = 'single' # 单本
|
|
31
|
+
CATEGORY_SHORT = 'short' # 短篇
|
|
32
|
+
CATEGORY_ANOTHER = 'another' # 其他
|
|
33
|
+
CATEGORY_HANMAN = 'hanman' # 韩漫
|
|
34
|
+
CATEGORY_MEIMAN = 'meiman' # 美漫
|
|
35
|
+
CATEGORY_DOUJIN_COSPLAY = 'doujin_cosplay' # cosplay
|
|
36
|
+
CATEGORY_3D = '3D' # 3D
|
|
37
|
+
CATEGORY_ENGLISH_SITE = 'english_site' # 英文站
|
|
38
|
+
CATEGORY_JM_TEAM = '禁漫漢化組'
|
|
38
39
|
|
|
39
40
|
# 分页大小
|
|
40
41
|
PAGE_SIZE_SEARCH = 80
|
|
@@ -52,10 +53,10 @@ class JmMagicConstants:
|
|
|
52
53
|
APP_TOKEN_SECRET = '18comicAPP'
|
|
53
54
|
APP_TOKEN_SECRET_2 = '18comicAPPContent'
|
|
54
55
|
APP_DATA_SECRET = '185Hcomic3PAPP7R'
|
|
55
|
-
APP_VERSION = '1.6.
|
|
56
|
+
APP_VERSION = '1.6.7'
|
|
56
57
|
APP_HEADERS_TEMPLATE = {
|
|
57
58
|
'Accept-Encoding': 'gzip',
|
|
58
|
-
'user-agent': 'Mozilla/5.0 (Linux; Android 9; V1938CT Build/PQ3A.190705.
|
|
59
|
+
'user-agent': 'Mozilla/5.0 (Linux; Android 9; V1938CT Build/PQ3A.190705.11211812; wv) AppleWebKit/537.36 (KHTML, '
|
|
59
60
|
'like Gecko) Version/4.0 Chrome/91.0.4472.114 Safari/537.36',
|
|
60
61
|
}
|
|
61
62
|
|
|
@@ -50,8 +50,10 @@ class JmDownloader(DownloadCallback):
|
|
|
50
50
|
|
|
51
51
|
def __init__(self, option: JmOption) -> None:
|
|
52
52
|
self.option = option
|
|
53
|
-
#
|
|
54
|
-
self.
|
|
53
|
+
# 下载成功的记录dict
|
|
54
|
+
self.download_success_dict: Dict[JmAlbumDetail, Dict[JmPhotoDetail, List[Tuple[str, JmImageDetail]]]] = {}
|
|
55
|
+
# 下载失败的记录list
|
|
56
|
+
self.download_failed_list: List[Tuple[JmImageDetail, BaseException]] = []
|
|
55
57
|
|
|
56
58
|
def download_album(self, album_id):
|
|
57
59
|
client = self.client_for_album(album_id)
|
|
@@ -101,11 +103,21 @@ class JmDownloader(DownloadCallback):
|
|
|
101
103
|
if use_cache is True and image.is_exists:
|
|
102
104
|
return
|
|
103
105
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
e = None
|
|
107
|
+
try:
|
|
108
|
+
client.download_by_image_detail(
|
|
109
|
+
image,
|
|
110
|
+
img_save_path,
|
|
111
|
+
decode_image=decode_image,
|
|
112
|
+
)
|
|
113
|
+
except BaseException as e:
|
|
114
|
+
jm_log('image.failed', f'图片下载失败: [{image.download_url}], 异常: {e}')
|
|
115
|
+
# 保存失败记录
|
|
116
|
+
self.download_failed_list.append((image, e))
|
|
117
|
+
|
|
118
|
+
if e is not None:
|
|
119
|
+
raise e
|
|
120
|
+
|
|
109
121
|
self.after_image(image, img_save_path)
|
|
110
122
|
|
|
111
123
|
# noinspection PyMethodMayBeStatic
|
|
@@ -164,11 +176,33 @@ class JmDownloader(DownloadCallback):
|
|
|
164
176
|
"""
|
|
165
177
|
return self.option.build_jm_client()
|
|
166
178
|
|
|
179
|
+
@property
|
|
180
|
+
def all_success(self) -> bool:
|
|
181
|
+
"""
|
|
182
|
+
是否成功下载了全部图片
|
|
183
|
+
|
|
184
|
+
该属性需要等到downloader的全部download_xxx方法完成后才有意义。
|
|
185
|
+
|
|
186
|
+
注意!如果使用了filter机制,例如通过filter只下载3张图片,那么all_success也会为False
|
|
187
|
+
"""
|
|
188
|
+
if len(self.download_failed_list) != 0:
|
|
189
|
+
return False
|
|
190
|
+
|
|
191
|
+
for album, photo_dict in self.download_success_dict.items():
|
|
192
|
+
if len(album) != len(photo_dict):
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
for photo, image_list in photo_dict.items():
|
|
196
|
+
if len(photo) != len(image_list):
|
|
197
|
+
return False
|
|
198
|
+
|
|
199
|
+
return True
|
|
200
|
+
|
|
167
201
|
# 下面是回调方法
|
|
168
202
|
|
|
169
203
|
def before_album(self, album: JmAlbumDetail):
|
|
170
204
|
super().before_album(album)
|
|
171
|
-
self.
|
|
205
|
+
self.download_success_dict.setdefault(album, {})
|
|
172
206
|
self.option.call_all_plugin(
|
|
173
207
|
'before_album',
|
|
174
208
|
album=album,
|
|
@@ -185,8 +219,8 @@ class JmDownloader(DownloadCallback):
|
|
|
185
219
|
|
|
186
220
|
def before_photo(self, photo: JmPhotoDetail):
|
|
187
221
|
super().before_photo(photo)
|
|
188
|
-
self.
|
|
189
|
-
self.
|
|
222
|
+
self.download_success_dict.setdefault(photo.from_album, {})
|
|
223
|
+
self.download_success_dict[photo.from_album].setdefault(photo, [])
|
|
190
224
|
self.option.call_all_plugin(
|
|
191
225
|
'before_photo',
|
|
192
226
|
photo=photo,
|
|
@@ -214,7 +248,7 @@ class JmDownloader(DownloadCallback):
|
|
|
214
248
|
photo = image.from_photo
|
|
215
249
|
album = photo.from_album
|
|
216
250
|
|
|
217
|
-
self.
|
|
251
|
+
self.download_success_dict.get(album).get(photo).append((img_save_path, image))
|
|
218
252
|
self.option.call_all_plugin(
|
|
219
253
|
'after_image',
|
|
220
254
|
image=image,
|
|
@@ -105,13 +105,11 @@ class DirRule:
|
|
|
105
105
|
解析下载路径dsl,得到一个路径规则解析列表
|
|
106
106
|
"""
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
ExceptionTool.raises(f'不支持的dsl: "{rule_dsl}"')
|
|
110
|
-
|
|
111
|
-
rule_list = rule_dsl.split('_')
|
|
108
|
+
rule_list = self.split_rule_dsl(rule_dsl)
|
|
112
109
|
solver_ls: List[DirRule.RuleSolver] = []
|
|
113
110
|
|
|
114
111
|
for rule in rule_list:
|
|
112
|
+
rule = rule.strip()
|
|
115
113
|
if rule == 'Bd':
|
|
116
114
|
solver_ls.append((0, lambda _: base_dir, 'Bd'))
|
|
117
115
|
continue
|
|
@@ -124,6 +122,19 @@ class DirRule:
|
|
|
124
122
|
|
|
125
123
|
return solver_ls
|
|
126
124
|
|
|
125
|
+
# noinspection PyMethodMayBeStatic
|
|
126
|
+
def split_rule_dsl(self, rule_dsl: str) -> List[str]:
|
|
127
|
+
if rule_dsl == 'Bd':
|
|
128
|
+
return [rule_dsl]
|
|
129
|
+
|
|
130
|
+
if '/' in rule_dsl:
|
|
131
|
+
return rule_dsl.split('/')
|
|
132
|
+
|
|
133
|
+
if '_' in rule_dsl:
|
|
134
|
+
return rule_dsl.split('_')
|
|
135
|
+
|
|
136
|
+
ExceptionTool.raises(f'不支持的rule配置: "{rule_dsl}"')
|
|
137
|
+
|
|
127
138
|
@classmethod
|
|
128
139
|
def get_rule_solver(cls, rule: str) -> Optional[RuleSolver]:
|
|
129
140
|
# 查找缓存
|
|
@@ -181,6 +192,7 @@ class JmOption:
|
|
|
181
192
|
client: Dict,
|
|
182
193
|
plugins: Dict,
|
|
183
194
|
filepath=None,
|
|
195
|
+
call_after_init_plugin=True,
|
|
184
196
|
):
|
|
185
197
|
# 路径规则配置
|
|
186
198
|
self.dir_rule = DirRule(**dir_rule)
|
|
@@ -196,7 +208,21 @@ class JmOption:
|
|
|
196
208
|
# 需要主线程等待完成的插件
|
|
197
209
|
self.need_wait_plugins = []
|
|
198
210
|
|
|
199
|
-
|
|
211
|
+
if call_after_init_plugin:
|
|
212
|
+
self.call_all_plugin('after_init', safe=True)
|
|
213
|
+
|
|
214
|
+
def copy_option(self):
|
|
215
|
+
return self.__class__(
|
|
216
|
+
dir_rule={
|
|
217
|
+
'rule': self.dir_rule.rule_dsl,
|
|
218
|
+
'base_dir': self.dir_rule.base_dir,
|
|
219
|
+
},
|
|
220
|
+
download=self.download.src_dict,
|
|
221
|
+
client=self.client.src_dict,
|
|
222
|
+
plugins=self.plugins.src_dict,
|
|
223
|
+
filepath=self.filepath,
|
|
224
|
+
call_after_init_plugin=False
|
|
225
|
+
)
|
|
200
226
|
|
|
201
227
|
"""
|
|
202
228
|
下面是decide系列方法,为了支持重写和增加程序动态性。
|
|
@@ -298,7 +298,7 @@ class ZipPlugin(JmOptionPlugin):
|
|
|
298
298
|
|
|
299
299
|
# 原文件夹 -> zip文件
|
|
300
300
|
dir_zip_dict: Dict[str, Optional[str]] = {}
|
|
301
|
-
photo_dict = downloader.
|
|
301
|
+
photo_dict = downloader.download_success_dict[album]
|
|
302
302
|
|
|
303
303
|
if level == 'album':
|
|
304
304
|
zip_path = self.get_zip_path(album, None, filename_rule, suffix, zip_dir)
|
|
@@ -383,7 +383,7 @@ class ZipPlugin(JmOptionPlugin):
|
|
|
383
383
|
dirs = sorted(dir_zip_dict.keys(), reverse=True)
|
|
384
384
|
image_paths = [
|
|
385
385
|
path
|
|
386
|
-
for photo_dict in self.downloader.
|
|
386
|
+
for photo_dict in self.downloader.download_success_dict.values()
|
|
387
387
|
for image_list in photo_dict.values()
|
|
388
388
|
for path, image in image_list
|
|
389
389
|
]
|
|
@@ -752,7 +752,7 @@ class ConvertJpgToPdfPlugin(JmOptionPlugin):
|
|
|
752
752
|
|
|
753
753
|
paths = [
|
|
754
754
|
path
|
|
755
|
-
for path, image in downloader.
|
|
755
|
+
for path, image in downloader.download_success_dict[photo.from_album][photo]
|
|
756
756
|
]
|
|
757
757
|
|
|
758
758
|
paths.append(self.option.decide_image_save_dir(photo, ensure_exists=False))
|
|
@@ -472,7 +472,7 @@ class JmPageTool:
|
|
|
472
472
|
return JmFavoritePage(content, folder_list, total)
|
|
473
473
|
|
|
474
474
|
@classmethod
|
|
475
|
-
def parse_api_to_search_page(cls, data:
|
|
475
|
+
def parse_api_to_search_page(cls, data: AdvancedEasyAccessDict) -> JmSearchPage:
|
|
476
476
|
"""
|
|
477
477
|
model_data: {
|
|
478
478
|
"search_query": "MANA",
|
|
@@ -501,7 +501,7 @@ class JmPageTool:
|
|
|
501
501
|
return JmSearchPage(content, total)
|
|
502
502
|
|
|
503
503
|
@classmethod
|
|
504
|
-
def parse_api_to_favorite_page(cls, data:
|
|
504
|
+
def parse_api_to_favorite_page(cls, data: AdvancedEasyAccessDict) -> JmFavoritePage:
|
|
505
505
|
"""
|
|
506
506
|
{
|
|
507
507
|
"list": [
|
|
@@ -546,7 +546,7 @@ class JmPageTool:
|
|
|
546
546
|
|
|
547
547
|
@classmethod
|
|
548
548
|
def adapt_content(cls, content):
|
|
549
|
-
def adapt_item(item:
|
|
549
|
+
def adapt_item(item: AdvancedEasyAccessDict):
|
|
550
550
|
item: dict = item.src_dict
|
|
551
551
|
item.setdefault('tags', [])
|
|
552
552
|
return item
|
|
@@ -673,7 +673,7 @@ class JmApiAdaptTool:
|
|
|
673
673
|
series = data['series']
|
|
674
674
|
episode_list = []
|
|
675
675
|
for chapter in series:
|
|
676
|
-
chapter =
|
|
676
|
+
chapter = AdvancedEasyAccessDict(chapter)
|
|
677
677
|
# photo_id, photo_index, photo_title, photo_pub_date
|
|
678
678
|
episode_list.append(
|
|
679
679
|
(chapter.id, chapter.sort, chapter.name, None)
|
|
@@ -688,7 +688,7 @@ class JmApiAdaptTool:
|
|
|
688
688
|
sort = 1
|
|
689
689
|
series: list = data['series'] # series中的sort从1开始
|
|
690
690
|
for chapter in series:
|
|
691
|
-
chapter =
|
|
691
|
+
chapter = AdvancedEasyAccessDict(chapter)
|
|
692
692
|
if int(chapter.id) == int(data['id']):
|
|
693
693
|
sort = chapter.sort
|
|
694
694
|
break
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: jmcomic
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.7
|
|
4
4
|
Summary: Python API For JMComic (禁漫天堂)
|
|
5
5
|
Home-page: https://github.com/hect0x7/JMComic-Crawler-Python
|
|
6
6
|
Author: hect0x7
|
|
@@ -42,16 +42,26 @@ Requires-Dist: pycryptodome
|
|
|
42
42
|
|
|
43
43
|
本项目的核心功能是下载本子,基于此,设计了一套方便使用、便于扩展,能满足一些特殊下载需求的框架。
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
目前核心功能实现较为稳定,项目也处于维护阶段。
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
除了下载功能以外,也实现了其他的一些禁漫接口,按需实现,具体如下。
|
|
48
|
+
|
|
49
|
+
### 已实现的禁漫API:
|
|
50
|
+
|
|
51
|
+
- 登录
|
|
52
|
+
- 搜本
|
|
53
|
+
- 分类 (排行榜)
|
|
54
|
+
- 本子章节详情
|
|
55
|
+
- 图片下载解码
|
|
56
|
+
- 收藏夹
|
|
57
|
+
- 移动端接口加解密
|
|
48
58
|
|
|
49
59
|
## 安装教程
|
|
50
60
|
|
|
51
61
|
* 通过pip官方源安装(推荐,并且更新也是这个命令)
|
|
52
62
|
|
|
53
63
|
```shell
|
|
54
|
-
pip install jmcomic -i https://pypi.org/project
|
|
64
|
+
pip install jmcomic -i https://pypi.org/project -U
|
|
55
65
|
```
|
|
56
66
|
* 通过源代码安装
|
|
57
67
|
|
|
@@ -75,6 +85,21 @@ jmcomic.download_album('422866') # 传入要下载的album的id,即可下载
|
|
|
75
85
|
$ jmcomic 422866
|
|
76
86
|
```
|
|
77
87
|
|
|
88
|
+
## 进阶使用
|
|
89
|
+
|
|
90
|
+
文档网站:[jmcomic.readthedocs.io](https://jmcomic.readthedocs.io/en/latest)
|
|
91
|
+
|
|
92
|
+
进阶使用可以参考:[jmcomic常用类和方法演示](assets/docs/sources/tutorial/0_demo.md)
|
|
93
|
+
|
|
94
|
+
下面列出的是一些常用的文档:
|
|
95
|
+
|
|
96
|
+
* [jmcomic常用类和方法演示](assets/docs/sources/tutorial/0_demo.md)
|
|
97
|
+
* [option配置文件语法(包含插件配置)](./assets/docs/sources/option_file_syntax.md)
|
|
98
|
+
* [GitHub Actions使用教程](./assets/docs/sources/tutorial/1_github_actions.md)
|
|
99
|
+
* [命令行使用教程](assets/docs/sources/tutorial/2_command_line.md)
|
|
100
|
+
* [插件机制](assets/docs/sources/tutorial/6_plugin.md)
|
|
101
|
+
* [下载过滤器机制](assets/docs/sources/tutorial/5_filter.md)
|
|
102
|
+
|
|
78
103
|
## 项目特点
|
|
79
104
|
|
|
80
105
|
- **绕过Cloudflare的反爬虫**
|
|
@@ -111,19 +136,6 @@ $ jmcomic 422866
|
|
|
111
136
|
- `jpg图片合成为一个pdf插件`
|
|
112
137
|
- `导出收藏夹为csv文件插件`
|
|
113
138
|
|
|
114
|
-
## 进阶使用
|
|
115
|
-
|
|
116
|
-
进阶使用请查阅文档:[文档](https://jmcomic.readthedocs.io/en/latest)
|
|
117
|
-
|
|
118
|
-
下面列出一些常用的文档链接:
|
|
119
|
-
|
|
120
|
-
* [option配置文件语法(包含插件配置)](./assets/docs/sources/option_file_syntax.md)
|
|
121
|
-
* [常用类和方法演示(下载本子、获取实体类、搜索本子)](assets/docs/sources/tutorial/3_demo.md)
|
|
122
|
-
* [命令行使用教程](assets/docs/sources/tutorial/2_command_line.md)
|
|
123
|
-
* [GitHub Actions使用教程](./assets/docs/sources/tutorial/1_github_actions.md)
|
|
124
|
-
* [插件机制](assets/docs/sources/tutorial/6_plugin.md)
|
|
125
|
-
* [下载过滤器机制](assets/docs/sources/tutorial/5_filter.md)
|
|
126
|
-
|
|
127
139
|
## 使用小说明
|
|
128
140
|
|
|
129
141
|
* Python >= 3.7
|
|
@@ -131,10 +143,11 @@ $ jmcomic 422866
|
|
|
131
143
|
|
|
132
144
|
## 项目文件夹介绍
|
|
133
145
|
|
|
146
|
+
* .github:GitHub Actions配置文件
|
|
134
147
|
* assets:存放一些非代码的资源文件
|
|
135
148
|
|
|
136
|
-
* config:存放配置文件
|
|
137
149
|
* docs:项目文档
|
|
150
|
+
* option:存放配置文件
|
|
138
151
|
|
|
139
152
|
* src:存放源代码
|
|
140
153
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|