Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf2adb33

Browse files
authored
v2.6.9: 增加下载本子封面图的函数以及download_cover插件; 修复client.after_init时advance_retry插件没有生效的问题(#472) (#482)
1 parent7943b9b commitf2adb33

File tree

10 files changed

+100
-19
lines changed

10 files changed

+100
-19
lines changed

‎assets/docs/sources/option_file_syntax.md‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@ dir_rule:
109109
# 规则: 根目录 / 本子id / 章节序号 / 图片文件
110110
# rule: 'Bd / Aid / Pindex'
111111
# rule: 'Bd_Aid_Pindex'
112-
113112
# 默认规则是: 根目录 / 章节标题 / 图片文件
114-
rule:Bd_Ptitle
113+
rule:Bd / Ptitle
115114
# jmcomic v2.5.36 以后,支持使用python的f-string的语法组合文件夹名,下为示例
116115
# rule: Bd / Aauthor / (JM{Aid}-{Pindex})-{Pname}
117116
# {}大括号里的内容同样是写 Axxx 或 Pxxx,其他语法自行参考python f-string的语法
117+
# 另外,rule开头的Bd可忽略不写,因为程序会自动插入Bd
118118
```
119119

120120
##3. option插件配置项
@@ -194,6 +194,15 @@ plugins:
194194
album_photo_dict:
195195
324930:424507
196196

197+
before_album:
198+
-plugin:download_cover# 额外下载本子封面的插件
199+
kwargs:
200+
size:'_3x4'# 可选项,禁漫搜索页的封面图尺寸是 4x3,和详情页不一样,想下搜索页的封面就设置此项
201+
dir_rule:# 封面图存放路径规则,写法同上
202+
base_dir:D:/a/b/c/
203+
rule:'{Atitle}/{Aid}_cover.jpg'
204+
205+
197206
after_album:
198207
-plugin:zip# 压缩文件插件
199208
kwargs:

‎assets/docs/sources/tutorial/0_common_usage.md‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ download_album(123, option)
3838
option.download_album(123)
3939
```
4040

41-
##获取本子/章节/图片的实体类,下载图片
41+
##获取本子/章节/图片的实体类,下载图片/封面图
4242

4343
```python
4444
from jmcomicimport*
@@ -49,23 +49,26 @@ client = JmOption.default().new_jm_client()
4949
# 本子实体类
5050
album: JmAlbumDetail= client.get_album_detail('427413')
5151

52+
# 下载本子封面图,保存为 cover.png (图片后缀可指定为jpg、webp等)
53+
client.download_album_cover('427413','./cover.png')
54+
5255

5356
deffetch(photo: JmPhotoDetail):
5457
# 章节实体类
5558
photo= client.get_photo_detail(photo.photo_id,False)
5659
print(f'章节id:{photo.photo_id}')
57-
60+
5861
# 图片实体类
5962
image: JmImageDetail
6063
for imagein photo:
6164
print(f'图片url:{image.img_url}')
62-
65+
6366
# 下载单个图片
6467
client.download_by_image_detail(image,'./a.jpg')
6568
# 如果是已知未混淆的图片,也可以直接使用url来下载
6669
random_image_domain= JmModuleConfig.DOMAIN_IMAGE_LIST[0]
6770
client.download_image(f'https://{random_image_domain}/media/albums/416130.jpg','./a.jpg')
68-
71+
6972

7073
# 多线程发起请求
7174
multi_thread_launcher(

‎assets/option/option_test_api.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ plugins:
2727
proxy_client_key:photo_concurrent_fetcher_proxy
2828
whitelist:[ api, ]
2929

30-
-plugin:advanced-retry
30+
-plugin:advanced_retry
3131
kwargs:
3232
retry_config:
3333
retry_rounds:3# 一共对域名列表重试3轮

‎src/jmcomic/__init__.py‎

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

5-
__version__='2.6.7'
5+
__version__='2.6.9'
66

77
from .apiimport*
88
from .jm_pluginimport*

‎src/jmcomic/jm_client_impl.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def __init__(self,
1515
postman:Postman,
1616
domain_list:List[str],
1717
retry_times=0,
18+
domain_retry_strategy=None,
1819
):
1920
"""
2021
创建JM客户端
@@ -26,9 +27,11 @@ def __init__(self,
2627
super().__init__(postman)
2728
self.retry_times=retry_times
2829
self.domain_list=domain_list
29-
self.domain_retry_strategy=None
30+
self.domain_retry_strategy=domain_retry_strategy
3031
self.CLIENT_CACHE=None
3132
self._username=None# help for favorite_folder method
33+
ifdomain_retry_strategy:
34+
domain_retry_strategy(self)
3235
self.enable_cache()
3336
self.after_init()
3437

‎src/jmcomic/jm_client_interface.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,14 @@ def img_is_not_need_to_decode(cls, data_original: str, _resp) -> bool:
293293
# https://cdn-msp2.18comic.vip/media/photos/498976/00027.gif
294294
returndata_original.endswith('.gif')
295295

296+
defdownload_album_cover(self,album_id,save_path:str,size:str=''):
297+
self.download_image(
298+
img_url=JmcomicText.get_album_cover_url(album_id,size=size),
299+
img_save_path=save_path,
300+
scramble_id=None,
301+
decode_image=False,
302+
)
303+
296304

297305
classJmSearchAlbumClient:
298306
"""

‎src/jmcomic/jm_option.py‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ def get_rule_parser(cls, rule: str):
158158
ifrule.startswith(('A','P')):
159159
returncls.parse_detail_rule
160160

161-
ExceptionTool.raises(f'不支持的rule配置: "{rule}"')
161+
returncls.parse_f_string_rule
162+
# ExceptionTool.raises(f'不支持的rule配置: "{rule}"')
162163

163164
@classmethod
164165
defapply_rule_to_filename(cls,album,photo,rule:str)->str:
@@ -362,7 +363,13 @@ def build_jm_client(self, **kwargs):
362363
"""
363364
returnself.new_jm_client(**kwargs)
364365

365-
defnew_jm_client(self,domain_list=None,impl=None,cache=None,**kwargs)->Union[JmHtmlClient,JmApiClient]:
366+
defnew_jm_client(self,
367+
domain_list=None,
368+
impl=None,
369+
cache=None,
370+
domain_retry_strategy=None,
371+
**kwargs
372+
)->Union[JmHtmlClient,JmApiClient]:
366373
"""
367374
创建新的Client(客户端),不同Client之间的元数据不共享
368375
"""
@@ -423,6 +430,7 @@ def decide_domain_list():
423430
postman=postman,
424431
domain_list=decide_domain_list(),
425432
retry_times=retry_times,
433+
domain_retry_strategy=domain_retry_strategy,
426434
)
427435

428436
# enable cache

‎src/jmcomic/jm_plugin.py‎

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def wait_until_finish(self):
111111
defdecide_filepath(self,
112112
album:Optional[JmAlbumDetail],
113113
photo:Optional[JmPhotoDetail],
114-
filename_rule:str,suffix:str,base_dir:Optional[str],
114+
filename_rule:Optional[str],suffix:Optional[str],base_dir:Optional[str],
115115
dir_rule_dict:Optional[dict]
116116
):
117117
"""
@@ -1219,7 +1219,7 @@ def new_decide_dir(photo, ensure_exists=True) -> str:
12191219

12201220

12211221
classAdvancedRetryPlugin(JmOptionPlugin):
1222-
plugin_key='advanced-retry'
1222+
plugin_key='advanced_retry'
12231223

12241224
def__init__(self,option:JmOption):
12251225
super().__init__(option)
@@ -1234,15 +1234,18 @@ def invoke(self,
12341234
new_jm_client:Callable=self.option.new_jm_client
12351235

12361236
defhook_new_jm_client(*args,**kwargs):
1237-
client:JmcomicClient=new_jm_client(*args,**kwargs)
1238-
client.domain_retry_strategy=self.request_with_retry
1239-
client.domain_req_failed_counter= {}
1240-
fromthreadingimportLock
1241-
client.domain_counter_lock=Lock()
1242-
returnclient
1237+
returnnew_jm_client(*args,**kwargs,domain_retry_strategy=self)
12431238

12441239
self.option.new_jm_client=hook_new_jm_client
12451240

1241+
def__call__(self,client:AbstractJmClient,*args,**kwargs):
1242+
ifargs:
1243+
returnself.request_with_retry(client,*args,**kwargs)
1244+
# init
1245+
fromthreadingimportLock
1246+
client.domain_req_failed_counter= {}
1247+
client.domain_counter_lock=Lock()
1248+
12461249
defrequest_with_retry(self,
12471250
client:AbstractJmClient,
12481251
request:Callable,
@@ -1306,3 +1309,25 @@ def update_failed_count(self, client: AbstractJmClient, domain: str):
13061309
deffailed_count(client:JmcomicClient,domain:str)->int:
13071310
# noinspection PyUnresolvedReferences
13081311
returnclient.domain_req_failed_counter.get(domain,0)
1312+
1313+
1314+
classDownloadCoverPlugin(JmOptionPlugin):
1315+
plugin_key='download_cover'
1316+
1317+
definvoke(self,
1318+
dir_rule:dict,
1319+
size='',
1320+
photo:JmPhotoDetail=None,
1321+
album:JmAlbumDetail=None,
1322+
downloader=None,
1323+
**kwargs)->None:
1324+
album_id=album.idifalbumelsephoto.album_id
1325+
save_path=self.decide_filepath(
1326+
album,photo,
1327+
None,None,None,
1328+
dir_rule
1329+
)
1330+
ifself.option.download.cacheandos.path.exists(save_path):
1331+
self.log(f'album-{album_id}的封面已存在,跳过下载: [{save_path}]','skip')
1332+
return
1333+
downloader.client.download_album_cover(album_id,save_path,size)

‎src/jmcomic/jm_toolkit.py‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,26 @@ def limit_text(cls, text: str, limit: int) -> str:
368368
length=len(text)
369369
returntextiflength<=limitelse (text[:limit]+f'...({length-limit}')
370370

371+
@classmethod
372+
defget_album_cover_url(cls,
373+
album_id:Union[str,int],
374+
image_domain:Optional[str]=None,
375+
size:str='',
376+
)->str:
377+
"""
378+
根据本子id生成封面url
379+
380+
:param album_id: 本子id
381+
:param image_domain: 图片cdn域名(可传入裸域或含协议的域名)
382+
:param size: 尺寸后缀,例如搜索列表页会使用 size="_3x4" 的封面图
383+
"""
384+
ifimage_domainisNone:
385+
importrandom
386+
image_domain=random.choice(JmModuleConfig.DOMAIN_IMAGE_LIST)
387+
388+
path=f'/media/albums/{cls.parse_to_jm_id(album_id)}{size}.jpg'
389+
returncls.format_url(path,image_domain)
390+
371391

372392
# 支持dsl: #{???} -> os.getenv(???)
373393
JmcomicText.dsl_replacer.add_dsl_and_replacer(r'\$\{(.*?)\}',JmcomicText.match_os_env)

‎tests/test_jmcomic/test_jm_client.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,8 @@ def print_page(page):
332332
# 打印page内容
333333
foraid,atitleinpage:
334334
print(aid,atitle)
335+
336+
deftest_download_cover(self):
337+
album_id=123
338+
self.client.download_album_cover(album_id,f'{self.option.dir_rule.base_dir}/{album_id}.webp')
339+
self.client.download_album_cover(album_id,f'{self.option.dir_rule.base_dir}/{album_id}_3x4.webp','_3x4')

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp