Added override file

This commit is contained in:
Seoxi Ryouko
2025-10-30 22:24:17 -05:00
parent d0f0d07b51
commit 9591dcdd3e
4 changed files with 124 additions and 15 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
/.env /.env
/watcat.db* /watcat.db*
/http-cacache /http-cacache
/overrides.txt

34
Cargo.lock generated
View File

@ -1100,6 +1100,12 @@ dependencies = [
"foldhash", "foldhash",
] ]
[[package]]
name = "hashbrown"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
[[package]] [[package]]
name = "hashlink" name = "hashlink"
version = "0.10.0" version = "0.10.0"
@ -1570,12 +1576,12 @@ checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.9.0" version = "2.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown 0.15.3", "hashbrown 0.16.0",
] ]
[[package]] [[package]]
@ -2958,9 +2964,19 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.219" version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index" 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 = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@ -2976,9 +2992,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.219" version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -4695,9 +4711,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.7.10" version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "watcat" name = "watcat"
version = "0.6.1" version = "0.6.2"
edition = "2024" edition = "2024"
[dependencies] [dependencies]

View File

@ -34,6 +34,9 @@ use rspotify::{ClientCredsSpotify, Credentials, clients::BaseClient};
use imagetext::fontdb::FontDB; use imagetext::fontdb::FontDB;
use imagetext::superfont::SuperFont; use imagetext::superfont::SuperFont;
use std::time::SystemTime;
use std::io::Read;
mod text; mod text;
static START: Once = Once::new(); 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<SystemTime>) -> Option<HashMap<String, String>> {
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<String, String> {
let data = ctx.data.write().await;
let overrides = data.get::<OverridesHaver>().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<String>) -> Reply { async fn fmi(ctx: &Context, arg: Option<&str>, id: UserId, avatar: Option<String>) -> Reply {
let track = match get_track(ctx, arg, id).await { let track = match get_track(ctx, arg, id).await {
Ok(track) => track, Ok(track) => track,
@ -206,11 +254,20 @@ async fn fmi(ctx: &Context, arg: Option<&str>, id: UserId, avatar: Option<String
artist: track.artist.name, artist: track.artist.name,
album: track.album, album: track.album,
}; };
let image_uri = match track.image.extralarge { let original_image_uri = match track.image.extralarge {
Some(iu) => iu, Some(iu) => iu,
None => return Reply::Text("Error: getting image uri failed".to_owned()), 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 base_color = PixelWand::new();
let mut accent_color = PixelWand::new(); let mut accent_color = PixelWand::new();
let mut white = PixelWand::new(); let mut white = PixelWand::new();
@ -397,7 +454,7 @@ async fn fmi(ctx: &Context, arg: Option<&str>, id: UserId, avatar: Option<String
"Failed to set main colorspace" "Failed to set main colorspace"
); );
handle_magick_result!( handle_magick_result!(
art_wand.adaptive_resize_image(124, 124), art_wand.resize_image(124, 124, FilterType::RobidouxSharp),
"Failed to resize art" "Failed to resize art"
); );
/*handle_magick_result!( /*handle_magick_result!(
@ -436,6 +493,19 @@ async fn fmi(ctx: &Context, arg: Option<&str>, id: UserId, avatar: Option<String
Reply::Image(main_wand.write_image_blob("png").unwrap()) Reply::Image(main_wand.write_image_blob("png").unwrap())
} }
async fn text(ctx: &Context, arg: Option<&str>, 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 { fn help(arg: Option<&str>) -> Reply {
Reply::Text(format!( Reply::Text(format!(
"```{}```", "```{}```",
@ -526,14 +596,21 @@ impl EventHandler for Handler {
| (".ku" | ".kl" | ".kurl", arg, "") =>*/ { | (".ku" | ".kl" | ".kurl", arg, "") =>*/ {
log!("{} received", msg.content); log!("{} received", msg.content);
Some(url(&ctx, arg, msg.author.id).await) 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) => cmd_pattern!("spot" | "spotify", ".kx", arg) =>
/*(".k", "spot" | "spotify", arg) /*(".k", "spot" | "spotify", arg)
| (".k", arg, "spot" | "spotify") | (".k", arg, "spot" | "spotify")
| (".ks" | ".kspot", arg, "") =>*/ { | (".ks" | ".kspot", arg, "") =>*/ {
log!("{} received", msg.content); log!("{} received", msg.content);
Some(spot(&ctx, arg, msg.author.id).await) Some(spot(&ctx, arg, msg.author.id).await)
} },
(Some(".ks"), Some(_), _) => { (Some(".ks"), Some(_), _) => {
log!("{} received", msg.content); log!("{} received", msg.content);
Some(search(&ctx, &msg.content[4..]).await) Some(search(&ctx, &msg.content[4..]).await)
@ -596,6 +673,15 @@ impl TypeMapKey for ColorsHaver {
type Value = ColorCache; type Value = ColorCache;
} }
struct Overrides {
map: Arc<Mutex<HashMap<String, String>>>,
last_modified: Option<SystemTime>,
}
struct OverridesHaver;
impl TypeMapKey for OverridesHaver {
type Value = Overrides;
}
struct DBResponse { struct DBResponse {
lastfm_username: String, lastfm_username: String,
} }
@ -729,11 +815,16 @@ async fn main() {
let _ = &spotify_client.request_token().await.unwrap(); let _ = &spotify_client.request_token().await.unwrap();
} }
let colors_cache: ColorCache = ColorCache { let colors_cache = ColorCache {
map: Arc::new(Mutex::new(HashMap::new())), map: Arc::new(Mutex::new(HashMap::new())),
max: env::var("MAX_CACHE_SIZE").unwrap_or("".to_owned()).parse::<usize>().unwrap_or(1000000), max: env::var("MAX_CACHE_SIZE").unwrap_or("".to_owned()).parse::<usize>().unwrap_or(1000000),
}; };
let overrides = Overrides {
map: Arc::new(Mutex::new(HashMap::new())),
last_modified: None,
};
let mut discord_client = Client::builder(&token, intents) let mut discord_client = Client::builder(&token, intents)
.event_handler(Handler) .event_handler(Handler)
.await .await
@ -746,6 +837,7 @@ async fn main() {
data.insert::<FontsHaver>((regular_fonts, bold_fonts)); data.insert::<FontsHaver>((regular_fonts, bold_fonts));
data.insert::<SpotifyHaver>(spotify.map(Mutex::new).map(Arc::new)); data.insert::<SpotifyHaver>(spotify.map(Mutex::new).map(Arc::new));
data.insert::<ColorsHaver>(colors_cache); data.insert::<ColorsHaver>(colors_cache);
data.insert::<OverridesHaver>(overrides);
} }
if let Err(why) = discord_client.start().await { if let Err(why) = discord_client.start().await {