Update desktop app to support new persistence config
This commit is contained in:
parent
d77d96bd48
commit
275b3b0185
6 changed files with 68 additions and 22 deletions
|
|
@ -334,6 +334,13 @@ pub enum SessionPersistenceConfig {
|
||||||
Json { folder: Option<PathBuf> },
|
Json { folder: Option<PathBuf> },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SessionPersistenceConfig {
|
||||||
|
pub fn default_json_persistence_folder() -> anyhow::Result<PathBuf> {
|
||||||
|
let dir = get_configuration_directory("session")?;
|
||||||
|
Ok(dir.data_dir().to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct SessionOptions {
|
pub struct SessionOptions {
|
||||||
/// Turn on to disable DHT.
|
/// Turn on to disable DHT.
|
||||||
|
|
@ -475,16 +482,11 @@ impl Session {
|
||||||
async fn persistence_factory(
|
async fn persistence_factory(
|
||||||
opts: &SessionOptions,
|
opts: &SessionOptions,
|
||||||
) -> anyhow::Result<Option<BoxSessionPersistenceStore>> {
|
) -> anyhow::Result<Option<BoxSessionPersistenceStore>> {
|
||||||
pub fn default_persistence_folder() -> anyhow::Result<PathBuf> {
|
|
||||||
let dir = get_configuration_directory("session")?;
|
|
||||||
Ok(dir.data_dir().to_owned())
|
|
||||||
}
|
|
||||||
|
|
||||||
match &opts.persistence {
|
match &opts.persistence {
|
||||||
Some(SessionPersistenceConfig::Json { folder }) => {
|
Some(SessionPersistenceConfig::Json { folder }) => {
|
||||||
let folder = match folder.as_ref() {
|
let folder = match folder.as_ref() {
|
||||||
Some(f) => f.clone(),
|
Some(f) => f.clone(),
|
||||||
None => default_persistence_folder()?,
|
None => SessionPersistenceConfig::default_json_persistence_folder()?,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some(Box::new(
|
Ok(Some(Box::new(
|
||||||
|
|
|
||||||
9
desktop/src-tauri/Cargo.lock
generated
9
desktop/src-tauri/Cargo.lock
generated
|
|
@ -1847,6 +1847,7 @@ version = "6.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-stream",
|
"async-stream",
|
||||||
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
"backoff",
|
"backoff",
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
|
|
@ -1897,6 +1898,7 @@ name = "librqbit-bencode"
|
||||||
version = "2.2.3"
|
version = "2.2.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"bytes",
|
||||||
"librqbit-buffers",
|
"librqbit-buffers",
|
||||||
"librqbit-clone-to-owned",
|
"librqbit-clone-to-owned",
|
||||||
"librqbit-sha1-wrapper",
|
"librqbit-sha1-wrapper",
|
||||||
|
|
@ -1907,6 +1909,7 @@ dependencies = [
|
||||||
name = "librqbit-buffers"
|
name = "librqbit-buffers"
|
||||||
version = "3.0.1"
|
version = "3.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
"librqbit-clone-to-owned",
|
"librqbit-clone-to-owned",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
@ -1914,12 +1917,16 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librqbit-clone-to-owned"
|
name = "librqbit-clone-to-owned"
|
||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "librqbit-core"
|
name = "librqbit-core"
|
||||||
version = "3.9.0"
|
version = "3.9.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"bytes",
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
"directories",
|
"directories",
|
||||||
"hex 0.4.3",
|
"hex 0.4.3",
|
||||||
|
|
@ -1942,6 +1949,7 @@ version = "5.0.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"backoff",
|
"backoff",
|
||||||
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"futures",
|
"futures",
|
||||||
|
|
@ -1969,6 +1977,7 @@ dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"bitvec",
|
"bitvec",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
"librqbit-bencode",
|
"librqbit-bencode",
|
||||||
"librqbit-buffers",
|
"librqbit-buffers",
|
||||||
"librqbit-clone-to-owned",
|
"librqbit-clone-to-owned",
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
use std::{
|
use std::{
|
||||||
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
|
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
|
||||||
path::PathBuf,
|
path::{Path, PathBuf},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use librqbit::{dht::PersistentDht, Session};
|
use librqbit::dht::PersistentDht;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_with::serde_as;
|
use serde_with::serde_as;
|
||||||
|
|
||||||
|
|
@ -49,14 +49,35 @@ impl Default for RqbitDesktopConfigTcpListen {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct RqbitDesktopConfigPersistence {
|
pub struct RqbitDesktopConfigPersistence {
|
||||||
pub disable: bool,
|
pub disable: bool,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub folder: PathBuf,
|
||||||
|
|
||||||
|
/// Deprecated, but keeping for backwards compat for serialized / deserialized config.
|
||||||
|
#[serde(default)]
|
||||||
pub filename: PathBuf,
|
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 {
|
impl Default for RqbitDesktopConfigPersistence {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
let folder = librqbit::SessionPersistenceConfig::default_json_persistence_folder().unwrap();
|
||||||
Self {
|
Self {
|
||||||
disable: false,
|
disable: false,
|
||||||
filename: Session::default_persistence_filename().unwrap(),
|
folder,
|
||||||
|
filename: PathBuf::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ use librqbit::{
|
||||||
dht::PersistentDhtConfig,
|
dht::PersistentDhtConfig,
|
||||||
tracing_subscriber_config_utils::{init_logging, InitLoggingOptions, InitLoggingResult},
|
tracing_subscriber_config_utils::{init_logging, InitLoggingOptions, InitLoggingResult},
|
||||||
AddTorrent, AddTorrentOptions, Api, ApiError, PeerConnectionOptions, Session, SessionOptions,
|
AddTorrent, AddTorrentOptions, Api, ApiError, PeerConnectionOptions, Session, SessionOptions,
|
||||||
|
SessionPersistenceConfig,
|
||||||
};
|
};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
@ -42,7 +43,9 @@ struct State {
|
||||||
|
|
||||||
fn read_config(path: &str) -> anyhow::Result<RqbitDesktopConfig> {
|
fn read_config(path: &str) -> anyhow::Result<RqbitDesktopConfig> {
|
||||||
let rdr = BufReader::new(File::open(path)?);
|
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<()> {
|
fn write_config(path: &str, config: &RqbitDesktopConfig) -> anyhow::Result<()> {
|
||||||
|
|
@ -65,6 +68,17 @@ async fn api_from_config(
|
||||||
init_logging: &InitLoggingResult,
|
init_logging: &InitLoggingResult,
|
||||||
config: &RqbitDesktopConfig,
|
config: &RqbitDesktopConfig,
|
||||||
) -> anyhow::Result<Api> {
|
) -> anyhow::Result<Api> {
|
||||||
|
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(
|
let session = Session::new_with_opts(
|
||||||
config.default_download_location.clone(),
|
config.default_download_location.clone(),
|
||||||
SessionOptions {
|
SessionOptions {
|
||||||
|
|
@ -74,8 +88,7 @@ async fn api_from_config(
|
||||||
config_filename: Some(config.dht.persistence_filename.clone()),
|
config_filename: Some(config.dht.persistence_filename.clone()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
persistence: !config.persistence.disable,
|
persistence,
|
||||||
persistence_filename: Some(config.persistence.filename.clone()),
|
|
||||||
peer_opts: Some(PeerConnectionOptions {
|
peer_opts: Some(PeerConnectionOptions {
|
||||||
connect_timeout: Some(config.peer_opts.connect_timeout),
|
connect_timeout: Some(config.peer_opts.connect_timeout),
|
||||||
read_write_timeout: Some(config.peer_opts.read_write_timeout),
|
read_write_timeout: Some(config.peer_opts.read_write_timeout),
|
||||||
|
|
@ -266,7 +279,7 @@ async fn torrent_action_delete(
|
||||||
state: tauri::State<'_, State>,
|
state: tauri::State<'_, State>,
|
||||||
id: usize,
|
id: usize,
|
||||||
) -> Result<EmptyJsonResponse, ApiError> {
|
) -> Result<EmptyJsonResponse, ApiError> {
|
||||||
state.api()?.api_torrent_action_delete(id)
|
state.api()?.api_torrent_action_delete(id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|
@ -274,7 +287,7 @@ async fn torrent_action_pause(
|
||||||
state: tauri::State<'_, State>,
|
state: tauri::State<'_, State>,
|
||||||
id: usize,
|
id: usize,
|
||||||
) -> Result<EmptyJsonResponse, ApiError> {
|
) -> Result<EmptyJsonResponse, ApiError> {
|
||||||
state.api()?.api_torrent_action_pause(id)
|
state.api()?.api_torrent_action_pause(id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|
@ -282,7 +295,7 @@ async fn torrent_action_forget(
|
||||||
state: tauri::State<'_, State>,
|
state: tauri::State<'_, State>,
|
||||||
id: usize,
|
id: usize,
|
||||||
) -> Result<EmptyJsonResponse, ApiError> {
|
) -> Result<EmptyJsonResponse, ApiError> {
|
||||||
state.api()?.api_torrent_action_forget(id)
|
state.api()?.api_torrent_action_forget(id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|
@ -290,7 +303,7 @@ async fn torrent_action_start(
|
||||||
state: tauri::State<'_, State>,
|
state: tauri::State<'_, State>,
|
||||||
id: usize,
|
id: usize,
|
||||||
) -> Result<EmptyJsonResponse, ApiError> {
|
) -> Result<EmptyJsonResponse, ApiError> {
|
||||||
state.api()?.api_torrent_action_start(id)
|
state.api()?.api_torrent_action_start(id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|
@ -302,6 +315,7 @@ async fn torrent_action_configure(
|
||||||
state
|
state
|
||||||
.api()?
|
.api()?
|
||||||
.api_torrent_action_update_only_files(id, &only_files.into_iter().collect())
|
.api_torrent_action_update_only_files(id, &only_files.into_iter().collect())
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ interface RqbitDesktopConfigTcpListen {
|
||||||
|
|
||||||
interface RqbitDesktopConfigPersistence {
|
interface RqbitDesktopConfigPersistence {
|
||||||
disable: boolean;
|
disable: boolean;
|
||||||
filename: PathLike;
|
folder: PathLike;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RqbitDesktopConfigPeerOpts {
|
interface RqbitDesktopConfigPeerOpts {
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ export const ConfigModal: React.FC<{
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleToggleChange: React.ChangeEventHandler<HTMLInputElement> = (
|
const handleToggleChange: React.ChangeEventHandler<HTMLInputElement> = (
|
||||||
e,
|
e
|
||||||
) => {
|
) => {
|
||||||
const name: string = e.target.name;
|
const name: string = e.target.name;
|
||||||
const [mainField, subField] = name.split(".", 2);
|
const [mainField, subField] = name.split(".", 2);
|
||||||
|
|
@ -166,7 +166,7 @@ export const ConfigModal: React.FC<{
|
||||||
text: "Error saving configuration",
|
text: "Error saving configuration",
|
||||||
details: e,
|
details: e,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -292,10 +292,10 @@ export const ConfigModal: React.FC<{
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormInput
|
<FormInput
|
||||||
label="Persistence filename"
|
label="Persistence folder"
|
||||||
name="persistence.filename"
|
name="persistence.folder"
|
||||||
inputType="text"
|
inputType="text"
|
||||||
value={config.persistence.filename}
|
value={config.persistence.folder}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
disabled={config.persistence.disable}
|
disabled={config.persistence.disable}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue