From b79cfa3b3c15a5fefff4ebe2dad8ea68716295e7 Mon Sep 17 00:00:00 2001 From: Stridsvagn69420 Date: Sun, 4 Dec 2022 17:37:54 +0100 Subject: [PATCH] Artists live in central artists.json file now --- src/artist.rs | 47 +++++++++++++++++++++----------------------- src/config.rs | 9 ++++++++- src/lib.rs | 4 +++- src/server/mod.rs | 2 +- src/server/routes.rs | 10 ++++++---- 5 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/artist.rs b/src/artist.rs index 6856dc9..2cce581 100644 --- a/src/artist.rs +++ b/src/artist.rs @@ -1,12 +1,12 @@ use serde::{Serialize, Deserialize}; use uuid::Uuid; +use dirs::home_dir; use std::fmt::{Display, Result}; use std::cmp::PartialEq; use std::convert::From; -use std::path::{Path, PathBuf}; -use std::fs; -use std::io; -use super::Owner; +use std::path::Path; +use std::{fs, io, env}; +use super::{Owner, meta}; /// Artist /// @@ -39,35 +39,32 @@ impl Artist { } } - /// Load single .artists.json + /// Load artists.json /// - /// Loads a single `.artists.json` as a [Vec] of [Artist]s - pub fn load_artists(path: impl AsRef) -> io::Result> { + /// Loads a `artists.json` as a [Vec] of [Artist]s + pub fn load(path: impl AsRef) -> io::Result> { let rawdata = fs::read_to_string(path)?; Ok(serde_json::from_str(rawdata.as_str())?) } - /// Load multiple .artists.json + /// Cascade Loading /// - /// Loads multiple `.artists.json` as a combined [Vec] of [Artist]s - pub fn load_multiple_artists(paths: Vec>) -> io::Result> { - let mut res: Vec = Vec::new(); - for pth in paths { - let artst = Artist::load_artists(pth)?; - res.extend(artst); + /// Attempts to load a config file by: + /// 1. Provided [String] + /// 2. `CYRKENSIA_ARTISTS` environment variable + /// 3. `~/.config/cyrkensia/artists.json` file + pub fn load_cascade(cmdarg: &Option) -> io::Result> { + // Select extra path + let envvar = env::var(meta::ARTISTS_ENVVAR); + + // Read config from extra location + if let Some(path) = cmdarg.as_ref().or_else(|| envvar.as_ref().ok()) { + return Artist::load(path); } - Ok(res) - } - /// Read multiple folders' .artists.json - /// - /// Reads the .artists.json of multiple folders. Essentially like `load_multiple_artists`, but with `.artists.json` appended. - pub fn read_multiple(paths: &[String]) -> io::Result> { - let conv_paths: Vec = paths.iter() - .map(|x| Path::new(x).join(".artists.json")).collect(); - - // Read all artists - Artist::load_multiple_artists(conv_paths) + // Read with default path + let localpath = home_dir().unwrap_or_default().join(meta::ARTISTS_PATH); + Artist::load(localpath) } } diff --git a/src/config.rs b/src/config.rs index cb2ec10..30c7a67 100644 --- a/src/config.rs +++ b/src/config.rs @@ -41,9 +41,15 @@ pub struct Config { /// Note that the file must be a JSON of [Vec]<[Account](super::account::Account)>. pub htpasswd: Option, + /// Artists file + /// + /// The path to the central artists file, used for displaying an album's artists. + /// It will cascade load the file as described in [Artist](crate::Artist)'s `load_cascade()` function. + pub artists: Option, + /// Bind address /// - /// The IP address to bind to, e.g. `127.0.0.1`, `0.0.0.0:80` or a Unix socket (Unix only). + /// The IP address to bind to, e.g. `127.0.0.1`, `0.0.0.0:80` or a Unix Domain Socket (Unix only). pub bindaddr: String, /// Owners @@ -104,6 +110,7 @@ impl From for Config { icon: x.icon, htpasswd: None, bindaddr: "".to_string(), + artists: None, owners: x.owners, max_age: None } diff --git a/src/lib.rs b/src/lib.rs index aced3a6..06b9fdf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,7 @@ //! // Load the config file //! let config = Config::load_file("config.json").unwrap(); //! // Load the artists -//! let artists = Artist::read_multiple(&config.root).unwrap(); +//! let artists = Artist::load_cascade(&None).unwrap(); //! // Generate the corresponding Hostinfo //! let mut hostinfo = Hostinfo::generate(&config, &artists).unwrap(); //! ``` @@ -79,6 +79,8 @@ pub mod meta { pub const CONFIG_PATH: &str = concat!(".config/", env!("CARGO_PKG_NAME"), "/config.json"); pub const USERS_ENVVAR: &str = "CYRKENSIA_USERS"; pub const USERS_PATH: &str = concat!(".config/", env!("CARGO_PKG_NAME"), "/users.json"); + pub const ARTISTS_ENVVAR: &str = "CYRKENSIA_ARTISTS"; + pub const ARTISTS_PATH: &str = concat!(".config/", env!("CARGO_PKG_NAME"), "/artists.json"); } #[cfg(feature = "server")] diff --git a/src/server/mod.rs b/src/server/mod.rs index e176360..7c6b029 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -91,7 +91,7 @@ impl CyrkensiaState { // State with caching if cfg.max_age.is_some() { - let arts = Artist::read_multiple(&cfg.root)?; + let arts = Artist::load_cascade(&cfg.artists)?; let hostinfo = Hostinfo::generate(&cfg, &arts)?; return Ok(CyrkensiaState { last_updated: Mutex::new(Instant::now()), diff --git a/src/server/routes.rs b/src/server/routes.rs index 1776091..0e08e85 100644 --- a/src/server/routes.rs +++ b/src/server/routes.rs @@ -12,7 +12,7 @@ pub async fn hostinfo(data: web::Data) -> impl Responder { // Get config let Some(delay) = data.config.max_age else { // Ad hoch Hostinfo - let Ok(artists) = Artist::read_multiple(&data.config.root) else { + let Ok(artists) = Artist::load_cascade(&data.config.artists) else { return responses::server_500(Some("Failed to generate hostinfo")); }; let Ok(resp) = responses::hostinfo_json(&data.config, &artists) else { @@ -35,7 +35,7 @@ pub async fn hostinfo(data: web::Data) -> impl Responder { // Update Cache if expired if last_updated.elapsed().as_secs() >= delay { // Read updated artists - let Ok(new_artists) = Artist::read_multiple(&data.config.root) else { + let Ok(new_artists) = Artist::load_cascade(&data.config.artists) else { return responses::server_500(Some("Failed to update hostinfo")); }; @@ -105,11 +105,13 @@ pub async fn index(p: web::Path, data: web::Data) - }; // Codegen - let headmeta = r""; + + "###; let headstr = format!("

{} ({})

", meta.0, meta.1); let bodystr = meta.2.into_iter().fold(String::new(), |total, item| total + &format!("{}
\n", item, item));