Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion assets/docs/sources/option_file_syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 / 章节序号 / 图片文件
Expand All @@ -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插件配置项
Expand Down
2 changes: 1 addition & 1 deletion src/jmcomic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down
5 changes: 4 additions & 1 deletion src/jmcomic/jm_client_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
# 解密图片并保存文件
Expand Down
2 changes: 1 addition & 1 deletion src/jmcomic/jm_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
26 changes: 26 additions & 0 deletions src/jmcomic/jm_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.items():
k = prefix + name
result[k] = func(self)

return result


class JmImageDetail(JmBaseEntity, Downloadable):

Expand Down
18 changes: 13 additions & 5 deletions src/jmcomic/jm_option.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions tests/test_jmcomic/test_jm_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,21 @@

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')

Check failure on line 91 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.9, ubuntu-latest)

test_partial_exception

Check failure on line 91 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.9, ubuntu-latest)

test_partial_exception

Check failure on line 91 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.10, ubuntu-latest)

test_partial_exception

Check failure on line 91 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.10, ubuntu-latest)

test_partial_exception

Check failure on line 91 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.11, ubuntu-latest)

test_partial_exception

Check failure on line 91 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.11, ubuntu-latest)

test_partial_exception

Check failure on line 91 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.13, ubuntu-latest)

test_partial_exception

Check failure on line 91 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.13, ubuntu-latest)

test_partial_exception

Check failure on line 91 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.13, ubuntu-latest)

test_partial_exception

Check failure on line 91 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.13, ubuntu-latest)

test_partial_exception

@catch_exception
def download_by_photo_detail(self, photo: JmPhotoDetail):
if photo.index != 2:
raise Exception('test_partial_exception')

Check failure on line 96 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.9, ubuntu-latest)

test_partial_exception

Check failure on line 96 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.10, ubuntu-latest)

test_partial_exception

Check failure on line 96 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.11, ubuntu-latest)

test_partial_exception

Check failure on line 96 in tests/test_jmcomic/test_jm_api.py

View workflow job for this annotation

GitHub Actions / test (3.13, ubuntu-latest)

test_partial_exception
return super().download_by_photo_detail(photo)

self.assertRaises(
Expand Down
Loading