diff --git a/crates/librqbit/src/session.rs b/crates/librqbit/src/session.rs index b57b4073..70afda01 100644 --- a/crates/librqbit/src/session.rs +++ b/crates/librqbit/src/session.rs @@ -334,6 +334,13 @@ pub enum SessionPersistenceConfig { Json { folder: Option }, } +impl SessionPersistenceConfig { + pub fn default_json_persistence_folder() -> anyhow::Result { + let dir = get_configuration_directory("session")?; + Ok(dir.data_dir().to_owned()) + } +} + #[derive(Default)] pub struct SessionOptions { /// Turn on to disable DHT. @@ -475,16 +482,11 @@ impl Session { async fn persistence_factory( opts: &SessionOptions, ) -> anyhow::Result> { - pub fn default_persistence_folder() -> anyhow::Result { - let dir = get_configuration_directory("session")?; - Ok(dir.data_dir().to_owned()) - } - match &opts.persistence { Some(SessionPersistenceConfig::Json { folder }) => { let folder = match folder.as_ref() { Some(f) => f.clone(), - None => default_persistence_folder()?, + None => SessionPersistenceConfig::default_json_persistence_folder()?, }; Ok(Some(Box::new( diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index 14f6de26..cc2ad56e 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -1847,6 +1847,7 @@ version = "6.0.0" dependencies = [ "anyhow", "async-stream", + "async-trait", "axum", "backoff", "base64 0.21.7", @@ -1897,6 +1898,7 @@ name = "librqbit-bencode" version = "2.2.3" dependencies = [ "anyhow", + "bytes", "librqbit-buffers", "librqbit-clone-to-owned", "librqbit-sha1-wrapper", @@ -1907,6 +1909,7 @@ dependencies = [ name = "librqbit-buffers" version = "3.0.1" dependencies = [ + "bytes", "librqbit-clone-to-owned", "serde", ] @@ -1914,12 +1917,16 @@ dependencies = [ [[package]] name = "librqbit-clone-to-owned" version = "2.2.1" +dependencies = [ + "bytes", +] [[package]] name = "librqbit-core" version = "3.9.0" dependencies = [ "anyhow", + "bytes", "data-encoding", "directories", "hex 0.4.3", @@ -1942,6 +1949,7 @@ version = "5.0.4" dependencies = [ "anyhow", "backoff", + "bytes", "chrono", "dashmap", "futures", @@ -1969,6 +1977,7 @@ dependencies = [ "bincode", "bitvec", "byteorder", + "bytes", "librqbit-bencode", "librqbit-buffers", "librqbit-clone-to-owned", diff --git a/desktop/src-tauri/src/config.rs b/desktop/src-tauri/src/config.rs index cef1abab..17058cd9 100644 --- a/desktop/src-tauri/src/config.rs +++ b/desktop/src-tauri/src/config.rs @@ -1,10 +1,10 @@ use std::{ net::{Ipv4Addr, SocketAddr, SocketAddrV4}, - path::PathBuf, + path::{Path, PathBuf}, time::Duration, }; -use librqbit::{dht::PersistentDht, Session}; +use librqbit::dht::PersistentDht; use serde::{Deserialize, Serialize}; use serde_with::serde_as; @@ -49,14 +49,35 @@ impl Default for RqbitDesktopConfigTcpListen { #[serde(default)] pub struct RqbitDesktopConfigPersistence { pub disable: bool, + + #[serde(default)] + pub folder: PathBuf, + + /// Deprecated, but keeping for backwards compat for serialized / deserialized config. + #[serde(default)] pub filename: PathBuf, } +impl RqbitDesktopConfigPersistence { + pub(crate) fn fix_backwards_compat(&mut self) { + if self.folder != Path::new("") { + return; + } + if self.filename != Path::new("") { + if let Some(parent) = self.filename.parent() { + self.folder = parent.to_owned(); + } + } + } +} + impl Default for RqbitDesktopConfigPersistence { fn default() -> Self { + let folder = librqbit::SessionPersistenceConfig::default_json_persistence_folder().unwrap(); Self { disable: false, - filename: Session::default_persistence_filename().unwrap(), + folder, + filename: PathBuf::new(), } } } diff --git a/desktop/src-tauri/src/main.rs b/desktop/src-tauri/src/main.rs index 2b03d637..36f6b531 100644 --- a/desktop/src-tauri/src/main.rs +++ b/desktop/src-tauri/src/main.rs @@ -21,6 +21,7 @@ use librqbit::{ dht::PersistentDhtConfig, tracing_subscriber_config_utils::{init_logging, InitLoggingOptions, InitLoggingResult}, AddTorrent, AddTorrentOptions, Api, ApiError, PeerConnectionOptions, Session, SessionOptions, + SessionPersistenceConfig, }; use parking_lot::RwLock; use serde::Serialize; @@ -42,7 +43,9 @@ struct State { fn read_config(path: &str) -> anyhow::Result { let rdr = BufReader::new(File::open(path)?); - Ok(serde_json::from_reader(rdr)?) + let mut config: RqbitDesktopConfig = serde_json::from_reader(rdr)?; + config.persistence.fix_backwards_compat(); + Ok(config) } fn write_config(path: &str, config: &RqbitDesktopConfig) -> anyhow::Result<()> { @@ -65,6 +68,17 @@ async fn api_from_config( init_logging: &InitLoggingResult, config: &RqbitDesktopConfig, ) -> anyhow::Result { + let persistence = if config.persistence.disable { + None + } else { + Some(SessionPersistenceConfig::Json { + folder: if config.persistence.folder == Path::new("") { + None + } else { + Some(config.persistence.folder.clone()) + }, + }) + }; let session = Session::new_with_opts( config.default_download_location.clone(), SessionOptions { @@ -74,8 +88,7 @@ async fn api_from_config( config_filename: Some(config.dht.persistence_filename.clone()), ..Default::default() }), - persistence: !config.persistence.disable, - persistence_filename: Some(config.persistence.filename.clone()), + persistence, peer_opts: Some(PeerConnectionOptions { connect_timeout: Some(config.peer_opts.connect_timeout), read_write_timeout: Some(config.peer_opts.read_write_timeout), @@ -266,7 +279,7 @@ async fn torrent_action_delete( state: tauri::State<'_, State>, id: usize, ) -> Result { - state.api()?.api_torrent_action_delete(id) + state.api()?.api_torrent_action_delete(id).await } #[tauri::command] @@ -274,7 +287,7 @@ async fn torrent_action_pause( state: tauri::State<'_, State>, id: usize, ) -> Result { - state.api()?.api_torrent_action_pause(id) + state.api()?.api_torrent_action_pause(id).await } #[tauri::command] @@ -282,7 +295,7 @@ async fn torrent_action_forget( state: tauri::State<'_, State>, id: usize, ) -> Result { - state.api()?.api_torrent_action_forget(id) + state.api()?.api_torrent_action_forget(id).await } #[tauri::command] @@ -290,7 +303,7 @@ async fn torrent_action_start( state: tauri::State<'_, State>, id: usize, ) -> Result { - state.api()?.api_torrent_action_start(id) + state.api()?.api_torrent_action_start(id).await } #[tauri::command] @@ -302,6 +315,7 @@ async fn torrent_action_configure( state .api()? .api_torrent_action_update_only_files(id, &only_files.into_iter().collect()) + .await } #[tauri::command] diff --git a/desktop/src/configuration.tsx b/desktop/src/configuration.tsx index a0157a50..9936b5b0 100644 --- a/desktop/src/configuration.tsx +++ b/desktop/src/configuration.tsx @@ -16,7 +16,7 @@ interface RqbitDesktopConfigTcpListen { interface RqbitDesktopConfigPersistence { disable: boolean; - filename: PathLike; + folder: PathLike; } interface RqbitDesktopConfigPeerOpts { diff --git a/desktop/src/configure.tsx b/desktop/src/configure.tsx index 55a1012b..acd225ec 100644 --- a/desktop/src/configure.tsx +++ b/desktop/src/configure.tsx @@ -130,7 +130,7 @@ export const ConfigModal: React.FC<{ }; const handleToggleChange: React.ChangeEventHandler = ( - e, + e ) => { const name: string = e.target.name; const [mainField, subField] = name.split(".", 2); @@ -166,7 +166,7 @@ export const ConfigModal: React.FC<{ text: "Error saving configuration", details: e, }); - }, + } ); }; @@ -292,10 +292,10 @@ export const ConfigModal: React.FC<{ />