From 44afe5a713d8d77deed1e120014c58c197eb978c Mon Sep 17 00:00:00 2001 From: Victoria Fischer Date: Tue, 9 Jun 2026 20:29:52 +0200 Subject: [PATCH] artifacts: move mixxx api bits into artifacts module --- src/artifacts.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ src/scene/mod.rs | 46 +++---------------------------------------- 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/src/artifacts.rs b/src/artifacts.rs index 755dd49..b8c684f 100644 --- a/src/artifacts.rs +++ b/src/artifacts.rs @@ -1,6 +1,7 @@ use chrono::{DateTime, Utc}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use sqlite::OpenFlags; #[derive(Debug, Serialize, Deserialize, Clone)] @@ -48,4 +49,54 @@ impl Into for bandcamp::Artist { #[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)] pub struct BandcampQueryArgs { pub query: String +} + +#[derive(Debug, Default, Serialize, Deserialize, Clone)] +pub struct MixxxTrack { + pub artist: String, + pub album: String, + pub title: String, + pub bpm: f64 +} + +#[derive(Debug)] +pub enum MixxxError { + Sql(sqlite::Error) +} + +impl From for MixxxError { + fn from(value: sqlite::Error) -> Self { + Self::Sql(value) + } +} + +pub struct MixxxDB(()); + +impl MixxxDB { + pub fn load(episode_number: u32) -> Result, MixxxError> { + let mut ret = vec![]; + let playlist_name = format!("BFF.fm - Episode {}", episode_number); + let connection = sqlite::Connection::open_thread_safe_with_flags("mixxxdb.sqlite", OpenFlags::new().with_read_only())?; + let query = "SELECT id FROM Playlists WHERE name = ? ORDER BY id DESC LIMIT 1"; + let mut statement = connection.prepare(query)?; + statement.bind((1, playlist_name.as_str()))?; + statement.next()?; + let latest_id = statement.read::("id").unwrap(); + + let query = "SELECT title, artist, album, comment, url, bpm FROM library LEFT JOIN PlaylistTracks ON PlaylistTracks.track_id = library.id WHERE PlaylistTracks.playlist_id = ? ORDER BY position"; + for track in connection.prepare(query).unwrap().into_iter().bind((1, latest_id)).unwrap().map(|row| row.unwrap()) { + let title = track.try_read::<&str, _>("title").unwrap_or("Untitled Track"); + let artist = track.try_read::<&str, _>("artist").unwrap_or("Unknown Artist"); + let album = track.try_read::<&str, _>("album").unwrap_or("Unknown Album"); + let bpm = track.try_read::("bpm").unwrap_or(0.); + ret.push(MixxxTrack { + artist: artist.into(), + album: album.into(), + title: title.into(), + bpm + }); + } + + Ok(ret) + } } \ No newline at end of file diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 016fb57..5e49bb2 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -2,7 +2,7 @@ use chrono::{DateTime, Duration, Utc}; use serde::{Deserialize, Serialize}; use sqlite::OpenFlags; -use crate::{artifacts::Artifact, prediction::{GeneratedResponses, PossibleResponse}, scene::conversation::ConversationEntry}; +use crate::{artifacts::{Artifact, MixxxDB, MixxxError, MixxxTrack}, prediction::{GeneratedResponses, PossibleResponse}, scene::conversation::ConversationEntry}; pub mod conversation; @@ -12,7 +12,7 @@ pub struct StageDirection { #[serde(skip)] pub end_time: DateTime, pub narrative: String, - pub current_playlist: Vec + pub current_playlist: Vec } impl StageDirection { @@ -37,41 +37,9 @@ pub struct Scenery { pub artifacts: Vec } -#[derive(Debug)] -pub enum MixxxError { - Sql(sqlite::Error) -} - -impl From for MixxxError { - fn from(value: sqlite::Error) -> Self { - Self::Sql(value) - } -} - impl StageDirection { pub fn reload_mixxx_playlist(&mut self) -> Result<(), MixxxError> { - self.current_playlist.clear(); - let playlist_name = format!("BFF.fm - Episode {}", self.episode_number); - let connection = sqlite::Connection::open_thread_safe_with_flags("mixxxdb.sqlite", OpenFlags::new().with_read_only())?; - let query = "SELECT id FROM Playlists WHERE name = ? ORDER BY id DESC LIMIT 1"; - let mut statement = connection.prepare(query)?; - statement.bind((1, playlist_name.as_str()))?; - statement.next()?; - let latest_id = statement.read::("id").unwrap(); - - let query = "SELECT title, artist, album, comment, url, bpm FROM library LEFT JOIN PlaylistTracks ON PlaylistTracks.track_id = library.id WHERE PlaylistTracks.playlist_id = ? ORDER BY position"; - for track in connection.prepare(query).unwrap().into_iter().bind((1, latest_id)).unwrap().map(|row| row.unwrap()) { - let title = track.try_read::<&str, _>("title").unwrap_or("Untitled Track"); - let artist = track.try_read::<&str, _>("artist").unwrap_or("Unknown Artist"); - let album = track.try_read::<&str, _>("album").unwrap_or("Unknown Album"); - let bpm = track.try_read::("bpm").unwrap_or(0.); - self.current_playlist.push(PlaylistEntry { - artist: artist.into(), - album: album.into(), - title: title.into(), - bpm - }); - } + self.current_playlist = MixxxDB::load(self.episode_number)?; Ok(()) } @@ -86,14 +54,6 @@ pub enum PredictionAction { SetShowEndTime(DateTime) } -#[derive(Debug, Default, Serialize, Deserialize, Clone)] -pub struct PlaylistEntry { - pub artist: String, - pub album: String, - pub title: String, - pub bpm: f64 -} - #[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct Scene { reply_options: GeneratedResponses,