artifacts: split out each artifact source into a submodule, move archive.rs into artifacts/beets.rs
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
use schemars::JsonSchema;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::artifacts::{Album, Artifact, Artist, SourceID};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
|
||||||
|
pub struct BandcampQueryArgs {
|
||||||
|
pub query: String
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Artifact> for bandcamp::Artist {
|
||||||
|
fn into(self) -> Artifact {
|
||||||
|
Artifact::Artist(Artist { name: self.name, bio: self.bio, location: self.location, sources: vec![SourceID::Bandcamp(self.id)] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Artifact> for bandcamp::Album {
|
||||||
|
fn into(self) -> Artifact {
|
||||||
|
Artifact::Album(Album {
|
||||||
|
about: self.about,
|
||||||
|
title: self.title,
|
||||||
|
artist: self.band.name,
|
||||||
|
credits: self.credits,
|
||||||
|
release_date: Some(self.release_date),
|
||||||
|
sources: vec!{SourceID::Bandcamp(self.id)}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
use sqlite::OpenFlags;
|
||||||
|
|
||||||
|
use crate::artifacts::{Album, Artifact, Artist, SourceID, Track};
|
||||||
|
|
||||||
|
#[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(());
|
||||||
|
|
||||||
|
impl MixxxDB {
|
||||||
|
pub fn load(episode_number: u32) -> Result<Vec<Artifact>, MixxxError> {
|
||||||
|
let mut ret = vec![];
|
||||||
|
let playlist_name = format!("BFF.fm - Episode {}", episode_number);
|
||||||
|
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.as_str()))?;
|
||||||
|
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(Artifact::Track(Track {
|
||||||
|
artist: Some(artist.into()),
|
||||||
|
album: Some(album.into()),
|
||||||
|
title: title.into(),
|
||||||
|
bpm: Some(bpm),
|
||||||
|
sources: vec![SourceID::Mixxx],
|
||||||
|
..Default::default()
|
||||||
|
}));
|
||||||
|
|
||||||
|
ret.push(Artifact::Album(Album {
|
||||||
|
artist: artist.into(),
|
||||||
|
title: album.into(),
|
||||||
|
sources: vec![SourceID::Mixxx],
|
||||||
|
..Default::default()
|
||||||
|
}));
|
||||||
|
|
||||||
|
ret.push(Artifact::Artist(Artist {
|
||||||
|
name: artist.into(),
|
||||||
|
sources: vec![SourceID::Mixxx],
|
||||||
|
..Default::default()
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use schemars::JsonSchema;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlite::OpenFlags;
|
|
||||||
|
pub mod bandcamp;
|
||||||
|
pub mod mixxx;
|
||||||
|
pub mod beets;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum SourceID {
|
pub enum SourceID {
|
||||||
@@ -131,88 +133,4 @@ impl Artifact {
|
|||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<Artifact> for bandcamp::Artist {
|
|
||||||
fn into(self) -> Artifact {
|
|
||||||
Artifact::Artist(Artist { name: self.name, bio: self.bio, location: self.location, sources: vec![SourceID::Bandcamp(self.id)] })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<Artifact> for bandcamp::Album {
|
|
||||||
fn into(self) -> Artifact {
|
|
||||||
Artifact::Album(Album {
|
|
||||||
about: self.about,
|
|
||||||
title: self.title,
|
|
||||||
artist: self.band.name,
|
|
||||||
credits: self.credits,
|
|
||||||
release_date: Some(self.release_date),
|
|
||||||
sources: vec!{SourceID::Bandcamp(self.id)}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
|
|
||||||
pub struct BandcampQueryArgs {
|
|
||||||
pub query: String
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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(());
|
|
||||||
|
|
||||||
impl MixxxDB {
|
|
||||||
pub fn load(episode_number: u32) -> Result<Vec<Artifact>, MixxxError> {
|
|
||||||
let mut ret = vec![];
|
|
||||||
let playlist_name = format!("BFF.fm - Episode {}", episode_number);
|
|
||||||
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.as_str()))?;
|
|
||||||
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(Artifact::Track(Track {
|
|
||||||
artist: Some(artist.into()),
|
|
||||||
album: Some(album.into()),
|
|
||||||
title: title.into(),
|
|
||||||
bpm: Some(bpm),
|
|
||||||
sources: vec![SourceID::Mixxx],
|
|
||||||
..Default::default()
|
|
||||||
}));
|
|
||||||
|
|
||||||
ret.push(Artifact::Album(Album {
|
|
||||||
artist: artist.into(),
|
|
||||||
title: album.into(),
|
|
||||||
sources: vec![SourceID::Mixxx],
|
|
||||||
..Default::default()
|
|
||||||
}));
|
|
||||||
|
|
||||||
ret.push(Artifact::Artist(Artist {
|
|
||||||
name: artist.into(),
|
|
||||||
sources: vec![SourceID::Mixxx],
|
|
||||||
..Default::default()
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(ret)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,6 @@ mod tts;
|
|||||||
mod prediction;
|
mod prediction;
|
||||||
mod audio;
|
mod audio;
|
||||||
mod artifacts;
|
mod artifacts;
|
||||||
mod archive;
|
|
||||||
mod ui;
|
mod ui;
|
||||||
mod widgets;
|
mod widgets;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use serde_json::{Serializer, ser::CompactFormatter};
|
use serde_json::{Serializer, ser::CompactFormatter};
|
||||||
use tokio::sync::{RwLock, mpsc, watch};
|
use tokio::sync::{RwLock, mpsc, watch};
|
||||||
|
|
||||||
use crate::{SaveData, archive::BeatsQueryArgs, artifacts::{Album, Artifact, Artist, BandcampQueryArgs, MixxxDB, Track}, scene::{Scene, Scenery, StageDirection, conversation::ConversationEntry}};
|
use crate::{SaveData, artifacts::{Album, Artifact, Artist, Track, beets::BeatsQueryArgs, bandcamp::BandcampQueryArgs, mixxx::MixxxDB}, scene::{Scene, Scenery, StageDirection, conversation::ConversationEntry}};
|
||||||
|
|
||||||
|
|
||||||
const SYSTEM_PROMPT: &str = include_str!("system-prompt.txt");
|
const SYSTEM_PROMPT: &str = include_str!("system-prompt.txt");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use chrono::{Duration, Utc};
|
use chrono::{Duration, Utc};
|
||||||
use crossterm::event::{self, KeyCode, KeyModifiers, MediaKeyCode::Record};
|
use crossterm::event::{self, KeyCode, KeyModifiers};
|
||||||
use ratatui::{Frame, layout::{Direction, Layout, Rect}, style::{self, Style, Stylize}, text::{Line, Span, Text}, widgets::{BorderType, Clear, Gauge, List, ListDirection, ListState, Paragraph, StatefulWidget, Widget, Wrap}};
|
use ratatui::{Frame, layout::{Direction, Layout, Rect}, style::{self, }, text::Span, widgets::{BorderType, Clear, ListState, Paragraph}};
|
||||||
use throbber_widgets_tui::{Throbber, ThrobberState};
|
use throbber_widgets_tui::{Throbber, ThrobberState};
|
||||||
use tokio::time::Instant;
|
use tokio::time::Instant;
|
||||||
use tui_input::{Input, backend::crossterm::EventHandler};
|
use tui_input::{Input, backend::crossterm::EventHandler};
|
||||||
|
|||||||
Reference in New Issue
Block a user