Skip to content

Commit b3a122f

Browse files
committed
dir_rule重构
1 parent 398e1ea commit b3a122f

2 files changed

Lines changed: 51 additions & 77 deletions

File tree

src/jmcomic/jm_option.py

Lines changed: 50 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -58,90 +58,95 @@ def enable_client_cache_on_condition(cls,
5858

5959

6060
class DirRule:
61-
rule_sample = [
62-
# 根目录 / Album-id / Photo-序号 /
63-
'Bd_Aid_Pindex', # 禁漫网站的默认下载方式
64-
# 根目录 / Album-作者 / Album-标题 / Photo-序号 /
65-
'Bd_Aauthor_Atitle_Pindex',
66-
# 根目录 / Photo-序号&标题 /
67-
'Bd_Pindextitle',
68-
# 根目录 / Photo-自定义类属性 /
69-
'Bd_Aauthor_Atitle_Pcustomfield',
70-
# 需要替换JmModuleConfig.CLASS_ALBUM / CLASS_PHOTO才能让自定义属性生效
71-
]
72-
73-
Detail = Union[JmAlbumDetail, JmPhotoDetail, None]
74-
RuleFunc = Callable
75-
RuleSolver = Tuple[str, RuleFunc, str]
76-
RuleSolverList = List[RuleSolver]
61+
RULE_BASE_DIR = 'Bd'
7762

7863
def __init__(self, rule: str, base_dir=None):
7964
base_dir = JmcomicText.parse_to_abspath(base_dir)
8065
self.base_dir = base_dir
8166
self.rule_dsl = rule
82-
self.solver_list = self.get_role_solver_list(rule, base_dir)
67+
self.parser_list: List[Tuple[str, Callable]] = self.get_rule_solver_list(rule)
8368

8469
def decide_image_save_dir(self,
8570
album: JmAlbumDetail,
8671
photo: JmPhotoDetail,
8772
) -> str:
8873
path_ls = []
89-
for solver in self.solver_list:
74+
for rule, parser in self.parser_list:
9075
try:
91-
ret = self.apply_rule_solver(album, photo, solver)
76+
path = parser(album, photo, rule)
9277
except BaseException as e:
9378
# noinspection PyUnboundLocalVariable
94-
jm_log('dir_rule', f'路径规则"{solver[2]}"的解析出错: {e}, album={album}, photo={photo}')
79+
jm_log('dir_rule', f'路径规则"{rule}"的解析出错: {e}, album={album}, photo={photo}')
9580
raise e
81+
if parser != self.parse_bd_rule:
82+
path = fix_windir_name(str(path)).strip()
9683

97-
path_ls.append(str(ret))
84+
path_ls.append(path)
9885

9986
return fix_filepath('/'.join(path_ls), is_dir=True)
10087

10188
def decide_album_root_dir(self, album: JmAlbumDetail) -> str:
10289
path_ls = []
103-
for solver in self.solver_list:
104-
key, _, rule = solver
105-
106-
if key != 'Bd' and key != 'A':
90+
for rule, parser in self.parser_list:
91+
if rule == self.RULE_BASE_DIR or rule.startswith('A'):
10792
continue
10893

10994
try:
110-
ret = self.apply_rule_solver(album, None, solver)
95+
path = parser(album, None, rule)
11196
except BaseException as e:
11297
# noinspection PyUnboundLocalVariable
11398
jm_log('dir_rule', f'路径规则"{rule}"的解析出错: {e}, album={album}')
11499
raise e
100+
if parser != self.parse_bd_rule:
101+
path = fix_windir_name(str(path)).strip()
115102

116-
path_ls.append(str(ret))
103+
path_ls.append(path)
117104

118105
return fix_filepath('/'.join(path_ls), is_dir=True)
119106

120-
def get_role_solver_list(self, rule_dsl: str, base_dir: str) -> RuleSolverList:
107+
def get_rule_solver_list(self, rule_dsl: str):
121108
"""
122109
解析下载路径dsl,得到一个路径规则解析列表
123110
"""
124111

125112
rule_list = self.split_rule_dsl(rule_dsl)
126-
solver_ls: List[DirRule.RuleSolver] = []
113+
parser_list: list = []
127114

128115
for rule in rule_list:
129116
rule = rule.strip()
130-
if rule == 'Bd':
131-
solver_ls.append(('Bd', lambda _: base_dir, 'Bd'))
117+
if rule == self.RULE_BASE_DIR:
118+
parser_list.append((rule, self.parse_bd_rule))
132119
continue
133120

134-
rule_solver = self.get_rule_solver(rule)
135-
if rule_solver is None:
121+
parser = self.get_rule_parser(rule)
122+
if parser is None:
136123
ExceptionTool.raises(f'不支持的dsl: "{rule}" in "{rule_dsl}"')
137124

138-
solver_ls.append(rule_solver)
125+
parser_list.append((rule, parser))
126+
127+
return parser_list
139128

140-
return solver_ls
129+
# noinspection PyUnusedLocal
130+
def parse_bd_rule(self, album, photo, rule):
131+
return self.base_dir
132+
133+
@classmethod
134+
def parse_f_string_rule(cls, album, photo, rule: str):
135+
properties = {}
136+
if album:
137+
properties.update(album.get_properties_dict())
138+
if photo:
139+
properties.update(photo.get_properties_dict())
140+
return rule.format(**properties)
141+
142+
@classmethod
143+
def parse_detail_rule(cls, album, photo, rule: str):
144+
detail = album if rule.startswith('A') else photo
145+
return str(DetailEntity.get_dirname(detail, rule[1:]))
141146

142147
# noinspection PyMethodMayBeStatic
143-
def split_rule_dsl(self, rule_dsl: str) -> List[str]:
144-
if rule_dsl == 'Bd':
148+
def split_rule_dsl(self, rule_dsl: str):
149+
if rule_dsl == self.RULE_BASE_DIR:
145150
return [rule_dsl]
146151

147152
if '/' in rule_dsl:
@@ -153,50 +158,19 @@ def split_rule_dsl(self, rule_dsl: str) -> List[str]:
153158
ExceptionTool.raises(f'不支持的rule配置: "{rule_dsl}"')
154159

155160
@classmethod
156-
def get_rule_solver(cls, rule: str) -> Optional[RuleSolver]:
161+
def get_rule_parser(cls, rule: str):
157162
if '{' in rule:
158-
def format_path(album, photo):
159-
return fix_windir_name(rule.format(**album.get_properties_dict(), **photo.get_properties_dict())).strip()
160-
161-
return 'F', format_path, rule
162-
163-
# 检查dsl
164-
if not rule.startswith(('A', 'P')):
165-
return None
163+
return cls.parse_f_string_rule
166164

167-
def solve_func(detail):
168-
return fix_windir_name(str(DetailEntity.get_dirname(detail, rule[1:]))).strip()
165+
if rule.startswith(('A', 'P')):
166+
return cls.parse_detail_rule
169167

170-
return rule[0], solve_func, rule
171-
172-
@classmethod
173-
def apply_rule_solver(cls, album, photo, rule_solver: RuleSolver) -> str:
174-
"""
175-
应用规则解析器(RuleSolver)
176-
177-
:param album: JmAlbumDetail
178-
:param photo: JmPhotoDetail
179-
:param rule_solver: Ptitle
180-
:returns: photo.title
181-
"""
182-
183-
def choose_detail(key):
184-
if key == 'Bd':
185-
return None,
186-
if key == 'A':
187-
return album,
188-
if key == 'P':
189-
return photo,
190-
if key == 'F':
191-
return album, photo
192-
193-
key, func, _ = rule_solver
194-
detail = choose_detail(key)
195-
return func(*detail)
168+
ExceptionTool.raises(f'不支持的rule配置: "{rule}"')
196169

197170
@classmethod
198171
def apply_rule_directly(cls, album, photo, rule: str) -> str:
199-
return cls.apply_rule_solver(album, photo, cls.get_rule_solver(rule))
172+
# noinspection PyArgumentList
173+
return fix_windir_name(cls.get_rule_parser(rule)(album, photo, rule)).strip()
200174

201175

202176
class JmOption:
@@ -471,7 +445,7 @@ def update_cookies(self, cookies: dict):
471445
orig_cookies.update(cookies)
472446
metadata['cookies'] = orig_cookies
473447

474-
# noinspection PyMethodMayBeStatic
448+
# noinspection PyMethodMayBeStatic,PyTypeChecker
475449
def decide_client_domain(self, client_key: str) -> List[str]:
476450
def is_client_type(ctype) -> bool:
477451
return self.client_key_is_given_type(client_key, ctype)

src/jmcomic/jm_plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def invoke(self,
307307

308308
elif level == 'photo':
309309
for photo, image_list in photo_dict.items():
310-
zip_path = self.get_zip_path(None, photo, filename_rule, suffix, zip_dir)
310+
zip_path = self.get_zip_path(photo.from_album, photo, filename_rule, suffix, zip_dir)
311311
self.zip_photo(photo, image_list, zip_path, path_to_delete)
312312

313313
else:

0 commit comments

Comments
 (0)