@@ -58,56 +58,40 @@ 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+ path = 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
80+ if parser != self .parse_bd_rule :
81+ path = fix_windir_name (str (path )).strip ()
9682
97- path_ls .append (str ( ret ) )
83+ path_ls .append (path )
9884
9985 return fix_filepath ('/' .join (path_ls ), is_dir = True )
10086
10187 def decide_album_root_dir (self , album : JmAlbumDetail ) -> str :
10288 path_ls = []
103- for solver in self .solver_list :
104- key , _ , rule = solver
105-
106- if key != 'Bd' and key != 'A' :
89+ for rule , parser in self .parser_list :
90+ if rule != 'Bd' or not rule .startswith ('A' ):
10791 continue
10892
10993 try :
110- ret = self . apply_rule_solver (album , None , solver )
94+ ret = parser (album , None , parser )
11195 except BaseException as e :
11296 # noinspection PyUnboundLocalVariable
11397 jm_log ('dir_rule' , f'路径规则"{ rule } "的解析出错: { e } , album={ album } ' )
@@ -117,30 +101,49 @@ def decide_album_root_dir(self, album: JmAlbumDetail) -> str:
117101
118102 return fix_filepath ('/' .join (path_ls ), is_dir = True )
119103
120- def get_role_solver_list (self , rule_dsl : str , base_dir : str ) -> RuleSolverList :
104+ def get_rule_solver_list (self , rule_dsl : str ) :
121105 """
122106 解析下载路径dsl,得到一个路径规则解析列表
123107 """
124108
125109 rule_list = self .split_rule_dsl (rule_dsl )
126- solver_ls : List [ DirRule . RuleSolver ] = []
110+ parser_list : list = []
127111
128112 for rule in rule_list :
129113 rule = rule .strip ()
130114 if rule == 'Bd' :
131- solver_ls .append (('Bd' , lambda _ : base_dir , 'Bd' ))
115+ parser_list .append ((rule , self . parse_bd_rule ))
132116 continue
133117
134- rule_solver = self .get_rule_solver (rule )
135- if rule_solver is None :
118+ parser = self .get_rule_parser (rule )
119+ if parser is None :
136120 ExceptionTool .raises (f'不支持的dsl: "{ rule } " in "{ rule_dsl } "' )
137121
138- solver_ls .append (rule_solver )
122+ parser_list .append ((rule , parser ))
123+
124+ return parser_list
125+
126+ # noinspection PyUnusedLocal
127+ def parse_bd_rule (self , album , photo , rule ):
128+ return self .base_dir
129+
130+ @classmethod
131+ def parse_f_string_rule (cls , album , photo , rule : str ):
132+ properties = {}
133+ if photo :
134+ properties .update (photo .getproperties ())
135+ if album :
136+ properties .update (photo .getproperties ())
139137
140- return solver_ls
138+ return rule .format (properties )
139+
140+ @classmethod
141+ def parse_detail_rule (cls , album , photo , rule : str ):
142+ detail = album if rule .startswith ('A' ) else photo
143+ return str (DetailEntity .get_dirname (detail , rule [1 :]))
141144
142145 # noinspection PyMethodMayBeStatic
143- def split_rule_dsl (self , rule_dsl : str ) -> List [ str ] :
146+ def split_rule_dsl (self , rule_dsl : str ):
144147 if rule_dsl == 'Bd' :
145148 return [rule_dsl ]
146149
@@ -153,50 +156,19 @@ def split_rule_dsl(self, rule_dsl: str) -> List[str]:
153156 ExceptionTool .raises (f'不支持的rule配置: "{ rule_dsl } "' )
154157
155158 @classmethod
156- def get_rule_solver (cls , rule : str ) -> Optional [ RuleSolver ] :
159+ def get_rule_parser (cls , rule : str ):
157160 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
161+ return cls .parse_f_string_rule
162162
163- # 检查dsl
164- if not rule .startswith (('A' , 'P' )):
165- return None
163+ if rule .startswith (('A' , 'P' )):
164+ return cls .parse_detail_rule
166165
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- """
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 )
166+ ExceptionTool .raises (f'不支持的rule配置: "{ rule } "' )
196167
197168 @classmethod
198169 def apply_rule_directly (cls , album , photo , rule : str ) -> str :
199- return cls .apply_rule_solver (album , photo , cls .get_rule_solver (rule ))
170+ # noinspection PyArgumentList
171+ return cls .get_rule_parser (rule )(album , photo , rule )
200172
201173
202174class JmOption :
@@ -471,7 +443,7 @@ def update_cookies(self, cookies: dict):
471443 orig_cookies .update (cookies )
472444 metadata ['cookies' ] = orig_cookies
473445
474- # noinspection PyMethodMayBeStatic
446+ # noinspection PyMethodMayBeStatic,PyTypeChecker
475447 def decide_client_domain (self , client_key : str ) -> List [str ]:
476448 def is_client_type (ctype ) -> bool :
477449 return self .client_key_is_given_type (client_key , ctype )
0 commit comments