or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-system.mdcommand-line-interface.mdconfiguration-management.mdcontent-entities.mdcore-download-api.mddownload-system.mdexception-handling.mdindex.mdplugin-system.mdtext-data-processing.md

download-system.mddocs/

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

```