kget/
lib.rs

1//! KGet - A powerful download library for Rust
2//!
3//! `kget` provides robust downloading capabilities including HTTP/HTTPS,
4//! FTP, SFTP, and torrent downloads with progress tracking, proxy support,
5//! and various optimizations.
6
7mod config;
8mod download;
9mod advanced_download;
10mod progress;
11mod utils;
12mod optimization;
13mod ftp;
14mod sftp;
15mod torrent;
16
17// Re-export public API
18pub use crate::config::{Config, ProxyConfig, ProxyType, OptimizationConfig, TorrentConfig, FtpConfig, SftpConfig};
19pub use crate::optimization::Optimizer;
20pub use crate::progress::create_progress_bar;
21
22/// Main download client for the KGet library
23pub struct KGet {
24    config: Config,
25}
26
27impl KGet {
28    /// Create a new KGet client with default configuration
29    pub fn new() -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
30        let config = Config::load()?;
31        Ok(Self { config })
32    }
33
34    /// Create a new KGet client with custom configuration
35    pub fn with_config(config: Config) -> Self {
36        Self { config }
37    }
38
39    /// Download a file from a URL to a local path
40    pub fn download(
41        &self,
42        url: &str,
43        output_path: Option<String>,
44        quiet_mode: bool,
45    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
46        // Create optimizer from config
47        let optimizer = Optimizer::new(self.config.optimization.clone());
48
49        if url.starts_with("ftp://") {
50            use crate::ftp::FtpDownloader;
51            let downloader = FtpDownloader::new(
52                url.to_string(), 
53                output_path.unwrap_or_else(|| crate::utils::get_filename_from_url_or_default(url, "ftp_output")), 
54                quiet_mode, 
55                self.config.proxy.clone(),
56                optimizer,
57            );
58            return downloader.download();
59        } else if url.starts_with("sftp://") {
60            use crate::sftp::SftpDownloader;
61            let downloader = SftpDownloader::new(
62                url.to_string(),
63                output_path.unwrap_or_else(|| crate::utils::get_filename_from_url_or_default(url, "sftp_output")),
64                quiet_mode,
65                self.config.proxy.clone(),
66                optimizer,
67            );
68            return downloader.download();
69        } else if url.starts_with("magnet:?") {
70            use crate::torrent::TorrentDownloader;
71            let downloader = TorrentDownloader::new(
72                url.to_string(),
73                output_path.unwrap_or_else(|| "torrent_output".to_string()),
74                quiet_mode,
75                self.config.proxy.clone(),
76                optimizer,
77            );
78            
79            // Create tokio runtime for async torrent downloads
80            let runtime = tokio::runtime::Runtime::new()?;
81            return runtime.block_on(downloader.download());
82        } else {
83            // Regular HTTP/HTTPS download
84            return download::download(url, quiet_mode, output_path, self.config.proxy.clone(), optimizer);
85        }
86    }
87
88    /// Advanced download with parallel chunks and resumable capability
89    pub fn advanced_download(
90        &self,
91        url: &str,
92        output_path: Option<String>,
93        quiet_mode: bool,
94    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
95        let optimizer = Optimizer::new(self.config.optimization.clone());
96        
97        // Use the existing advanced_download implementation
98        let downloader = crate::advanced_download::AdvancedDownloader::new(
99            url.to_string(),
100            output_path.unwrap_or_else(|| crate::utils::get_filename_from_url_or_default(url, "advanced_output")),
101            quiet_mode,
102            self.config.proxy.clone(),
103            optimizer,
104        );
105        
106        downloader.download()
107    }
108
109    /// Get current configuration
110    pub fn get_config(&self) -> &Config {
111        &self.config
112    }
113    
114    /// Update configuration
115    pub fn set_config(&mut self, config: Config) {
116        self.config = config;
117    }
118}
119
120/// Custom progress callback type for integration with other libraries
121pub type ProgressCallback = Box<dyn Fn(u64, u64, f64) -> () + Send + Sync>;
122
123/// Download options for fine-tuning the download process
124pub struct DownloadOptions {
125    pub quiet_mode: bool,
126    pub retry_count: Option<u32>,
127    pub retry_delay: Option<std::time::Duration>,
128    pub progress_callback: Option<ProgressCallback>,
129}
130
131impl Default for DownloadOptions {
132    fn default() -> Self {
133        Self {
134            quiet_mode: false,
135            retry_count: Some(3),
136            retry_delay: Some(std::time::Duration::from_secs(2)),
137            progress_callback: None,
138        }
139    }
140}
141
142/// Simplified API for quick downloads without creating a KelpsGet instance
143pub mod simple {
144    use super::*;
145
146    /// Download a file with minimal configuration
147    pub fn download(
148        url: &str, 
149        output_path: Option<&str>
150    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
151        let client = KGet::new()?;
152        client.download(
153            url,
154            output_path.map(|s| s.to_string()),
155            false
156        )
157    }
158
159    /// Download a file with custom options
160    pub fn download_with_options(
161        url: &str, 
162        output_path: Option<&str>,
163        options: DownloadOptions
164    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
165        let client = KGet::new()?;
166
167       
168        
169        client.download(
170            url,
171            output_path.map(|s| s.to_string()),
172            options.quiet_mode
173        )
174    }
175}