usenet-dl
A high-performance, highly configurable backend library for building Usenet download applications in Rust.
Features
Core Capabilities
- Queue Management: Priority-based download queue with pause/resume/cancel
- Resume Support: Article-level download tracking, survives crashes and restarts
- Parallel Downloads: Concurrent article fetching using all configured connections (~N× speedup with N connections)
- Speed Limiting: Global bandwidth control with token bucket algorithm
- Retry Logic: Exponential backoff with jitter for transient failures
- Event System: Real-time events via
tokio::broadcastchannels - Graceful Shutdown: Signal handling with state preservation
Post-Processing
- DirectUnpack: Extract RAR archives while downloads are still in progress (overlaps extraction with download time)
- DirectRename: Fix obfuscated filenames mid-download using PAR2 metadata
- Archive Extraction: RAR, 7z, and ZIP with password support
- Nested Extraction: Automatic recursive extraction (configurable depth)
- Password Management: Multi-source passwords (per-download, NZB metadata, global file, cache)
- Deobfuscation: Automatic detection and renaming of obfuscated filenames
- File Collision Handling: Rename, overwrite, or skip on conflicts
- Smart Cleanup: Remove .par2, .nzb, .sfv, sample folders, and archives after extraction
REST API
- OpenAPI 3.1 Compliant: Full schema generation with utoipa
- Swagger UI: Interactive API documentation at
/swagger-ui - Server-Sent Events: Real-time updates via
/eventsendpoint - 37 Endpoints: Complete CRUD for downloads, queue, history, config, categories, RSS, scheduler
- Authentication: Optional API key protection
- CORS: Configurable cross-origin support for frontend development
- Rate Limiting: Optional per-IP rate limiting (disabled by default)
Automation
- Folder Watching: Auto-import NZB files from watched directories
- URL Fetching: Download NZBs directly from HTTP(S) URLs
- RSS Feed Monitoring: Automatic download with regex filters and scheduling
- Time-Based Scheduler: Speed limits and pause/resume based on time rules
- Duplicate Detection: Hash and name-based duplicate checking
Notifications
- Webhooks: HTTP POST on download events (complete, failed, queued)
- Script Execution: Run external scripts with environment variables
- Category Scripts: Per-category script configuration
- Disk Space Checks: Pre-download validation with configurable buffer
- Server Health Checks: Test NNTP server connectivity and capabilities
Design Philosophy
usenet-dl is a library-first backend. No CLI, no UI - just a solid Rust crate that frontend applications can embed.
- Highly Configurable: Almost every behavior can be customized
- Sensible Defaults: Works out of the box with minimal configuration
- Event-Driven: Subscribe to events, no polling required
- Async Native: Built on tokio for efficient concurrent operations
Architecture
┌─────────────────────────────────────────┐
│ Your Application │
├─────────────────────────────────────────┤
│ usenet-dl │
│ (Queue, Post-processing, API, DB) │
├─────────────────────────────────────────┤
│ nntp-rs │
│ (NNTP, NZB parsing, yEnc, PAR2) │
└─────────────────────────────────────────┘
Responsibility Split
usenet-dl handles:
- Download queue management and persistence (SQLite)
- Post-processing pipeline (verify, repair, extract, rename, cleanup)
- Archive extraction (RAR/7z/ZIP) with password management
- File organization and collision handling
- REST API with OpenAPI documentation
- Event broadcasting to subscribers
- Folder watching and RSS feed monitoring
- Scheduler for time-based rules
- External notifications (webhooks, scripts)
- Disk space checking and health monitoring
nntp-rs handles:
- NNTP protocol implementation (RFC 3977)
- NZB file parsing
- yEnc decoding
- PAR2 verification and repair
- Connection pooling
Installation
Not yet published to crates.io
Add as a path or git dependency:
[]
= { = "../usenet-dl" }
# or
= { = "https://github.com/jvz-devx/usenet-dl" }
Requirements
- Rust 1.93 or later
- SQLite (embedded via sqlx)
- Optional: unrar command-line tool for RAR extraction
- Optional: 7z command-line tool for 7z extraction
Quick Start
Basic Usage
use ;
use ;
async
REST API
Start the API server:
use Arc;
use start_api_server;
use ;
let config = Config ;
let downloader = new;
let config = new;
start_api_server.await?;
The API will be available at http://localhost:6789 with Swagger UI at http://localhost:6789/swagger-ui.
Example API Calls
# Add NZB from URL
# List all downloads
# Get download status
# Pause download
# Set speed limit to 10 MB/s
# Stream real-time events
Configuration
All settings have sensible defaults. Only NNTP server configuration is required.
Default Settings
| Setting | Default | Rationale |
|---|---|---|
| Download directory | ./downloads |
Current directory, easy to find |
| Temp directory | ./temp |
Separate from final downloads |
| Concurrent downloads | 3 | Balanced throughput without overwhelming |
| Speed limit | Unlimited | Users expect full speed by default |
| Post-processing | Unpack + Cleanup | Most users want ready-to-use files |
| DirectUnpack | Disabled | Opt-in for advanced users |
| Failed download action | Keep files | Don't delete potentially recoverable data |
| File collision | Rename (add number) | Never lose data silently |
| Nested extraction depth | 2 levels | Handle common archive-in-archive |
| Deobfuscation | Enabled | Most users want readable names |
| Duplicate detection | Warn only | Alert but don't block |
| Try empty password | Yes | Common for public releases |
| Delete samples | Yes | Usually unwanted |
| Disk space check | Enabled, 1GB buffer | Prevent failed extractions |
| Retry attempts | 5 with exponential backoff | Resilient to transient failures |
| Pipeline depth | 10 articles per connection | Reduces round-trip latency overhead |
| API bind address | 127.0.0.1:6789 | Localhost only for security |
| API authentication | None | Easy local development |
| CORS | Enabled for all origins | Easy frontend development |
| Swagger UI | Enabled | Self-documenting API |
| Rate limiting | Disabled | Trust local network |
For a complete configuration example with all options, see Configuration Guide.
Documentation
| Topic | Link |
|---|---|
| Getting Started | docs/getting-started.md |
| Configuration | docs/configuration.md |
| REST API Reference | docs/api-reference.md |
| Architecture | docs/architecture.md |
| Post-Processing | docs/post-processing.md |
| Contributing | docs/contributing.md |
| Manual Testing | tests/manual/ |
| API Documentation | Run cargo doc --open for inline Rustdoc |
Interactive API docs are available at /swagger-ui when the API server is running.
Known Issues & Limitations
- PAR2 repair not yet implemented in nntp-rs - Verification works, repair planned
- Archive extraction requires external tools - unrar and 7z must be in PATH for RAR/7z support
- No Windows testing yet - Primarily developed and tested on Linux/macOS
Contributing
Contributions are welcome! Please see docs/contributing.md for development guidelines and workflow.
Quick start:
# Create feature branch
# Make changes and test
# Commit with descriptive message
# Push and create PR
License
Licensed under either of:
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
at your option.
Acknowledgments
- The Rust community for excellent libraries and tooling
- Contributors to nntp-rs for NNTP protocol implementation
Support
- Issues: https://github.com/jvz-devx/usenet-dl/issues
- Discussions: https://github.com/jvz-devx/usenet-dl/discussions
- Documentation: Run
cargo doc --openor visit https://docs.rs/usenet-dl
Built with Rust