diff --git a/Cargo.lock b/Cargo.lock index d44156212221b75cb9613f0d254233b8998a08c3..8bf9af0108b3114cf01fb4f630e22d750f3d4cc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -840,6 +840,27 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -1885,6 +1906,7 @@ dependencies = [ "anyhow", "base64", "chrono", + "dirs", "is-wsl", "libc", "log", @@ -2440,6 +2462,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "orbclient" version = "0.3.46" @@ -2845,6 +2873,17 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall 0.2.16", + "thiserror", +] + [[package]] name = "regex" version = "1.10.2" diff --git a/Cargo.toml b/Cargo.toml index 0fb8bdc5130390eebc53be440ac32cc596191afe..43d99fff1db64252f6ea22d0d01fe4bc1d8a336d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,6 +61,7 @@ chrono = { version = "0.4", default-features = false, features = ["clock"] } sha256 = { version = "1", default-features = false, features = ["async"] } base64 = "*" anyhow = "1" +dirs = "5" # Data Structures hashbrown = { version = "0.14", features = ["serde"] } diff --git a/lektor_nkdb/src/lib.rs b/lektor_nkdb/src/lib.rs index f911de72f5dcab7f04712055be95e819075e7366..526808a1288cba8228e68584c9d4b9d3a373a1ee 100644 --- a/lektor_nkdb/src/lib.rs +++ b/lektor_nkdb/src/lib.rs @@ -11,7 +11,7 @@ pub use crate::{ }; use crate::{database::*, queue::*, search::*}; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context, Result}; use hashbrown::HashMap; use lektor_utils::{log, pushvec::*}; use playlist::Playlists; @@ -59,7 +59,9 @@ impl AsRef<str> for PlayState { impl<Storage: DatabaseStorage> Database<Storage> { /// Create a new database with the correspondig prefix. pub async fn new(prefix: impl Into<Storage::Prefix>) -> Result<Self> { - let storage = Storage::load_from_prefix(prefix.into()).await?; + let storage = Storage::load_from_prefix(prefix.into()) + .await + .with_context(|| "failed to load database storage")?; log::info!("load the last epoch and populate the pool without factorization"); let epochs: PushVec<Epoch> = Default::default(); @@ -75,7 +77,10 @@ impl<Storage: DatabaseStorage> Database<Storage> { .await; log::info!("fatcorize content in the last_epoch and in the playlists"); - let mut playlists = storage.read_playlists().await?; + let mut playlists = storage + .read_playlists() + .await + .with_context(|| "failed to read playlists")?; pool.factorize_epoch_data(last_epoch.content().data_mut()); playlists .iter_mut() diff --git a/lektor_nkdb/src/storage/disk_storage.rs b/lektor_nkdb/src/storage/disk_storage.rs index 8d3d7012054bcbd16814970707919969f1294181..6dc408fda4db841bfd123ef6f68c8957984c67cd 100644 --- a/lektor_nkdb/src/storage/disk_storage.rs +++ b/lektor_nkdb/src/storage/disk_storage.rs @@ -271,7 +271,9 @@ impl DatabaseStorage for DatabaseDiskStorage { let folder = prefix.join(folder); match create_dir_all(&folder).await { Err(err) if err.kind() != std::io::ErrorKind::AlreadyExists => { - return Err(err).with_context(|| "failed to create folder") + return Err(err).with_context(|| { + format!("failed to create folder {}", folder.to_string_lossy()) + }) } _ => {} } diff --git a/lektor_utils/Cargo.toml b/lektor_utils/Cargo.toml index c46b0c9de7c8160261ba98707e60ee2dcd4e1958..a0c54bbe272107b05e515fa6b1221323a7939009 100644 --- a/lektor_utils/Cargo.toml +++ b/lektor_utils/Cargo.toml @@ -18,6 +18,7 @@ doctest = false [dependencies] log.workspace = true toml.workspace = true +dirs.workspace = true serde.workspace = true tokio.workspace = true anyhow.workspace = true diff --git a/lektor_utils/src/config/base.rs b/lektor_utils/src/config/base.rs index a7c7d6c0afdaa7f454beb66c6b4d4005c5bcadb1..8e95d67ec8c9f31c3ed3cc9636f561d075d374f4 100644 --- a/lektor_utils/src/config/base.rs +++ b/lektor_utils/src/config/base.rs @@ -102,7 +102,7 @@ impl Default for LektorRepoConfig { impl Default for LektorDatabaseConfig { fn default() -> Self { Self { - folder: PathBuf::from("/home/kara"), + folder: crate::user_home_directory().join("kara"), autoclear: true, save_history: false, } diff --git a/lektor_utils/src/lib.rs b/lektor_utils/src/lib.rs index 07bd53e140c1969479e636539316fdecade2872d..7ba1476ec80e3e574aca2879e946d5693e2030dc 100644 --- a/lektor_utils/src/lib.rs +++ b/lektor_utils/src/lib.rs @@ -15,22 +15,9 @@ pub mod pushvec; include!(concat!(env!("OUT_DIR"), "/commons_build_infos.rs")); /// Returns the home folder of the user. If no home folder is found log the -/// error and panic. This function check in order the following env variables to -/// determine the home folder: -/// 1. HOME -/// 2. HOMEPATH -/// 3. USERPROFILE +/// error and panic. pub fn user_home_directory() -> std::path::PathBuf { - use std::env::var; - std::path::PathBuf::from(if let Ok(home) = var("HOME") { - home - } else if let Ok(home) = var("HOMEPATH") { - home - } else if let Ok(home) = var("USERPROFILE") { - home - } else { - panic!("failed to find a home folder for the user...") - }) + dirs::home_dir().expect("failed to find a home folder for the user...") } /// Returns the config folder for the user. If neither HOME, HOMEPATH, @@ -39,7 +26,12 @@ pub fn user_home_directory() -> std::path::PathBuf { /// behaviour on unix systems. pub fn user_config_directory(app: impl AsRef<str>) -> std::path::PathBuf { let folder = user_home_directory().join(".config").join(app.as_ref()); - std::fs::create_dir_all(&folder).expect("failed to create config folder for application"); + std::fs::create_dir_all(&folder).unwrap_or_else(|err| { + panic!( + "failed to create config folder for application {}: {err}", + folder.to_string_lossy() + ) + }); folder } diff --git a/lektord/c/CMakeLists.txt b/lektord/c/CMakeLists.txt index ec9b6d5e075eed1eb8981a5083ed8a9e338c68d2..81169171958944a81ef12543f5527b4f8f3ceaee 100644 --- a/lektord/c/CMakeLists.txt +++ b/lektord/c/CMakeLists.txt @@ -85,7 +85,7 @@ set(GNU_C_FLAGS if(WIN32) # list(PREPEND CMAKE_FIND_LIBRARY_SUFFIXES .a .dll.a .lib) - set(Qt6_USE_STATIC_LIBS ON) + set(Qt6_USE_STATIC_LIBS ON) set(Qt6_USE_STATIC_RUNTIME ON) endif() diff --git a/lektord/src/app.rs b/lektord/src/app.rs index a8d70b5e14985a45d071c2435d027217b5f85250..a1f76f1717db5ab439ce389e81923a084a1ee1d7 100644 --- a/lektord/src/app.rs +++ b/lektord/src/app.rs @@ -3,7 +3,7 @@ #![forbid(unsafe_code)] use crate::{routes, LektorConfig}; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context, Result}; use axum::{ http::{Request, StatusCode}, middleware::Next, @@ -58,7 +58,9 @@ pub async fn app(config: LektorConfig) -> Result<(Router, tokio::sync::oneshot:: } let (sender, receiver) = tokio::sync::oneshot::channel(); - let state = LektorState::new(config, sender).await?; + let state = LektorState::new(config, sender) + .await + .with_context(|| "failed to build lektord state")?; let route = router! { "/" -> get: routes::root // Control the playback @@ -173,19 +175,23 @@ impl LektorState { false => LektorUser::User(user.user.into(), user.token.into()), }); let ptr = LektorStatePtr::from(Arc::new(Self { - database: Database::<DatabaseDiskStorage>::new(folder).await?, + database: Database::<DatabaseDiskStorage>::new(folder) + .await + .with_context(|| "failed to build database")?, repo: Repo::new(repo), users: users.collect(), mpris: Default::default(), shutdown: RwLock::new(Some(shutdown)), })); if config.mpris { - *ptr.mpris.write().await = Some( + *ptr.mpris.write().await = lektor_mpris::MPRISAdapter::builder("lektord", LektorStateWeakPtr::from(&ptr)) .desktop_entry("Lektord") .try_build() - .await?, - ); + .await + .with_context(|| "failed to build mpris server, run with no mpris") + .map_err(|err| log::error!("{err}")) + .ok(); } crate::c_wrapper::init_player_module(ptr.clone(), player)?; Ok(ptr)