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

plugin-system.mddocs/

0

# Plugin System

1

2

Extensible plugin framework with 18+ built-in plugins covering login, monitoring, notifications, content processing, and advanced download features. Provides a comprehensive system for extending and customizing JMComic functionality.

3

4

## Types

5

6

```python { .api }

7

from typing import Dict, Any, List, Optional, Union, Callable

8

```

9

10

## Capabilities

11

12

### Base Plugin Framework

13

14

Foundation classes for creating and managing plugins with validation, logging, and lifecycle management.

15

16

```python { .api }

17

class JmOptionPlugin:

18

"""

19

Base plugin class with validation, logging, and file operations.

20

21

All plugins inherit from this base class and implement specific

22

functionality through hook methods and configuration.

23

24

Attributes:

25

- option: JmOption - Configuration options

26

- enabled: bool - Whether plugin is enabled

27

- priority: int - Plugin execution priority

28

- plugin_key: str - Unique plugin identifier

29

30

Methods:

31

- validate(): Validate plugin configuration

32

- before_album(album): Hook called before album processing

33

- after_album(album): Hook called after album processing

34

- before_photo(photo): Hook called before photo processing

35

- after_photo(photo): Hook called after photo processing

36

- before_image(image): Hook called before image processing

37

- after_image(image): Hook called after image processing

38

- on_error(exception, context): Hook called on errors

39

"""

40

41

def __init__(self, option: 'JmOption'):

42

"""

43

Initialize plugin with configuration.

44

45

Parameters:

46

- option: JmOption - Configuration options

47

"""

48

49

def validate(self):

50

"""

51

Validate plugin configuration and requirements.

52

53

Raises:

54

PluginValidationException - If configuration is invalid

55

"""

56

57

def before_album(self, album: 'JmAlbumDetail'):

58

"""

59

Hook called before album processing starts.

60

61

Parameters:

62

- album: JmAlbumDetail - Album being processed

63

"""

64

65

def after_album(self, album: 'JmAlbumDetail'):

66

"""

67

Hook called after album processing completes.

68

69

Parameters:

70

- album: JmAlbumDetail - Processed album

71

"""

72

73

def before_photo(self, photo: 'JmPhotoDetail'):

74

"""

75

Hook called before photo processing starts.

76

77

Parameters:

78

- photo: JmPhotoDetail - Photo being processed

79

"""

80

81

def after_photo(self, photo: 'JmPhotoDetail'):

82

"""

83

Hook called after photo processing completes.

84

85

Parameters:

86

- photo: JmPhotoDetail - Processed photo

87

"""

88

89

class PluginValidationException(Exception):

90

"""

91

Exception raised when plugin configuration validation fails.

92

93

Attributes:

94

- plugin_name: str - Name of the plugin that failed validation

95

- message: str - Validation error message

96

"""

97

```

98

99

### Authentication and Login Plugins

100

101

Plugins for handling user authentication and session management.

102

103

```python { .api }

104

class JmLoginPlugin(JmOptionPlugin):

105

"""

106

Automated login and cookie management plugin.

107

108

Handles user authentication, session management, and automatic

109

cookie refreshing for accessing protected content.

110

111

Configuration:

112

- username: str - Login username/email

113

- password: str - Login password

114

- auto_login: bool - Whether to login automatically

115

- save_cookies: bool - Whether to save session cookies

116

- cookie_file: str - Path to cookie storage file

117

"""

118

119

def login(self) -> bool:

120

"""

121

Perform login with configured credentials.

122

123

Returns:

124

bool - True if login successful

125

"""

126

127

def is_logged_in(self) -> bool:

128

"""

129

Check if currently logged in.

130

131

Returns:

132

bool - True if valid session exists

133

"""

134

135

def refresh_session(self):

136

"""Refresh authentication session."""

137

138

class AutoSetBrowserCookiesPlugin(JmOptionPlugin):

139

"""

140

Import cookies from installed browsers for automatic authentication.

141

142

Supports importing cookies from Chrome, Firefox, Edge, and other

143

browsers to avoid manual login.

144

145

Configuration:

146

- browser: str - Browser to import from ('chrome', 'firefox', etc.)

147

- profile: str - Browser profile name (optional)

148

"""

149

```

150

151

### Monitoring and Logging Plugins

152

153

Plugins for system monitoring, resource tracking, and logging management.

154

155

