11from .jm_option import *
22
33
4- def catch_exception (field_name ):
5- def deco ( func ):
6- def wrapper ( self , * args , ** kwargs ):
7- try :
8- return func (self , * args , ** kwargs )
9- except Exception as e :
10- detail : JmBaseEntity = args [1 ]
11- getattr ( self , field_name ). append (( detail , e ))
12- if detail . is_image ():
13- detail : JmImageDetail
14- jm_log ( 'image.failed' , f'图片下载失败: [ { detail . download_url } ], 异常: { e } ' )
4+ def catch_exception (func ):
5+ def wrapper ( self , * args , ** kwargs ):
6+ self : JmDownloader
7+ try :
8+ return func (self , * args , ** kwargs )
9+ except Exception as e :
10+ detail : JmBaseEntity = args [0 ]
11+ if detail . is_image ():
12+ detail : JmImageDetail
13+ jm_log ( 'image.failed' , f'图片下载失败: [ { detail . download_url } ], 异常: [ { e } ]' )
14+ self . download_failed_image . append (( detail , e ) )
1515
16- elif detail .is_photo ():
17- detail : JmPhotoDetail
18- jm_log ('photo.failed' , f'章节下载失败: [{ detail .id } ], 异常: { e } ' )
16+ elif detail .is_photo ():
17+ detail : JmPhotoDetail
18+ jm_log ('photo.failed' , f'章节下载失败: [{ detail .id } ], 异常: [{ e } ]' )
19+ self .download_failed_photo .append ((detail , e ))
1920
20- raise e
21+ raise e
2122
22- return wrapper
23-
24- return deco
23+ wrapper .__name__ = func .__name__
24+ return wrapper
2525
2626
2727# noinspection PyMethodMayBeStatic
@@ -73,51 +73,50 @@ class JmDownloader(DownloadCallback):
7373
7474 def __init__ (self , option : JmOption ) -> None :
7575 self .option = option
76+ self .client = option .build_jm_client ()
7677 # 下载成功的记录dict
7778 self .download_success_dict : Dict [JmAlbumDetail , Dict [JmPhotoDetail , List [Tuple [str , JmImageDetail ]]]] = {}
7879 # 下载失败的记录list
7980 self .download_failed_image : List [Tuple [JmImageDetail , BaseException ]] = []
8081 self .download_failed_photo : List [Tuple [JmPhotoDetail , BaseException ]] = []
8182
8283 def download_album (self , album_id ):
83- client = self .client_for_album (album_id )
84- album = client .get_album_detail (album_id )
85- self .download_by_album_detail (album , client )
84+ album = self .client .get_album_detail (album_id )
85+ self .download_by_album_detail (album )
8686 return album
8787
88- def download_by_album_detail (self , album : JmAlbumDetail , client : JmcomicClient ):
88+ def download_by_album_detail (self , album : JmAlbumDetail ):
8989 self .before_album (album )
9090 if album .skip :
9191 return
92- self .execute_by_condition (
92+ self .execute_on_condition (
9393 iter_objs = album ,
94- apply = lambda photo : self .download_by_photo_detail ( photo , client ) ,
94+ apply = self .download_by_photo_detail ,
9595 count_batch = self .option .decide_photo_batch_count (album )
9696 )
9797 self .after_album (album )
9898
9999 def download_photo (self , photo_id ):
100- client = self .client_for_photo (photo_id )
101- photo = client .get_photo_detail (photo_id )
102- self .download_by_photo_detail (photo , client )
100+ photo = self .client .get_photo_detail (photo_id )
101+ self .download_by_photo_detail (photo )
103102 return photo
104103
105- @catch_exception ( 'download_failed_photo' )
106- def download_by_photo_detail (self , photo : JmPhotoDetail , client : JmcomicClient ):
107- client .check_photo (photo )
104+ @catch_exception
105+ def download_by_photo_detail (self , photo : JmPhotoDetail ):
106+ self . client .check_photo (photo )
108107
109108 self .before_photo (photo )
110109 if photo .skip :
111110 return
112- self .execute_by_condition (
111+ self .execute_on_condition (
113112 iter_objs = photo ,
114- apply = lambda image : self .download_by_image_detail ( image , client ) ,
113+ apply = self .download_by_image_detail ,
115114 count_batch = self .option .decide_image_batch_count (photo )
116115 )
117116 self .after_photo (photo )
118117
119- @catch_exception ( 'download_failed_image' )
120- def download_by_image_detail (self , image : JmImageDetail , client : JmcomicClient ):
118+ @catch_exception
119+ def download_by_image_detail (self , image : JmImageDetail ):
121120 img_save_path = self .option .decide_image_filepath (image )
122121
123122 image .save_path = img_save_path
@@ -136,16 +135,15 @@ def download_by_image_detail(self, image: JmImageDetail, client: JmcomicClient):
136135 if use_cache is True and image .exists :
137136 return
138137
139- client .download_by_image_detail (
138+ self . client .download_by_image_detail (
140139 image ,
141140 img_save_path ,
142141 decode_image = decode_image ,
143142 )
144143
145144 self .after_image (image , img_save_path )
146145
147- # noinspection PyMethodMayBeStatic
148- def execute_by_condition (self ,
146+ def execute_on_condition (self ,
149147 iter_objs : DetailEntity ,
150148 apply : Callable ,
151149 count_batch : int ,
@@ -186,20 +184,6 @@ def do_filter(self, detail: DetailEntity):
186184 """
187185 return detail
188186
189- # noinspection PyUnusedLocal
190- def client_for_album (self , jm_album_id ) -> JmcomicClient :
191- """
192- 默认情况下,所有的JmDownloader共用一个JmcomicClient
193- """
194- return self .option .build_jm_client ()
195-
196- # noinspection PyUnusedLocal
197- def client_for_photo (self , jm_photo_id ) -> JmcomicClient :
198- """
199- 默认情况下,所有的JmDownloader共用一个JmcomicClient
200- """
201- return self .option .build_jm_client ()
202-
203187 @property
204188 def all_success (self ) -> bool :
205189 """
@@ -209,7 +193,7 @@ def all_success(self) -> bool:
209193
210194 注意!如果使用了filter机制,例如通过filter只下载3张图片,那么all_success也会为False
211195 """
212- if not self .is_empty_download_failed :
196+ if not self .has_no_download_failed_exception :
213197 return False
214198
215199 for album , photo_dict in self .download_success_dict .items ():
@@ -223,7 +207,7 @@ def all_success(self) -> bool:
223207 return True
224208
225209 @property
226- def is_empty_download_failed (self ):
210+ def has_no_download_failed_exception (self ):
227211 return len (self .download_failed_image ) == 0 and len (self .download_failed_photo ) == 0
228212
229213 # 下面是回调方法
@@ -283,13 +267,19 @@ def after_image(self, image: JmImageDetail, img_save_path):
283267 downloader = self ,
284268 )
285269
286- def raise_if_have_exception (self ):
287- if self .is_empty_download_failed :
270+ def raise_if_has_exception (self ):
271+ if self .has_no_download_failed_exception :
288272 return
273+ msg_ls = ['部分下载失败' , '' , '' ]
274+
275+ if len (self .download_failed_photo ) != 0 :
276+ msg_ls [1 ] = f'共{ len (self .download_failed_photo )} 个章节下载失败: { self .download_failed_photo } '
277+
278+ if len (self .download_failed_image ) != 0 :
279+ msg_ls [2 ] = f'共{ len (self .download_failed_image )} 个图片下载失败: { self .download_failed_image } '
280+
289281 ExceptionTool .raises (
290- f'部分下载失败: 有{ len (self .download_failed_photo )} 个章节下载失败, { len (self .download_failed_image )} 个图片下载失败。\n ' +
291- f'失败章节IDs: { [photo .id for photo , _ in self .download_failed_photo ][:5 ]} { "..." if len (self .download_failed_photo ) > 5 else "" } \n ' +
292- f'失败图片URLs: { [image .download_url for image , _ in self .download_failed_image ][:5 ]} { "..." if len (self .download_failed_image ) > 5 else "" } ' ,
282+ '\n ' .join (msg_ls ),
293283 {'downloader' : self },
294284 PartialDownloadFailedException ,
295285 )
@@ -318,7 +308,7 @@ class DoNotDownloadImage(JmDownloader):
318308 不会下载任何图片的Downloader,用作测试
319309 """
320310
321- def download_by_image_detail (self , image : JmImageDetail , client : JmcomicClient ):
311+ def download_by_image_detail (self , image : JmImageDetail ):
322312 # ensure make dir
323313 self .option .decide_image_filepath (image )
324314
@@ -332,12 +322,13 @@ class JustDownloadSpecificCountImage(JmDownloader):
332322 count_lock = Lock ()
333323 count = 0
334324
335- def download_by_image_detail (self , image : JmImageDetail , client : JmcomicClient ):
325+ @catch_exception
326+ def download_by_image_detail (self , image : JmImageDetail ):
336327 # ensure make dir
337328 self .option .decide_image_filepath (image )
338329
339330 if self .try_countdown ():
340- return super ().download_by_image_detail (image , client )
331+ return super ().download_by_image_detail (image )
341332
342333 def try_countdown (self ):
343334 if self .count < 0 :
0 commit comments