Skip to content

Commit fb609f9

Browse files
authored
v2.1.14: 增加文档和代码示例,优化代码集中配置 (#99)
1 parent 933da4a commit fb609f9

10 files changed

+116
-18
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jmcomic.download_album('422866') # 传入要下载的album的id,即可下载
3333
# 如果你想要配置,请参考assets/config/和usgae/下的文档和示例.
3434
```
3535

36-
进一步的使用可以参考usage文件夹下的示例代码: `getting_started.py` `sample_usage.py`
36+
进一步的使用可以参考usage文件夹下的示例代码: `getting_started.py` `usage_simple.py` `usage_feature_filter`
3737

3838
## 项目特点
3939

@@ -42,7 +42,7 @@ jmcomic.download_album('422866') # 传入要下载的album的id,即可下载
4242
- **可配置性强**
4343
- 不配置也能使用,十分方便
4444
- 配置可以从**配置文件**生成,支持多种文件格式,无需写Python代码
45-
- 配置点有:`是否使用磁盘缓存` `图片类型转换` `下载路径` `请求元信息(headers,cookies,代理)`
45+
- 配置点有:`是否使用磁盘缓存` `图片类型转换` `下载路径` `请求元信息(headers,cookies,代理)`
4646
- **可扩展性强**
4747
- 支持自定义本子/章节/图片下载前后的回调函数
4848
- 支持自定义debug日志的开关/格式

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
package_dir={"": "src"},
2828
python_requires=">=3.7",
2929
install_requires=[
30-
'commonX',
30+
'commonX>=0.5.3',
3131
'curl_cffi',
3232
'PyYAML',
3333
'Pillow',

src/jmcomic/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
# 被依赖方 <--- 使用方
33
# config <--- entity <--- toolkit <--- client <--- option <--- downloader
44

5-
__version__ = '2.1.13'
5+
__version__ = '2.1.14'
66

77
from .api import *

src/jmcomic/jm_client_impl.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,3 +420,7 @@ def __init__(self, workers=None) -> None:
420420
def save_image_resp(self, *args, **kwargs):
421421
future = self.executor.submit(lambda: super().save_image_resp(*args, **kwargs))
422422
self.future_list.append(future)
423+
424+
425+
JmModuleConfig.CLASS_CLIENT_IMPL['html'] = JmHtmlClient
426+
JmModuleConfig.CLASS_CLIENT_IMPL['api'] = JmApiClient

src/jmcomic/jm_client_interface.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ class JmImageClient:
221221
def download_image(self,
222222
img_url: str,
223223
img_save_path: str,
224-
scramble_id: str,
224+
scramble_id=None,
225225
decode_image=True,
226226
):
227227
"""
@@ -231,6 +231,10 @@ def download_image(self,
231231
@param scramble_id: 图片所在photo的scramble_id
232232
@param decode_image: 要保存的是解密后的图还是原图
233233
"""
234+
if scramble_id is None:
235+
# 大多数情况下,scramble_id = photo_id
236+
scramble_id = JmcomicText.parse_to_photo_id(scramble_id)
237+
234238
# 请求图片
235239
resp = self.get_jm_image(img_url)
236240

src/jmcomic/jm_config.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class JmModuleConfig:
5656
CLASS_OPTION = None
5757
CLASS_ALBUM = None
5858
CLASS_PHOTO = None
59+
CLASS_CLIENT_IMPL = {}
5960

6061
# 执行debug的函数
6162
debug_executor = default_jm_debug
@@ -96,6 +97,16 @@ def photo_class(cls):
9697
from .jm_entity import JmPhotoDetail
9798
return JmPhotoDetail
9899

100+
@classmethod
101+
def client_impl_class(cls, client_key: str):
102+
client_impl_dict = cls.CLASS_CLIENT_IMPL
103+
104+
impl_class = client_impl_dict.get(client_key, None)
105+
if impl_class is None:
106+
raise NotImplementedError(f'not found client impl class for key: "{client_key}"')
107+
108+
return impl_class
109+
99110
@classmethod
100111
@field_cache("DOMAIN")
101112
def domain(cls, postman=None):

src/jmcomic/jm_entity.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,12 @@ def __init__(self,
318318

319319
# 有的 album 没有章节,则自成一章。
320320
if len(episode_list) == 0:
321-
# photo_id, photo_index_of_album, photo_title, photo_pub_date
322-
episode_list = [(album_id, 0, title, pub_date)]
321+
# photo_id, photo_index, photo_title, photo_pub_date
322+
episode_list = [(album_id, 1, title, pub_date)]
323+
else:
324+
episode_list = self.distinct_episode(episode_list)
323325

324-
self.episode_list: List[Tuple] = self.distinct_episode(episode_list)
326+
self.episode_list: List[Tuple] = episode_list
325327

326328
def create_photo_detail(self, index) -> Tuple[JmPhotoDetail, Tuple]:
327329
# 校验参数
@@ -332,15 +334,15 @@ def create_photo_detail(self, index) -> Tuple[JmPhotoDetail, Tuple]:
332334

333335
# episode_info: ('212214', '81', '94 突然打來', '2020-08-29')
334336
episode_info: tuple = self.episode_list[index]
335-
photo_id, photo_index_of_album, photo_title, photo_pub_date = episode_info
337+
photo_id, photo_index, photo_title, photo_pub_date = episode_info
336338

337339
photo = JmPhotoDetail(
338340
photo_id=photo_id,
339341
scramble_id=self.scramble_id,
340342
title=photo_title,
341343
keywords='',
342344
series_id=self.album_id,
343-
sort=episode_info[1] if len(self) != 1 else 1,
345+
sort=photo_index,
344346
author=self.author,
345347
from_album=self,
346348
page_arr=None,

src/jmcomic/jm_option.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,6 @@ def to_file(self, filepath=None):
222222
下面是 build 方法
223223
"""
224224

225-
# 缓存
226-
jm_client_impl_mapping: Dict[str, Type[AbstractJmClient]] = {
227-
'html': JmHtmlClient,
228-
'api': JmApiClient,
229-
}
230-
231225
@field_cache("__jm_client_cache__")
232226
def build_jm_client(self, **kwargs) -> JmcomicClient:
233227
"""
@@ -255,7 +249,7 @@ def new_jm_client(self, **kwargs) -> JmcomicClient:
255249
domain_list = [JmcomicText.parse_to_jm_domain(JmModuleConfig.get_jmcomic_url(postman))]
256250

257251
# client
258-
client = self.jm_client_impl_mapping[self.client.impl](
252+
client = JmModuleConfig.client_impl_class(self.client.impl)(
259253
postman,
260254
self.client.retry_times,
261255
fallback_domain_list=domain_list,

usage/usage_feature_filter.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""
2+
3+
本文件演示 jmcomic 的filter(过滤器)
4+
利用filter,你可以实现下载时过滤本子/章节/图片,完全控制你要下载的内容。
5+
6+
使用filter的步骤如下:
7+
1. 自定义class,继承JmDownloader,重写filter_iter_objs方法,即:
8+
class MyDownloader(JmDownloader):
9+
def filter_iter_objs(self, iter_objs: DownloadIterObjs):
10+
# 如何重写?参考JmDownloader.filter_iter_objs和下面的示例
11+
...
12+
13+
2. 让你的class生效,使用如下代码:
14+
JmModuleConfig.CLASS_DOWNLOADER = MyDownloader
15+
16+
3. 照常使用下载api:
17+
download_album(xxx, option)
18+
19+
** 本文件下面的示例只演示步骤1 **
20+
21+
本文件包含如下示例:
22+
- 只下载本子的特定章节以后的章节
23+
- 只下载章节的前三张图
24+
25+
26+
"""
27+
28+
from jmcomic import *
29+
30+
31+
# 示例:只下载本子的特定章节以后的章节
32+
# 参考:https://github.com/hect0x7/JMComic-Crawler-Python/issues/95
33+
class FindUpdateDownloader(JmDownloader):
34+
album_after_photo = {
35+
'xxx': 'yyy'
36+
}
37+
38+
def filter_iter_objs(self, iter_objs: DownloadIterObjs):
39+
if not isinstance(iter_objs, JmAlbumDetail):
40+
return iter_objs
41+
42+
return self.find_update(iter_objs)
43+
44+
# 带入漫画id, 章节id(第x章),寻找该漫画下第x章节後的所有章节Id
45+
def find_update(self, album: JmAlbumDetail):
46+
if album.album_id not in self.album_after_photo:
47+
return album
48+
49+
photo_ls = []
50+
photo_begin = self.album_after_photo[album.album_id]
51+
is_new_photo = False
52+
53+
for photo in album:
54+
if is_new_photo:
55+
photo_ls.append(photo)
56+
57+
if photo.photo_id == photo_begin:
58+
is_new_photo = True
59+
60+
return photo_ls
61+
62+
63+
# 示例:只下载章节的前三张图
64+
class First3ImageDownloader(JmDownloader):
65+
66+
def filter_iter_objs(self, iter_objs: DownloadIterObjs):
67+
if isinstance(iter_objs, JmPhotoDetail):
68+
photo: JmPhotoDetail = iter_objs
69+
# 支持[start,end,step]
70+
return photo[:3]
71+
72+
return iter_objs

usage/sample_usage.py renamed to usage/usage_simple.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
"""
2+
3+
本文件仅演示一些简单的api使用,包含以下内容:
4+
1. 下载本子
5+
2. 获取实体类(本子/章节/图片)
6+
3. 搜索本子
7+
4. 搜索并下载本子(以下载带有 [無修正] 标签的本子为例)
8+
9+
"""
10+
111
from jmcomic import *
212

313
option = create_option(
@@ -6,7 +16,7 @@
616
client = option.build_jm_client()
717

818

9-
@timeit('下载本子集: ')
19+
@timeit('下载本子: ')
1020
def download_jm_album():
1121
ls = str_to_list('''
1222
438696
@@ -54,6 +64,7 @@ def search_jm_album():
5464
@timeit('搜索并下载本子: ')
5565
def search_and_download():
5666
tag = '無修正'
67+
# 搜索第一页
5768
search_page: JmSearchPage = client.search_album(tag, main_tag=3)
5869

5970
id_list = []

0 commit comments

Comments
 (0)