```python { .api }

156

class UsageLogPlugin(JmOptionPlugin):

157

"""

158

System resource usage monitoring and reporting plugin.

159

160

Tracks CPU usage, memory consumption, disk I/O, and network

161

traffic during download operations.

162

163

Configuration:

164

- log_file: str - Path to usage log file

165

- log_interval: int - Logging interval in seconds

166

- include_system_stats: bool - Include system-wide statistics

167

"""

168

169

def get_current_usage(self) -> Dict[str, Any]:

170

"""

171

Get current system resource usage.

172

173

Returns:

174

dict - Resource usage statistics

175

"""

176

177

class LogTopicFilterPlugin(JmOptionPlugin):

178

"""

179

Filter log messages by topic/category for cleaner logs.

180

181

Configuration:

182

- allowed_topics: List[str] - Topics to include in logs

183

- blocked_topics: List[str] - Topics to exclude from logs

184

- log_level: str - Minimum log level ('DEBUG', 'INFO', 'WARNING', 'ERROR')

185

"""

186

```

187

188

### Content Processing Plugins

189

190

Plugins for processing downloaded content including archiving, format conversion, and organization.

191

192

```python { .api }

193

class ZipPlugin(JmOptionPlugin):

194

"""

195

Archive downloaded content with optional password encryption.

196

197

Creates ZIP archives of downloaded albums with compression

198

and optional password protection.

199

200

Configuration:

201

- enabled: bool - Whether to create archives

202

- password: str - Archive password (optional)

203

- compression_level: int - Compression level (0-9)

204

- archive_per_album: bool - Create separate archive per album

205

- delete_original: bool - Delete original files after archiving

206

"""

207

208

def create_archive(self, album: 'JmAlbumDetail') -> str:

209

"""

210

Create ZIP archive for album.

211

212

Parameters:

213

- album: JmAlbumDetail - Album to archive

214

215

Returns:

216

str - Path to created archive file

217

"""

218

219

class Img2pdfPlugin(JmOptionPlugin):

220

"""

221

Convert images to PDF with optional encryption.

222

223

Creates PDF documents from downloaded images with support

224

for password protection and metadata.

225

226

Configuration:

227

- enabled: bool - Whether to create PDFs

228

- password: str - PDF password (optional)

229

- quality: str - Image quality ('high', 'medium', 'low')

230

- pdf_per_photo: bool - Create PDF per photo vs per album

231

"""

232

233

class LongImgPlugin(JmOptionPlugin):

234

"""

235

Merge images into long scrolling format for mobile viewing.

236

237

Concatenates images vertically to create long scroll images

238

suitable for mobile comic readers.

239

240

Configuration:

241

- enabled: bool - Whether to create long images

242

- max_height: int - Maximum image height

243

- spacing: int - Spacing between images in pixels

244

"""

245

```

246

247

### Download Enhancement Plugins

248

249

Plugins that enhance and customize the download process.

250

251

```python { .api }

252

class FindUpdatePlugin(JmOptionPlugin):

253

"""

254

Find and download new chapters for existing albums.

255

256

Monitors albums for new content and automatically downloads

257

new chapters when they become available.

258

259

Configuration:

260

- check_interval: int - Check interval in hours

261

- album_ids: List[str] - Albums to monitor

262

- auto_download: bool - Automatically download new chapters

263

"""

264

265

def check_for_updates(self) -> List['JmAlbumDetail']:

266

"""

267

Check monitored albums for updates.

268

269

Returns:

270

List[JmAlbumDetail] - Albums with new content

271

"""

272

273

class SubscribeAlbumUpdatePlugin(JmOptionPlugin):

274

"""

275

Monitor albums for new chapter updates with notifications.

276

277

Configuration:

278

- subscribed_albums: List[str] - Album IDs to monitor

279

- check_frequency: int - Check frequency in hours

280

- notification_method: str - Notification method ('email', 'webhook')

281

"""

282

283

class ClientProxyPlugin(JmOptionPlugin):

284

"""

285

Proxy client requests through other clients for failover.

286

287

Provides client redundancy by routing requests through

288

multiple client implementations.

289

290

Configuration:

291

- primary_client: str - Primary client type

292

- fallback_clients: List[str] - Fallback client types

293

- switch_threshold: int - Error threshold for client switching

294

"""

295

296

class AdvancedRetryPlugin(JmOptionPlugin):

297

"""

298

Enhanced retry mechanisms with backoff strategies.

299

300

Configuration:

301

- max_retries: int - Maximum retry attempts

302

- backoff_strategy: str - Backoff strategy ('exponential', 'linear')

303

- retry_delay: float - Base retry delay in seconds

304

"""

305

```

306

307

### Content Filtering Plugins

308

309

Plugins for filtering and selecting content based on various criteria.

310

311

```python { .api }

312

class ImageSuffixFilterPlugin(JmOptionPlugin):

313

"""

314

Filter downloads by image format/extension.

315

316

Configuration:

317

- allowed_formats: List[str] - Allowed image formats

318

- blocked_formats: List[str] - Blocked image formats

319

- convert_formats: Dict[str, str] - Format conversion mapping

320

"""

321

322

class SkipPhotoWithFewImagesPlugin(JmOptionPlugin):

323

"""

324

Skip chapters with insufficient images.

325

326

Configuration:

327

- min_images: int - Minimum number of images required

328

- skip_action: str - Action for skipped photos ('skip', 'mark', 'log')

329

"""

330

```

