mirror of
https://github.com/hect0x7/JMComic-Crawler-Python.git
synced 2025-09-26 22:31:30 +08:00
v2.5.36: 修复保存gif图的bug,dir_rule配置支持python f-string语法 (#415) (#420)
Some checks failed
Auto Release & Publish / release (push) Has been cancelled
Some checks failed
Auto Release & Publish / release (push) Has been cancelled
This commit is contained in:
parent
ebf0ea602d
commit
398e1ea42e
@ -96,7 +96,14 @@ dir_rule:
|
|||||||
# 写法:
|
# 写法:
|
||||||
# 1. 以'Bd'开头,表示根目录
|
# 1. 以'Bd'开头,表示根目录
|
||||||
# 2. 文件夹每增加一层,使用 '_' 或者 '/' 区隔
|
# 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 / 章节序号 / 图片文件
|
# 规则: 根目录 / 本子id / 章节序号 / 图片文件
|
||||||
@ -105,6 +112,9 @@ dir_rule:
|
|||||||
|
|
||||||
# 默认规则是: 根目录 / 章节标题 / 图片文件
|
# 默认规则是: 根目录 / 章节标题 / 图片文件
|
||||||
rule: Bd_Ptitle
|
rule: Bd_Ptitle
|
||||||
|
# jmcomic v2.5.36 以后,支持使用python的f-string的语法组合文件夹名,下为示例
|
||||||
|
# rule: Bd / Aauthor / (JM{Aid}-{Pindex})-{Pname}
|
||||||
|
# {}大括号里的内容同样是写 Axxx 或 Pxxx,其他语法自行参考python f-string的语法
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. option插件配置项
|
## 3. option插件配置项
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# 被依赖方 <--- 使用方
|
# 被依赖方 <--- 使用方
|
||||||
# config <--- entity <--- toolkit <--- client <--- option <--- downloader
|
# config <--- entity <--- toolkit <--- client <--- option <--- downloader
|
||||||
|
|
||||||
__version__ = '2.5.35'
|
__version__ = '2.5.36'
|
||||||
|
|
||||||
from .api import *
|
from .api import *
|
||||||
from .jm_plugin import *
|
from .jm_plugin import *
|
||||||
|
@ -62,13 +62,16 @@ class JmImageResp(JmResp):
|
|||||||
img_url=None,
|
img_url=None,
|
||||||
):
|
):
|
||||||
img_url = img_url or self.url
|
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:
|
if decode_image is False or scramble_id is None:
|
||||||
# 不解密图片,直接保存文件
|
# 不解密图片,直接保存文件
|
||||||
JmImageTool.save_resp_img(
|
JmImageTool.save_resp_img(
|
||||||
self,
|
self,
|
||||||
path,
|
path,
|
||||||
need_convert=suffix_not_equal(img_url[:img_url.find("?")], path),
|
need_convert=suffix_not_equal(img_url, path),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# 解密图片并保存文件
|
# 解密图片并保存文件
|
||||||
|
@ -414,7 +414,7 @@ class JmModuleConfig:
|
|||||||
'cache': None, # see CacheRegistry
|
'cache': None, # see CacheRegistry
|
||||||
'domain': [],
|
'domain': [],
|
||||||
'postman': {
|
'postman': {
|
||||||
'type': 'cffi',
|
'type': 'curl_cffi',
|
||||||
'meta_data': {
|
'meta_data': {
|
||||||
'impersonate': 'chrome110',
|
'impersonate': 'chrome110',
|
||||||
'headers': None,
|
'headers': None,
|
||||||
|
@ -164,6 +164,32 @@ class DetailEntity(JmBaseEntity, IndexedEntity):
|
|||||||
|
|
||||||
return getattr(detail, ref)
|
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):
|
class JmImageDetail(JmBaseEntity, Downloadable):
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ class DirRule:
|
|||||||
]
|
]
|
||||||
|
|
||||||
Detail = Union[JmAlbumDetail, JmPhotoDetail, None]
|
Detail = Union[JmAlbumDetail, JmPhotoDetail, None]
|
||||||
RuleFunc = Callable[[Detail], str]
|
RuleFunc = Callable
|
||||||
RuleSolver = Tuple[str, RuleFunc, str]
|
RuleSolver = Tuple[str, RuleFunc, str]
|
||||||
RuleSolverList = List[RuleSolver]
|
RuleSolverList = List[RuleSolver]
|
||||||
|
|
||||||
@ -154,6 +154,12 @@ class DirRule:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_rule_solver(cls, rule: str) -> Optional[RuleSolver]:
|
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
|
# 检查dsl
|
||||||
if not rule.startswith(('A', 'P')):
|
if not rule.startswith(('A', 'P')):
|
||||||
return None
|
return None
|
||||||
@ -176,15 +182,17 @@ class DirRule:
|
|||||||
|
|
||||||
def choose_detail(key):
|
def choose_detail(key):
|
||||||
if key == 'Bd':
|
if key == 'Bd':
|
||||||
return None
|
return None,
|
||||||
if key == 'A':
|
if key == 'A':
|
||||||
return album
|
return album,
|
||||||
if key == 'P':
|
if key == 'P':
|
||||||
return photo
|
return photo,
|
||||||
|
if key == 'F':
|
||||||
|
return album, photo
|
||||||
|
|
||||||
key, func, _ = rule_solver
|
key, func, _ = rule_solver
|
||||||
detail = choose_detail(key)
|
detail = choose_detail(key)
|
||||||
return func(detail)
|
return func(*detail)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def apply_rule_directly(cls, album, photo, rule: str) -> str:
|
def apply_rule_directly(cls, album, photo, rule: str) -> str:
|
||||||
|
@ -79,6 +79,13 @@ class Test_Api(JmTestConfigurable):
|
|||||||
|
|
||||||
def test_partial_exception(self):
|
def test_partial_exception(self):
|
||||||
class TestDownloader(JmDownloader):
|
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
|
@catch_exception
|
||||||
def download_by_image_detail(self, image: JmImageDetail):
|
def download_by_image_detail(self, image: JmImageDetail):
|
||||||
raise Exception('test_partial_exception')
|
raise Exception('test_partial_exception')
|
||||||
|
Loading…
Reference in New Issue
Block a user