@@ -58,56 +58,38 @@ def enable_client_cache_on_condition(cls,
5858
5959
6060class 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
202172class JmOption :
0 commit comments