1mod config;
8mod download;
9mod advanced_download;
10mod progress;
11mod utils;
12mod optimization;
13mod ftp;
14mod sftp;
15mod torrent;
16
17pub use crate::config::{Config, ProxyConfig, ProxyType, OptimizationConfig, TorrentConfig, FtpConfig, SftpConfig};
19pub use crate::optimization::Optimizer;
20pub use crate::progress::create_progress_bar;
21
22pub struct KGet {
24 config: Config,
25}
26
27impl KGet {
28 pub fn new() -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
30 let config = Config::load()?;
31 Ok(Self { config })
32 }
33
34 pub fn with_config(config: Config) -> Self {
36 Self { config }
37 }
38
39 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 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 let runtime = tokio::runtime::Runtime::new()?;
81 return runtime.block_on(downloader.download());
82 } else {
83 return download::download(url, quiet_mode, output_path, self.config.proxy.clone(), optimizer);
85 }
86 }
87
88 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 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 pub fn get_config(&self) -> &Config {
111 &self.config
112 }
113
114 pub fn set_config(&mut self, config: Config) {
116 self.config = config;
117 }
118}
119
120pub type ProgressCallback = Box<dyn Fn(u64, u64, f64) -> () + Send + Sync>;
122
123pub 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
142pub mod simple {
144 use super::*;
145
146 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 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}