331

332

### Notification and Integration Plugins

333

334

Plugins for external notifications and system integration.

335

336

```python { .api }

337

class SendQQEmailPlugin(JmOptionPlugin):

338

"""

339

Email notification system for download completion.

340

341

Sends email notifications when downloads complete or fail.

342

343

Configuration:

344

- smtp_server: str - SMTP server address

345

- smtp_port: int - SMTP server port

346

- username: str - Email username

347

- password: str - Email password

348

- to_email: str - Recipient email address

349

- notify_on_complete: bool - Send notification on completion

350

- notify_on_error: bool - Send notification on errors

351

"""

352

353

def send_notification(self, subject: str, message: str):

354

"""

355

Send email notification.

356

357

Parameters:

358

- subject: str - Email subject

359

- message: str - Email message body

360

"""

361

362

class JmServerPlugin(JmOptionPlugin):

363

"""

364

Built-in web server for viewing downloaded content.

365

366

Starts a local web server to browse and view downloaded

367

content through a web interface.

368

369

Configuration:

370

- port: int - Server port

371

- host: str - Server host address

372

- auto_start: bool - Start server automatically

373

- enable_uploads: bool - Enable file uploads

374

"""

375

376

def start_server(self):

377

"""Start the web server."""

378

379

def stop_server(self):

380

"""Stop the web server."""

381

```

382

383

### Utility Plugins

384

385

Plugins for file management and system utilities.

386

387

```python { .api }

388

class DeleteDuplicatedFilesPlugin(JmOptionPlugin):

389

"""

390

Remove duplicate files from downloads.

391

392

Configuration:

393

- check_method: str - Duplicate detection method ('hash', 'name', 'size')

394

- delete_action: str - Action for duplicates ('delete', 'move', 'mark')

395

"""

396

397

class ReplacePathStringPlugin(JmOptionPlugin):

398

"""

399

Modify file paths with pattern replacement.

400

401

Configuration:

402

- replacements: Dict[str, str] - Pattern replacement mapping

403

- use_regex: bool - Whether to use regex patterns

404

"""

405

406

class FavoriteFolderExportPlugin(JmOptionPlugin):

407

"""

408

Export user favorites data to files.

409

410

Configuration:

411

- export_format: str - Export format ('json', 'csv', 'txt')

412

- output_file: str - Output file path

413

- include_metadata: bool - Include full metadata

414

"""

415

```

416

417

## Plugin Usage Examples

418

419

```python

420

# Configure plugins in JmOption

421

option = JmOption.default()

422

423

# Enable login plugin

424

option.plugins['JmLoginPlugin'] = {

425

'username': 'user@example.com',

426

'password': 'password',

427

'auto_login': True

428

}

429

430

# Enable ZIP archiving

431

option.plugins['ZipPlugin'] = {

432

'enabled': True,

433

'password': 'archive_password',

434

'compression_level': 6

435

}

436

437

# Enable usage monitoring

438

option.plugins['UsageLogPlugin'] = {

439

'log_file': 'usage.log',

440

'log_interval': 60

441

}

442

443

# Use configured plugins

444

downloader = JmDownloader(option)

445

album = downloader.download_album("123456")

446

# Plugins automatically execute during download process

447

```

448

449

## Custom Plugin Development

450

451

Create custom plugins by inheriting from `JmOptionPlugin`:

452

453

```python

454

class MyCustomPlugin(JmOptionPlugin):

455

def validate(self):

456

# Validate plugin configuration

457

required_config = self.option.plugins.get('MyCustomPlugin', {})

458

if 'required_param' not in required_config:

459

raise PluginValidationException("required_param is missing")

460

461

def after_album(self, album):

462

# Custom processing after album download

463

print(f"Processed album: {album.title}")

464

# Add custom logic here

465

466

# Register and use custom plugin

467

option.plugins['MyCustomPlugin'] = {

468

'required_param': 'value'

469

}

470

```

471

472

## Plugin Execution Order

473

474

Plugins execute in priority order during download lifecycle:

475

476

1. **Validation Phase**: All plugins validate their configuration

477

2. **Before Album**: Plugins execute `before_album()` hooks

478

3. **Before Photo**: Plugins execute `before_photo()` hooks for each photo

479

4. **Before Image**: Plugins execute `before_image()` hooks for each image

480

5. **After Image**: Plugins execute `after_image()` hooks for each image

481

6. **After Photo**: Plugins execute `after_photo()` hooks for each photo

482

7. **After Album**: Plugins execute `after_album()` hooks

483

8. **Error Handling**: Plugins handle errors via `on_error()` hooks