From 5cd01043449c5c13612b28db5470646914969fb6 Mon Sep 17 00:00:00 2001 From: hect0x7 <93357912+hect0x7@users.noreply.github.com> Date: Wed, 16 Apr 2025 16:45:35 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=94=AF=E6=8C=81dir=5Frule=E4=BD=BF?= =?UTF-8?q?=E7=94=A8python=E6=A0=BC=E5=BC=8F=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?=E8=AF=AD=E6=B3=95=20(#415)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/jmcomic/jm_config.py | 2 +- src/jmcomic/jm_entity.py | 26 ++++++++++++++++++++++++++ src/jmcomic/jm_option.py | 18 +++++++++++++----- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/jmcomic/jm_config.py b/src/jmcomic/jm_config.py index b920a18ee..44cd46465 100644 --- a/src/jmcomic/jm_config.py +++ b/src/jmcomic/jm_config.py @@ -414,7 +414,7 @@ def new_postman(cls, session=False, **kwargs): 'cache': None, # see CacheRegistry 'domain': [], 'postman': { - 'type': 'cffi', + 'type': 'curl_cffi', 'meta_data': { 'impersonate': 'chrome110', 'headers': None, diff --git a/src/jmcomic/jm_entity.py b/src/jmcomic/jm_entity.py index 4d799b841..0549cfd31 100644 --- a/src/jmcomic/jm_entity.py +++ b/src/jmcomic/jm_entity.py @@ -164,6 +164,32 @@ def get_dirname(cls, detail: 'DetailEntity', ref: str) -> str: return getattr(detail, ref) + def get_properties_dict(self): + import inspect + + prefix = self.__class__.__name__[2] + result = {} + + # field + for k, v in self.__dict__.items(): + result[prefix + k] = v + + # property + for cls in inspect.getmro(type(self)): + for name, attr in cls.__dict__.items(): + k = prefix + name + if k not in result and isinstance(attr, property): + v = attr.__get__(self, cls) + result[k] = v + + # advice + advice_dict = JmModuleConfig.AFIELD_ADVICE if self.is_album() else JmModuleConfig.PFIELD_ADVICE + for name, func in advice_dict: + k = prefix + name + result[k] = func(self) + + return result + class JmImageDetail(JmBaseEntity, Downloadable): diff --git a/src/jmcomic/jm_option.py b/src/jmcomic/jm_option.py index 79168c30c..6c497c1b4 100644 --- a/src/jmcomic/jm_option.py +++ b/src/jmcomic/jm_option.py @@ -71,7 +71,7 @@ class DirRule: ] Detail = Union[JmAlbumDetail, JmPhotoDetail, None] - RuleFunc = Callable[[Detail], str] + RuleFunc = Callable RuleSolver = Tuple[str, RuleFunc, str] RuleSolverList = List[RuleSolver] @@ -154,6 +154,12 @@ def split_rule_dsl(self, rule_dsl: str) -> List[str]: @classmethod def get_rule_solver(cls, rule: str) -> Optional[RuleSolver]: + if '{' in rule: + def format_path(album, photo): + return fix_windir_name(rule.format(**album.get_properties_dict(), **photo.get_properties_dict())).strip() + + return 'F', format_path, rule + # 检查dsl if not rule.startswith(('A', 'P')): return None @@ -176,15 +182,17 @@ def apply_rule_solver(cls, album, photo, rule_solver: RuleSolver) -> str: def choose_detail(key): if key == 'Bd': - return None + return None, if key == 'A': - return album + return album, if key == 'P': - return photo + return photo, + if key == 'F': + return album, photo key, func, _ = rule_solver detail = choose_detail(key) - return func(detail) + return func(*detail) @classmethod def apply_rule_directly(cls, album, photo, rule: str) -> str: From 521b5006e1ee1d8781029da310c0fd39cf9decf7 Mon Sep 17 00:00:00 2001 From: hect0x7 <93357912+hect0x7@users.noreply.github.com> Date: Wed, 16 Apr 2025 17:25:39 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=94=AF=E6=8C=81dir=5Frule=E4=BD=BF?= =?UTF-8?q?=E7=94=A8f-string=E8=AF=AD=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/jmcomic/jm_entity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jmcomic/jm_entity.py b/src/jmcomic/jm_entity.py index 0549cfd31..ed1d0fb15 100644 --- a/src/jmcomic/jm_entity.py +++ b/src/jmcomic/jm_entity.py @@ -184,7 +184,7 @@ def get_properties_dict(self): # advice advice_dict = JmModuleConfig.AFIELD_ADVICE if self.is_album() else JmModuleConfig.PFIELD_ADVICE - for name, func in advice_dict: + for name, func in advice_dict.items(): k = prefix + name result[k] = func(self) From 89419f8d5f7efd8347e8cc4246383d253c1c88ba Mon Sep 17 00:00:00 2001 From: hect0x7 <93357912+hect0x7@users.noreply.github.com> Date: Wed, 16 Apr 2025 22:41:55 +0800 Subject: [PATCH 3/3] =?UTF-8?q?v2.5.36:=20=E4=BF=AE=E5=A4=8D=E4=BF=9D?= =?UTF-8?q?=E5=AD=98gif=E5=9B=BE=E7=9A=84bug=EF=BC=8Cdir=5Frule=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=94=AF=E6=8C=81python=20f-string=E8=AF=AD=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/docs/sources/option_file_syntax.md | 12 +++++++++++- src/jmcomic/__init__.py | 2 +- src/jmcomic/jm_client_interface.py | 5 ++++- tests/test_jmcomic/test_jm_api.py | 7 +++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/assets/docs/sources/option_file_syntax.md b/assets/docs/sources/option_file_syntax.md index 01b3abd08..ea4c9873d 100644 --- a/assets/docs/sources/option_file_syntax.md +++ b/assets/docs/sources/option_file_syntax.md @@ -96,7 +96,14 @@ dir_rule: # 写法: # 1. 以'Bd'开头,表示根目录 # 2. 文件夹每增加一层,使用 '_' 或者 '/' 区隔 - # 3. 用Pxxx或者Ayyy指代文件夹名,意思是 JmPhotoDetail.xxx / JmAlbumDetail的.yyy。xxx和yyy可以写什么需要看源码。 + # 3. 用Pxxx或者Ayyy指代文件夹名,意思是 JmPhotoDetail.xxx / JmAlbumDetail的.yyy。 + # xxx和yyy可以写什么需要看源码,或通过下面代码打印出所有可用的值 + # + # ```python + # import jmcomic + # properties: dict = jmcomic.JmOption.default().new_jm_client().get_album_detail(本子id).get_properties_dict() + # print(properties) + # ``` # # 下面演示如果要使用禁漫网站的默认下载方式,该怎么写: # 规则: 根目录 / 本子id / 章节序号 / 图片文件 @@ -105,6 +112,9 @@ dir_rule: # 默认规则是: 根目录 / 章节标题 / 图片文件 rule: Bd_Ptitle + # jmcomic v2.5.36 以后,支持使用python的f-string的语法组合文件夹名,下为示例 + # rule: Bd / Aauthor / (JM{Aid}-{Pindex})-{Pname} + # {}大括号里的内容同样是写 Axxx 或 Pxxx,其他语法自行参考python f-string的语法 ``` ## 3. option插件配置项 diff --git a/src/jmcomic/__init__.py b/src/jmcomic/__init__.py index df2750cf8..5f99c0b26 100644 --- a/src/jmcomic/__init__.py +++ b/src/jmcomic/__init__.py @@ -2,7 +2,7 @@ # 被依赖方 <--- 使用方 # config <--- entity <--- toolkit <--- client <--- option <--- downloader -__version__ = '2.5.35' +__version__ = '2.5.36' from .api import * from .jm_plugin import * diff --git a/src/jmcomic/jm_client_interface.py b/src/jmcomic/jm_client_interface.py index 5ec98ea3e..f5226948d 100644 --- a/src/jmcomic/jm_client_interface.py +++ b/src/jmcomic/jm_client_interface.py @@ -62,13 +62,16 @@ def transfer_to(self, img_url=None, ): img_url = img_url or self.url + index = img_url.find("?") + if index != -1: + img_url = img_url[0:index] if decode_image is False or scramble_id is None: # 不解密图片,直接保存文件 JmImageTool.save_resp_img( self, path, - need_convert=suffix_not_equal(img_url[:img_url.find("?")], path), + need_convert=suffix_not_equal(img_url, path), ) else: # 解密图片并保存文件 diff --git a/tests/test_jmcomic/test_jm_api.py b/tests/test_jmcomic/test_jm_api.py index ef4011851..c2905e2a4 100644 --- a/tests/test_jmcomic/test_jm_api.py +++ b/tests/test_jmcomic/test_jm_api.py @@ -79,6 +79,13 @@ def run_func_async(func): def test_partial_exception(self): class TestDownloader(JmDownloader): + def do_filter(self, detail: DetailEntity): + if detail.is_photo(): + return detail[0:2] + if detail.is_album(): + return detail[0:2] + return super().do_filter(detail) + @catch_exception def download_by_image_detail(self, image: JmImageDetail): raise Exception('test_partial_exception')