87 lines
3.0 KiB
Rust
87 lines
3.0 KiB
Rust
use schemars::JsonSchema;
|
|
use serde::{Deserialize, Serialize};
|
|
use sqlite::OpenFlags;
|
|
|
|
use crate::artifacts::{Album, Artifact, ArtifactBuilder, Artist, SourceID, Track, tools::{DataSource, ToolDescription}};
|
|
|
|
#[derive(Debug)]
|
|
#[allow(unused)]
|
|
pub enum MixxxError {
|
|
Sql(sqlite::Error)
|
|
}
|
|
|
|
impl From<sqlite::Error> for MixxxError {
|
|
fn from(value: sqlite::Error) -> Self {
|
|
Self::Sql(value)
|
|
}
|
|
}
|
|
|
|
pub struct MixxxDB;
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Default, JsonSchema)]
|
|
pub struct MixxxQuery {
|
|
pub playlist_name: String
|
|
}
|
|
|
|
impl DataSource for MixxxDB {
|
|
type Args = MixxxQuery;
|
|
type Error = MixxxError;
|
|
|
|
async fn synchronize(&self, _artifact: &mut Artifact) -> Result<Vec<Artifact>, Self::Error> {
|
|
Ok(vec![])
|
|
}
|
|
|
|
async fn query(&self, args: &Self::Args) -> Result<Vec<Artifact>, Self::Error> {
|
|
let mut ret = vec![];
|
|
let playlist_name = args.playlist_name.as_str();
|
|
log::info!("Loading Mixxx playlist {}", playlist_name);
|
|
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))?;
|
|
statement.next()?;
|
|
let latest_id = statement.read::<i64, _>("id")?;
|
|
|
|
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)?.into_iter().bind((1, latest_id))? {
|
|
let track = track?;
|
|
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::<f64, _>("bpm").unwrap_or(0.);
|
|
ret.push(ArtifactBuilder::new(SourceID::Mixxx)
|
|
.contents(Track {
|
|
artist: Some(artist.into()),
|
|
album: Some(album.into()),
|
|
title: title.into(),
|
|
bpm: Some(bpm),
|
|
..Default::default()
|
|
}).build());
|
|
|
|
ret.push(ArtifactBuilder::new(SourceID::Mixxx)
|
|
.contents(Album {
|
|
artist: artist.into(),
|
|
title: album.into(),
|
|
..Default::default()
|
|
}).build());
|
|
|
|
ret.push(ArtifactBuilder::new(SourceID::Mixxx)
|
|
.contents(Artist {
|
|
name: artist.into(),
|
|
..Default::default()
|
|
}).build());
|
|
}
|
|
|
|
Ok(ret)
|
|
}
|
|
}
|
|
|
|
impl ToolDescription for MixxxDB {
|
|
fn description(&self) -> &str {
|
|
"Loads artifacts from a given Mixxx playlist name"
|
|
}
|
|
|
|
fn name(&self) -> &str {
|
|
"query_mixxx"
|
|
}
|
|
} |