Skip to content

Commit 9aafc8e

Browse files
committed
dir_rule重构
1 parent 89419f8 commit 9aafc8e

1 file changed

Lines changed: 42 additions & 72 deletions

File tree

src/jmcomic/jm_option.py

Lines changed: 42 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -58,56 +58,38 @@ 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]
7761

7862
def __init__(self, rule: str, base_dir=None):
7963
base_dir = JmcomicText.parse_to_abspath(base_dir)
8064
self.base_dir = base_dir
8165
self.rule_dsl = rule
82-
self.solver_list = self.get_role_solver_list(rule, base_dir)
66+
self.parser_list: List[Tuple[str, Callable]] = self.get_rule_solver_list(rule)
8367

8468
def decide_image_save_dir(self,
8569
album: JmAlbumDetail,
8670
photo: JmPhotoDetail,
8771
) -> str:
8872
path_ls = []
89-
for solver in self.solver_list:
73+
for rule, parser in self.parser_list:
9074
try:
91-
ret = self.apply_rule_solver(album, photo, solver)
75+
ret = parser(album, photo, rule)
9276
except BaseException as e:
9377
# noinspection PyUnboundLocalVariable
94-
jm_log('dir_rule', f'路径规则"{solver[2]}"的解析出错: {e}, album={album}, photo={photo}')
78+
jm_log('dir_rule', f'路径规则"{rule}"的解析出错: {e}, album={album}, photo={photo}')
9579
raise e
9680

97-
path_ls.append(str(ret))
81+
path_ls.append(fix_windir_name(str(ret)).strip())
9882

9983
return fix_filepath('/'.join(path_ls), is_dir=True)
10084

10185
def decide_album_root_dir(self, album: JmAlbumDetail) -> str:
10286
path_ls = []
103-
for solver in self.solver_list:
104-
key, _, rule = solver
105-
106-
if key != 'Bd' and key != 'A':
87+
for rule, parser in self.parser_list:
88+
if rule != 'Bd' or not rule.startswith('A'):
10789
continue
10890

10991
try:
110-
ret = self.apply_rule_solver(album, None, solver)
92+
ret = parser(album, None, parser)
11193
except BaseException as e:
11294
# noinspection PyUnboundLocalVariable
11395
jm_log('dir_rule', f'路径规则"{rule}"的解析出错: {e}, album={album}')
@@ -117,30 +99,49 @@ def decide_album_root_dir(self, album: JmAlbumDetail) -> str:
11799

118100
return fix_filepath('/'.join(path_ls), is_dir=True)
119101

120-
def get_role_solver_list(self, rule_dsl: str, base_dir: str) -> RuleSolverList:
102+
def get_rule_solver_list(self, rule_dsl: str):
121103
"""
122104
解析下载路径dsl,得到一个路径规则解析列表
123105
"""
124106

125107
rule_list = self.split_rule_dsl(rule_dsl)
126-
solver_ls: List[DirRule.RuleSolver] = []
108+
parser_list: list = []
127109

128110
for rule in rule_list:
129111
rule = rule.strip()
130112
if rule == 'Bd':
131-
solver_ls.append(('Bd', lambda _: base_dir, 'Bd'))
113+
parser_list.append((rule, self.parse_bd_rule))
132114
continue
133115

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

138-
solver_ls.append(rule_solver)
120+
parser_list.append((rule, parser))
121+
122+
return parser_list
123+
124+
# noinspection PyUnusedLocal
125+
def parse_bd_rule(self, album, photo, rule):
126+
return self.base_dir
139127

140-
return solver_ls
128+
@classmethod
129+
def parse_f_string_rule(cls, album, photo, rule: str):
130+
properties = {}
131+
if photo:
132+
properties.update(photo.getproperties())
133+
if album:
134+
properties.update(photo.getproperties())
135+
136+
return rule.format(properties)
137+
138+
@classmethod
139+
def parse_detail_rule(cls, album, photo, rule: str):
140+
detail = album if rule.startswith('A') else photo
141+
return str(DetailEntity.get_dirname(detail, rule[1:]))
141142

142143
# noinspection PyMethodMayBeStatic
143-
def split_rule_dsl(self, rule_dsl: str) -> List[str]:
144+
def split_rule_dsl(self, rule_dsl: str):
144145
if rule_dsl == 'Bd':
145146
return [rule_dsl]
146147

@@ -153,50 +154,19 @@ def split_rule_dsl(self, rule_dsl: str) -> List[str]:
153154
ExceptionTool.raises(f'不支持的rule配置: "{rule_dsl}"')
154155

155156
@classmethod
156-
def get_rule_solver(cls, rule: str) -> Optional[RuleSolver]:
157+
def get_rule_parser(cls, rule: str):
157158
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
166-
167-
def solve_func(detail):
168-
return fix_windir_name(str(DetailEntity.get_dirname(detail, rule[1:]))).strip()
169-
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-
"""
159+
return cls.parse_f_string_rule
182160

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
161+
if rule.startswith(('A', 'P')):
162+
return cls.parse_detail_rule
192163

193-
key, func, _ = rule_solver
194-
detail = choose_detail(key)
195-
return func(*detail)
164+
ExceptionTool.raises(f'不支持的rule配置: "{rule}"')
196165

197166
@classmethod
198167
def apply_rule_directly(cls, album, photo, rule: str) -> str:
199-
return cls.apply_rule_solver(album, photo, cls.get_rule_solver(rule))
168+
# noinspection PyArgumentList
169+
return cls.get_rule_parser(rule)(album, photo, rule)
200170

201171

202172
class JmOption:

0 commit comments

Comments
 (0)