diff --git a/.gitignore b/.gitignore index 8da430e..c484ab1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /.env /watcat.db* /http-cacache +/overrides.txt diff --git a/Cargo.lock b/Cargo.lock index 9d3679a..776e8ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1100,6 +1100,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "hashlink" version = "0.10.0" @@ -1570,12 +1576,12 @@ checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" [[package]] name = "indexmap" -version = "2.9.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", - "hashbrown 0.15.3", + "hashbrown 0.16.0", ] [[package]] @@ -2958,9 +2964,19 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] @@ -2976,9 +2992,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -4695,9 +4711,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" -version = "0.7.10" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 43154cd..aaa51eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "watcat" -version = "0.6.1" +version = "0.6.2" edition = "2024" [dependencies] diff --git a/src/main.rs b/src/main.rs index 24231d2..fa657b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,6 +34,9 @@ use rspotify::{ClientCredsSpotify, Credentials, clients::BaseClient}; use imagetext::fontdb::FontDB; use imagetext::superfont::SuperFont; +use std::time::SystemTime; +use std::io::Read; + mod text; static START: Once = Once::new(); @@ -196,6 +199,51 @@ async fn spot(ctx: &Context, arg: Option<&str>, id: UserId) -> Reply { } } +async fn get_overrides_inner(last_modified: Option) -> Option> { + let mut file = match std::fs::File::open("overrides.txt") { + Ok(a) => a, + Err(_) => return None, + }; + let file_stats = match file.metadata() { + Ok(a) => a, + Err(_) => return None, + }; + let file_modified_time = match file_stats.modified() { + Ok(a) => a, + Err(_) => return None, + }; + let reload = match last_modified { + None => true, + Some(last_modified) => match file_modified_time.duration_since(last_modified) { + Err(_) => true, + Ok(a) => a != std::time::Duration::default() + } + }; + if !reload { return None; } + let mut contents = "".to_owned(); + match file.read_to_string(&mut contents) { + Ok(_) => (), + Err(_) => return None, + }; + Some(contents.as_str().lines().map(|x| { + let mut split = x.split("@"); + let a: &str = split.next().unwrap_or("").trim(); + let b: &str = split.next().unwrap_or("").trim(); + (a.to_owned(), b.to_owned()) + }).collect()) +} + +async fn get_overrides(ctx: &Context) -> HashMap { + let data = ctx.data.write().await; + let overrides = data.get::().expect("Failed to have overrides"); + let mut map = overrides.map.lock().await; + let new_map = get_overrides_inner(overrides.last_modified).await; + if let Some(new_map) = new_map { + *map = new_map; + } + map.clone() +} + async fn fmi(ctx: &Context, arg: Option<&str>, id: UserId, avatar: Option) -> Reply { let track = match get_track(ctx, arg, id).await { Ok(track) => track, @@ -206,11 +254,20 @@ async fn fmi(ctx: &Context, arg: Option<&str>, id: UserId, avatar: Option iu, None => return Reply::Text("Error: getting image uri failed".to_owned()), }; + let overrides = get_overrides(ctx).await; + let image_uri: String = match overrides.get(&format!("{} | {}", track_info.artist, track_info.album)) { + Some(s) => s, + None => match overrides.get(&track_info.album) { + Some(s) => s, + None => &original_image_uri, + }, + }.to_owned(); + let mut base_color = PixelWand::new(); let mut accent_color = PixelWand::new(); let mut white = PixelWand::new(); @@ -397,7 +454,7 @@ async fn fmi(ctx: &Context, arg: Option<&str>, id: UserId, avatar: Option, id: UserId, avatar: Option, id: UserId) -> Reply { + let track = match get_track(ctx, arg, id).await { + Ok(track) => track, + Err(e) => return e, + }; + Reply::Text(format!( + "{}\n{}\n{}", + track.name, + track.artist.name, + track.album, + )) +} + fn help(arg: Option<&str>) -> Reply { Reply::Text(format!( "```{}```", @@ -526,14 +596,21 @@ impl EventHandler for Handler { | (".ku" | ".kl" | ".kurl", arg, "") =>*/ { log!("{} received", msg.content); Some(url(&ctx, arg, msg.author.id).await) - } + }, + cmd_pattern!("text", ".kt", arg) => + /*(".k", "url" | "uri" | "link", arg) + | (".k", arg, "url" | "uri" | "link") + | (".ku" | ".kl" | ".kurl", arg, "") =>*/ { + log!("{} received", msg.content); + Some(text(&ctx, arg, msg.author.id).await) + }, cmd_pattern!("spot" | "spotify", ".kx", arg) => /*(".k", "spot" | "spotify", arg) | (".k", arg, "spot" | "spotify") | (".ks" | ".kspot", arg, "") =>*/ { log!("{} received", msg.content); Some(spot(&ctx, arg, msg.author.id).await) - } + }, (Some(".ks"), Some(_), _) => { log!("{} received", msg.content); Some(search(&ctx, &msg.content[4..]).await) @@ -596,6 +673,15 @@ impl TypeMapKey for ColorsHaver { type Value = ColorCache; } +struct Overrides { + map: Arc>>, + last_modified: Option, +} +struct OverridesHaver; +impl TypeMapKey for OverridesHaver { + type Value = Overrides; +} + struct DBResponse { lastfm_username: String, } @@ -729,11 +815,16 @@ async fn main() { let _ = &spotify_client.request_token().await.unwrap(); } - let colors_cache: ColorCache = ColorCache { + let colors_cache = ColorCache { map: Arc::new(Mutex::new(HashMap::new())), max: env::var("MAX_CACHE_SIZE").unwrap_or("".to_owned()).parse::().unwrap_or(1000000), }; + let overrides = Overrides { + map: Arc::new(Mutex::new(HashMap::new())), + last_modified: None, + }; + let mut discord_client = Client::builder(&token, intents) .event_handler(Handler) .await @@ -746,6 +837,7 @@ async fn main() { data.insert::((regular_fonts, bold_fonts)); data.insert::(spotify.map(Mutex::new).map(Arc::new)); data.insert::(colors_cache); + data.insert::(overrides); } if let Err(why) = discord_client.start().await {