0
# Download System
1
2
Comprehensive download management system with support for callbacks, progress tracking, exception handling, and specialized download behaviors. Provides fine-grained control over the download process with various downloader implementations.
3
4
## Types
5
6
```python { .api }
7
from typing import Callable, List, Any, Optional, Dict, Union
8
```
9
10
## Capabilities
11
12
### Main Downloader Class
13
14
The primary downloader class that handles album, photo, and image downloads with comprehensive error handling and callback support.
15
16
```python { .api }
17
class JmDownloader:
18
"""
19
Main downloader class with comprehensive download functionality.
20
21
Attributes:
22
- option: JmOption - Configuration options for the downloader
23
- client: JmcomicClient - Client instance for API/web operations
24
- exception_list: List[Exception] - List of exceptions encountered during download
25
- callback: DownloadCallback - Callback handler for download events
26
27
Methods:
28
- download_album(album_id): Download complete album with all episodes
29
- download_photo(photo_id): Download single photo with all images
30
- download_image(image): Download individual image
31
- has_exception(): Check if any exceptions occurred
32
- raise_if_has_exception(): Raise PartialDownloadFailedException if errors exist
33
- clear_exception(): Clear the exception list
34
"""
35
36
def __init__(self, option: 'JmOption'):
37
"""
38
Initialize downloader with configuration options.
39
40
Parameters:
41
- option: JmOption - Configuration for download behavior
42
"""
43
44
def download_album(self, album_id: Union[str, int]) -> 'JmAlbumDetail':
45
"""
46
Download a complete album including all episodes and images.
47
48
Parameters:
49
- album_id: str or int - Album ID to download
50
51
Returns:
52
JmAlbumDetail - Downloaded album with all metadata and episodes
53
"""
54
55
def download_photo(self, photo_id: Union[str, int]) -> 'JmPhotoDetail':
56
"""
57
Download a single photo/chapter with all images.
58
59
Parameters:
60
- photo_id: str or int - Photo ID to download
61
62
Returns:
63
JmPhotoDetail - Downloaded photo with all metadata and images
64
"""
65
66
def download_image(self, image: 'JmImageDetail') -> bool:
67
"""
68
Download an individual image.
69
70
Parameters:
71
- image: JmImageDetail - Image entity to download
72
73
Returns:
74
bool - True if download successful, False otherwise
75
"""
76
77
def has_exception(self) -> bool:
78
"""
79
Check if any exceptions occurred during download.
80
81
Returns:
82
bool - True if exceptions exist, False otherwise
83
"""
84
85
def raise_if_has_exception(self):
86
"""
87
Raise PartialDownloadFailedException if any exceptions occurred.
88
89
Raises:
90
PartialDownloadFailedException - If exception_list is not empty
91
"""
92
93
def clear_exception(self):
94
"""Clear all recorded exceptions."""
95
```
96
97
Usage examples:
98
99
```python
100
# Create and use downloader
101
option = create_option_by_file("config.yml")
102
downloader = JmDownloader(option)
103
104
# Download album
105
album = downloader.download_album("123456")
106
107
# Check for errors
108
if downloader.has_exception():
109
print(f"Errors occurred: {len(downloader.exception_list)}")
110
for exc in downloader.exception_list:
111
print(f" {type(exc).__name__}: {exc}")
112
113
# Raise errors if any
114
try:
115
downloader.raise_if_has_exception()
116
except PartialDownloadFailedException as e:
117
print(f"Download failed: {e}")
118
```
119
120
### Test Downloader Classes
121
122
Specialized downloader implementations for testing and development purposes.
123
124
```python { .api }
125
class DoNotDownloadImage(JmDownloader):
126
"""
127
Test downloader that skips actual image downloads.
128
129
Useful for testing metadata extraction and API functionality
130
without downloading large image files.
131
"""
132
133
class JustDownloadSpecificCountImage(JmDownloader):
134
"""
135
Test downloader that downloads only a specific number of images.
136
137
Useful for testing download functionality with limited data transfer.
138
139
Attributes:
140
- count: int - Maximum number of images to download
141
"""
142
143
def __init__(self, option: 'JmOption', count: int = 1):
144
"""
145
Initialize with download count limit.
146
147
Parameters:
148
- option: JmOption - Configuration options
149
- count: int - Maximum number of images to download
150
"""
151
```
152
153
Usage examples:
154
155
```python
156
# Test without downloading images
157
option = create_option_by_file("config.yml")
158
test_downloader = DoNotDownloadImage(option)
159
album = test_downloader.download_album("123456") # Only metadata, no images
160
161
# Test with limited image downloads
162
limited_downloader = JustDownloadSpecificCountImage(option, count=5)
163
album = limited_downloader.download_album("123456") # Only first 5 images
164
```
165
166
### Download Callback System
167
168
Callback interface for monitoring and responding to download events.
169
170
```python { .api }
171
class DownloadCallback:
172
"""
173
Callback interface for download progress and event monitoring.
174
175
Methods:
176
- on_album_start(album): Called when album download starts
177
- on_album_complete(album): Called when album download completes
178
- on_photo_start(photo): Called when photo download starts
179
- on_photo_complete(photo): Called when photo download completes
180
- on_image_start(image): Called when image download starts
181
- on_image_complete(image): Called when image download completes
182
- on_error(exception, context): Called when errors occur
183
"""
184
185
def on_album_start(self, album: 'JmAlbumDetail'):
186
"""
187
Called when album download starts.
188
189
Parameters:
190
- album: JmAlbumDetail - Album being downloaded
191
"""
192
193
def on_album_complete(self, album: 'JmAlbumDetail'):
194
"""
195
Called when album download completes.
196
197
Parameters:
198
- album: JmAlbumDetail - Completed album
199
"""
200
201
def on_photo_start(self, photo: 'JmPhotoDetail'):
202
"""
203
Called when photo download starts.
204
205
Parameters:
206
- photo: JmPhotoDetail - Photo being downloaded
207
"""
208
209
def on_photo_complete(self, photo: 'JmPhotoDetail'):
210
"""
211
Called when photo download completes.
212
213
Parameters:
214
- photo: JmPhotoDetail - Completed photo
215
"""
216
217
def on_image_start(self, image: 'JmImageDetail'):
218
"""
219
Called when image download starts.
220
221
Parameters:
222
- image: JmImageDetail - Image being downloaded
223
"""
224
225
def on_image_complete(self, image: 'JmImageDetail'):
226
"""
227
Called when image download completes.
228
229
Parameters:
230
- image: JmImageDetail - Completed image
231
"""
232
233
def on_error(self, exception: Exception, context: Dict[str, Any]):
234
"""
235
Called when errors occur during download.
236
237
Parameters:
238
- exception: Exception - The error that occurred
239
- context: dict - Additional context about the error
240
"""
241
```
242
243
Usage examples:
244
245
```python
246
# Custom callback implementation
247
class MyDownloadCallback(DownloadCallback):
248
def on_album_start(self, album):
249
print(f"Starting download: {album.title}")
250
251
def on_photo_complete(self, photo):
252
print(f"Completed chapter: {photo.title}")
253
254
def on_error(self, exception, context):
255
print(f"Error: {exception} in {context}")
256
257
# Use callback with downloader
258
callback = MyDownloadCallback()
259
option = create_option_by_file("config.yml")
260
downloader = JmDownloader(option)
261
downloader.callback = callback
262
263
album = downloader.download_album("123456")
264
```
265
266
### Exception Handling Utility
267
268
Decorator for exception handling in download operations.
269
270
```python { .api }
271
def catch_exception(func: Callable) -> Callable:
272
"""
273
Decorator for catching and logging exceptions in download operations.
274
275
Parameters:
276
- func: callable - Function to wrap with exception handling
277
278
Returns:
279
callable - Wrapped function with exception handling
280
"""
281
```
282
283
Usage examples:
284
285
```python
286
# Apply exception handling to custom functions
287
@catch_exception
288
def custom_download_operation():
289
# Custom download logic here
290
pass
291
292
# Exception is caught and logged automatically
293
custom_download_operation()
294
```
295
296
## Download Flow
297
298
The typical download flow follows this pattern:
299
300
1. **Initialization**: Create `JmDownloader` with `JmOption` configuration
301
2. **Album Download**: Call `download_album()` which:
302
- Fetches album metadata using the configured client
303
- Iterates through each episode/photo
304
- Downloads images for each photo
305
- Triggers callbacks for progress monitoring
306
3. **Error Handling**: Exceptions are collected in `exception_list`
307
4. **Completion**: Check for errors and process results
308
309
## Context Manager Support
310
311
Downloaders can be used as context managers for automatic resource cleanup:
312
313
```python
314
with new_downloader(option) as downloader:
315
album = downloader.download_album("123456")
316
# Automatic cleanup on exit
317
```