Skip to content

Commit 7d8fb35

Browse files
authored
v2.4.14: 更新禁漫APP端搜索接口,修复导出收藏夹插件的一些问题,优化代码。 (#189)
1 parent 06237f8 commit 7d8fb35

File tree

9 files changed

+47
-42
lines changed

9 files changed

+47
-42
lines changed

.github/workflows/export_favorites.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ jobs:
7373
- name: 上传结果
7474
uses: actions/upload-artifact@v3
7575
with:
76-
name: '收藏夹导出zip'
76+
name: '导出的收藏夹'
7777
path: ${{ env.ZIP_FP }}
7878
if-no-files-found: error
7979
retention-days: 90

assets/option/option_workflow_export_favorites.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ plugins:
2424
msg_to: ${EMAIL_TO}
2525
password: ${EMAIL_PASS}
2626
title: ${EMAIL_TITLE}
27-
content: ${EMAIL_CONTENT}
27+
content: ${EMAIL_CONTENT}

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.4.13'
5+
__version__ = '2.4.14'
66

77
from .api import *
88
from .jm_plugin import *

src/jmcomic/jm_config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ def new_postman(cls, session=False, **kwargs):
318318
# 一般情况下,建议使用option配置文件来定制配置
319319
# 而如果只想修改几个简单常用的配置,也可以下方的DEFAULT_XXX属性
320320
JM_OPTION_VER = '2.1'
321-
DEFAULT_CLIENT_IMPL = 'html' # 默认Client实现类型为网页端
321+
DEFAULT_CLIENT_IMPL = 'api' # 默认Client实现类型为网页端
322322
DEFAULT_CLIENT_CACHE = True # 默认开启Client缓存,缓存级别是level_option,详见CacheRegistry
323323
DEFAULT_PROXIES = ProxyBuilder.system_proxy() # 默认使用系统代理
324324

@@ -345,7 +345,7 @@ def new_postman(cls, session=False, **kwargs):
345345
}
346346
},
347347
'impl': None,
348-
'retry_times': 5
348+
'retry_times': 5,
349349
},
350350
'plugins': {
351351
# 如果插件抛出参数校验异常,只log。(全局配置,可以被插件的局部配置覆盖)

src/jmcomic/jm_entity.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ def __init__(self, content: List[ContentItem], total: int):
524524
"""
525525
content:
526526
[
527-
album_id, {title, tag_list, ...}
527+
album_id, {title, tags, ...}
528528
]
529529
:param content: 分页数据
530530
:param total: 总结果数
@@ -564,11 +564,11 @@ def iter_id_title(self) -> Generator[Tuple[str, str], None, None]:
564564

565565
def iter_id_title_tag(self) -> Generator[Tuple[str, str, List[str]], None, None]:
566566
"""
567-
返回 album_id, album_title, album_tag_list 的迭代器
567+
返回 album_id, album_title, album_tags 的迭代器
568568
"""
569569
for aid, ainfo in self.content:
570-
ainfo.setdefault('tag_list', [])
571-
yield aid, ainfo['name'], ainfo['tag_list']
570+
ainfo.setdefault('tags', [])
571+
yield aid, ainfo['name'], ainfo['tags']
572572

573573
# 下面的方法实现方便的元素访问
574574

@@ -610,7 +610,7 @@ def wrap_single_album(cls, album: JmAlbumDetail) -> 'JmSearchPage':
610610
page = JmSearchPage([(
611611
album.album_id, {
612612
'name': album.name,
613-
'tag_list': album.tags,
613+
'tags': album.tags,
614614
}
615615
)], 1)
616616
setattr(page, 'album', album)

src/jmcomic/jm_plugin.py

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,17 @@ def log(self, msg, topic=None):
4444
msg=msg
4545
)
4646

47-
def require_true(self, case: Any, msg: str, is_param_validation=True):
47+
def require_param(self, case: Any, msg: str):
4848
"""
49-
独立于ExceptionTool的一套异常抛出体系
50-
49+
专门用于校验参数的方法,会抛出特定异常,由option拦截根据策略进行处理
5150
5251
:param case: 条件
5352
:param msg: 报错信息
54-
:param is_param_validation: True 表示 调用本方法是用于校验参数,则会抛出特定异常(PluginValidationException)
5553
"""
5654
if case:
5755
return
5856

59-
if is_param_validation:
60-
raise PluginValidationException(self, msg)
61-
else:
62-
ExceptionTool.raises(msg)
57+
raise PluginValidationException(self, msg)
6358

6459
def warning_lib_not_install(self, lib: str):
6560
msg = (f'插件`{self.plugin_key}`依赖库: {lib},请先安装{lib}再使用。'
@@ -94,6 +89,11 @@ def execute_cmd(self, cmd):
9489
"""
9590
return os.system(cmd)
9691

92+
# noinspection PyMethodMayBeStatic
93+
def execute_multi_line_cmd(self, cmd: str):
94+
import subprocess
95+
subprocess.run(cmd, shell=True, check=True)
96+
9797

9898
class JmLoginPlugin(JmOptionPlugin):
9999
"""
@@ -106,10 +106,10 @@ def invoke(self,
106106
password: str,
107107
impl=None,
108108
) -> None:
109-
self.require_true(username, '用户名不能为空')
110-
self.require_true(password, '密码不能为空')
109+
self.require_param(username, '用户名不能为空')
110+
self.require_param(password, '密码不能为空')
111111

112-
client = self.option.new_jm_client(impl=impl)
112+
client = self.option.build_jm_client(impl=impl)
113113
client.login(username, password)
114114

115115
cookies = dict(client['cookies'])
@@ -459,7 +459,7 @@ def invoke(self,
459459
album=None,
460460
downloader=None,
461461
) -> None:
462-
self.require_true(msg_from and msg_to and password, '发件人、收件人、授权码都不能为空')
462+
self.require_param(msg_from and msg_to and password, '发件人、收件人、授权码都不能为空')
463463

464464
from common import EmailConfig
465465
econfig = EmailConfig(msg_from, msg_to, password)
@@ -551,7 +551,7 @@ def invoke(self,
551551
zip_password=None,
552552
delete_original_file=False,
553553
):
554-
self.save_dir = os.path.abspath(save_dir if save_dir is not None else os.getcwd() + '/export/')
554+
self.save_dir = os.path.abspath(save_dir if save_dir is not None else (os.getcwd() + '/export/'))
555555
self.zip_enable = zip_enable
556556
self.zip_filepath = os.path.abspath(zip_filepath)
557557
self.zip_password = zip_password
@@ -564,7 +564,7 @@ def invoke(self,
564564
self.main()
565565

566566
def main(self):
567-
cl = self.option.new_jm_client(impl=JmApiClient)
567+
cl = self.option.build_jm_client()
568568
# noinspection PyAttributeOutsideInit
569569
self.cl = cl
570570
page = cl.favorite_folder()
@@ -584,7 +584,7 @@ def main(self):
584584
return
585585

586586
# 压缩导出的文件
587-
self.require_true(self.zip_filepath, '如果开启zip,请指定zip_filepath参数(压缩文件保存路径)')
587+
self.require_param(self.zip_filepath, '如果开启zip,请指定zip_filepath参数(压缩文件保存路径)')
588588

589589
if self.zip_password is None:
590590
self.zip_folder_without_password(self.files, self.zip_filepath)
@@ -650,12 +650,16 @@ def zip_folder_without_password(self, files, zip_path):
650650
zipf.write(file, arcname=of_file_name(file))
651651

652652
def zip_with_password(self):
653-
os.chdir(self.save_dir)
654-
cmd = f'7z a "{self.zip_filepath}" "{self.save_dir}" -p{self.zip_password} -mhe=on'
655-
self.require_true(
656-
0 == self.execute_cmd(cmd),
657-
'加密压缩文件失败'
658-
)
653+
# 构造shell命令
654+
cmd_list = f'''
655+
cd {self.save_dir}
656+
7z a "{self.zip_filepath}" "./" -p{self.zip_password} -mhe=on > "../7z_output.txt"
657+
658+
'''
659+
self.log(f'运行命令: {cmd_list}')
660+
661+
# 执行
662+
self.execute_multi_line_cmd(cmd_list)
659663

660664

661665
class ConvertJpgToPdfPlugin(JmOptionPlugin):
@@ -726,11 +730,10 @@ def generate_cmd():
726730
self.log(f'Execute Command: [{cmd}]')
727731
code = self.execute_cmd(cmd)
728732

729-
self.require_true(
733+
ExceptionTool.require_true(
730734
code == 0,
731735
'jpg图片合并为pdf失败!'
732736
'请确认你是否安装了magick,安装网站: [http://www.imagemagick.org/]',
733-
False,
734737
)
735738

736739
self.log(f'Convert Successfully: JM{photo.id}{pdf_filepath}')

src/jmcomic/jm_toolkit.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ class JmPageTool:
371371
)
372372

373373
# 用来查找tag列表
374-
pattern_html_search_tag_list = compile(r'<a[^>]*?>(.*?)</a>')
374+
pattern_html_search_tags = compile(r'<a[^>]*?>(.*?)</a>')
375375

376376
# 查找错误,例如 [错误,關鍵字過短,請至少輸入兩個字以上。]
377377
pattern_html_search_error = compile(r'<fieldset>\n<legend>(.*?)</legend>\n<div class=.*?>\n(.*?)\n</div>\n</fieldset>')
@@ -418,11 +418,11 @@ def parse_html_to_search_page(cls, html: str) -> JmSearchPage:
418418
album_info_list = cls.pattern_html_search_album_info_list.findall(html)
419419

420420
for (album_id, title, _, label_category, label_sub, tag_text) in album_info_list:
421-
tag_list = cls.pattern_html_search_tag_list.findall(tag_text)
421+
tags = cls.pattern_html_search_tags.findall(tag_text)
422422
content.append((
423423
album_id, {
424424
'name': title, # 改成name是为了兼容 parse_api_resp_to_page
425-
'tag_list': tag_list
425+
'tags': tags
426426
}
427427
))
428428

@@ -436,11 +436,11 @@ def parse_html_to_category_page(cls, html: str) -> JmSearchPage:
436436
album_info_list = cls.pattern_html_category_album_info_list.findall(html)
437437

438438
for (album_id, title, tag_text) in album_info_list:
439-
tag_list = cls.pattern_html_search_tag_list.findall(tag_text)
439+
tags = cls.pattern_html_search_tags.findall(tag_text)
440440
content.append((
441441
album_id, {
442442
'name': title, # 改成name是为了兼容 parse_api_resp_to_page
443-
'tag_list': tag_list
443+
'tags': tags
444444
}
445445
))
446446

@@ -494,7 +494,7 @@ def parse_api_to_search_page(cls, data: DictModel) -> JmSearchPage:
494494
]
495495
}
496496
"""
497-
total: int = int(data.total)
497+
total: int = int(data.total or 0) # 2024.1.5 data.total可能为None
498498
content = cls.adapt_content(data.content)
499499
return JmSearchPage(content, total)
500500

@@ -546,7 +546,7 @@ def parse_api_to_favorite_page(cls, data: DictModel) -> JmFavoritePage:
546546
def adapt_content(cls, content):
547547
def adapt_item(item: DictModel):
548548
item: dict = item.src_dict
549-
item.setdefault('tag_list', [])
549+
item.setdefault('tags', [])
550550
return item
551551

552552
content = [

tests/test_jmcomic/test_jm_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ def test_search(self):
2222
for aid, ainfo in page[0:1:1]:
2323
print(aid, ainfo)
2424

25-
for aid, atitle, tag_list in page.iter_id_title_tag():
26-
print(aid, atitle, tag_list)
25+
for aid, atitle, tags in page.iter_id_title_tag():
26+
print(aid, atitle, tags)
2727

2828
aid = '438516'
2929
page = self.client.search_site(aid)

usage/workflow_export_favorites.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ def env(match: Match) -> str:
3232

3333
def main():
3434
prepare_actions_input_and_secrets()
35+
# 关闭logging,保证安全
36+
disable_jm_log()
3537
option = create_option('../assets/option/option_workflow_export_favorites.yml')
3638
option.call_all_plugin('main', safe=False)
3739

0 commit comments

Comments
 (0)