kget/
config.rs

1use serde::{Deserialize, Serialize};
2use std::path::PathBuf;
3use std::fs;
4use std::io;
5use dirs::config_dir;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct ProxyConfig {
9    pub enabled: bool,
10    pub url: Option<String>,
11    pub username: Option<String>,
12    pub password: Option<String>,
13    pub proxy_type: ProxyType,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub enum ProxyType {
18    Http,
19    Https,
20    Socks5,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct OptimizationConfig {
25    pub compression: bool,
26    pub compression_level: u8,
27    pub cache_enabled: bool,
28    pub cache_dir: String,
29    pub speed_limit: Option<u64>,
30    pub max_connections: usize,
31}
32
33// Function to provide the default value for max_peer_connections
34fn default_torrent_max_peer_connections() -> u32 {
35     50
36}
37
38// Function to provide the default value for max_upload_slots
39fn default_torrent_max_upload_slots() -> u32 {
40    4 
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct TorrentConfig {
45    pub enabled: bool,
46    pub download_dir: Option<String>,
47    pub max_peers: usize,
48    pub max_seeds: usize,
49    pub port: Option<u16>,
50    pub dht_enabled: bool,
51    #[serde(default = "default_torrent_max_peer_connections")]
52    pub max_peer_connections: u32,
53    #[serde(default = "default_torrent_max_upload_slots")]
54    pub max_upload_slots: u32,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct FtpConfig {
59    pub passive_mode: bool,
60    pub default_port: u16,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct SftpConfig {
65    pub default_port: u16,
66    pub key_path: Option<String>,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct Config {
71    pub proxy: ProxyConfig,
72    pub optimization: OptimizationConfig,
73    pub torrent: TorrentConfig,
74    pub ftp: FtpConfig,
75    pub sftp: SftpConfig,
76}
77
78impl Config {
79    pub fn load() -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
80        let config_path = Self::get_config_path()?;
81        
82        if !config_path.exists() {
83            // If the config file does not exist, return default config
84            return Ok(Self::default());
85        }
86        
87        let config_str = fs::read_to_string(config_path)?;
88        // The error occurs here if the existing JSON file does not have the field.
89        let config: Config = serde_json::from_str(&config_str)?;
90
91        Ok(config)
92    }
93    
94    pub fn save(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
95        let config_path = Self::get_config_path()?;
96
97        // Create config directory if it doesn't exist
98        if let Some(parent) = config_path.parent() {
99            fs::create_dir_all(parent)?;
100        }
101        
102        let config_str = serde_json::to_string_pretty(self)?;
103        fs::write(config_path, config_str)?;
104        
105        Ok(())
106    }
107    
108    fn get_config_path() -> Result<PathBuf, io::Error> {
109        let mut path = config_dir().ok_or_else(|| {
110            io::Error::new(io::ErrorKind::NotFound, "Not able to find config directory")
111        })?;
112        
113        path.push("kget");
114        path.push("config.json");
115        
116        Ok(path)
117    }
118}
119
120impl Default for Config {
121    fn default() -> Self {
122        Self {
123            proxy: ProxyConfig {
124                enabled: false,
125                url: None,
126                username: None,
127                password: None,
128                proxy_type: ProxyType::Http,
129            },
130            optimization: OptimizationConfig {
131                compression: true,
132                compression_level: 6,
133                cache_enabled: true,
134                cache_dir: "~/.cache/kget".to_string(),
135                speed_limit: None,
136                max_connections: 4,
137            },
138            torrent: TorrentConfig {
139                enabled: false,
140                download_dir: None,
141                max_peers: 50,
142                max_seeds: 25,
143                port: None,
144                dht_enabled: true,
145                max_peer_connections: default_torrent_max_peer_connections(),
146                max_upload_slots: default_torrent_max_upload_slots(),
147            },
148            ftp: FtpConfig {
149                passive_mode: true,
150                default_port: 21,
151            },
152            sftp: SftpConfig {
153                default_port: 22,
154                key_path: None,
155            },
156        }
157    }
158}