adding a lot more funcitonality to core library
This commit is contained in:
parent
ba51c56169
commit
3c87385895
7 changed files with 378 additions and 105 deletions
|
@ -1,16 +1,18 @@
|
|||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use color_eyre::eyre::{eyre, Result};
|
||||
use sqlx::query;
|
||||
use color_eyre::eyre::{eyre, Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{query, query_as, sqlite::SqliteRow, FromRow, Row};
|
||||
use tracing::{debug, error};
|
||||
|
||||
use crate::{
|
||||
model::Model,
|
||||
model::{get_db, Model},
|
||||
slides::{Background, TextAlignment},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Song {
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
pub lyrics: Option<String>,
|
||||
pub author: Option<String>,
|
||||
|
@ -31,34 +33,78 @@ const VERSE_KEYWORDS: [&str; 24] = [
|
|||
"Other 2", "Other 3", "Other 4",
|
||||
];
|
||||
|
||||
impl FromRow<'_, SqliteRow> for Song {
|
||||
fn from_row(row: &SqliteRow) -> sqlx::Result<Self> {
|
||||
Ok(Self {
|
||||
id: row.try_get(12)?,
|
||||
title: row.try_get(5)?,
|
||||
lyrics: row.try_get(8)?,
|
||||
author: row.try_get(10)?,
|
||||
ccli: row.try_get(9)?,
|
||||
audio: Some(PathBuf::from({
|
||||
let string: String = row.try_get(11)?;
|
||||
string
|
||||
})),
|
||||
verse_order: Some({
|
||||
let str: &str = row.try_get(0)?;
|
||||
str.split(' ').map(|s| s.to_string()).collect()
|
||||
}),
|
||||
background: Some({
|
||||
let string: String = row.try_get(7)?;
|
||||
Background::try_from(string)?
|
||||
}),
|
||||
text_alignment: Some({
|
||||
let horizontal_alignment: String = row.try_get(3)?;
|
||||
let vertical_alignment: String = row.try_get(4)?;
|
||||
match (horizontal_alignment.to_lowercase().as_str(), vertical_alignment.to_lowercase().as_str()) {
|
||||
("left", "top") => TextAlignment::TopLeft,
|
||||
("left", "center") => TextAlignment::MiddleLeft,
|
||||
("left", "bottom") => TextAlignment::BottomLeft,
|
||||
("center", "top") => TextAlignment::TopCenter,
|
||||
("center", "center") => TextAlignment::MiddleCenter,
|
||||
("center", "bottom") => TextAlignment::BottomCenter,
|
||||
("right", "top") => TextAlignment::TopRight,
|
||||
("right", "center") => TextAlignment::MiddleRight,
|
||||
("right", "bottom") => TextAlignment::BottomRight,
|
||||
_ => TextAlignment::MiddleCenter
|
||||
}
|
||||
}),
|
||||
font: row.try_get(6)?,
|
||||
font_size: row.try_get(1)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn get_song_from_db(index: i32) -> Result<Song> {
|
||||
let mut db = get_db();
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query(r#"SELECT vorder as "verse_order!", fontSize as "font_size!: i32", backgroundType as "background_type!", horizontalTextAlignment as "horizontal_text_alignment!", verticalTextAlignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs where id = $1"#).bind(index).fetch_one(&mut db).await;
|
||||
match result {
|
||||
Ok(record) => Ok(Song::from_row(&record)?),
|
||||
Err(e) => Err(eyre!("There was an error getting the song from the db: {e}")),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
impl Model<Song> {
|
||||
pub fn load_from_db(&mut self) {
|
||||
// static DATABASE_URL: &str = "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3";
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!(r#"SELECT vorder as "verse_order!", fontSize as "font_size!: i32", backgroundType as "background_type!", horizontalTextAlignment as "horizontal_text_alignment!", verticalTextAlignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs"#).fetch_all(&mut self.db).await;
|
||||
let result = query(r#"SELECT vorder as "verse_order!", fontSize as "font_size!: i32", backgroundType as "background_type!", horizontalTextAlignment as "horizontal_text_alignment!", verticalTextAlignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs"#).fetch_all(&mut self.db).await;
|
||||
match result {
|
||||
Ok(s) => {
|
||||
for song in s.into_iter() {
|
||||
let _ = self.add_item(Song {
|
||||
title: song.title,
|
||||
lyrics: Some(song.lyrics),
|
||||
author: Some(song.author),
|
||||
ccli: Some(song.ccli),
|
||||
audio: Some(song.audio.into()),
|
||||
verse_order: Some(song.verse_order.split(" ").map(|s| s.to_string()).collect()),
|
||||
background: Some(song.background.try_into().unwrap_or_default()),
|
||||
text_alignment: {
|
||||
if song.horizontal_text_alignment == "center" && song.vertical_text_alignment == "center" {
|
||||
Some(TextAlignment::MiddleCenter)
|
||||
} else {
|
||||
Some(TextAlignment::TopCenter)
|
||||
}
|
||||
match Song::from_row(&song) {
|
||||
Ok(song) => {
|
||||
let _ = self.add_item(song);
|
||||
},
|
||||
font: Some(song.font),
|
||||
font_size: Some(song.font_size),
|
||||
});
|
||||
}
|
||||
Err(e) => error!("Could not convert song: {e}"),
|
||||
};
|
||||
};
|
||||
},
|
||||
Err(e) => {
|
||||
error!("There was an error in converting songs: {e}");
|
||||
|
@ -66,17 +112,26 @@ impl Model<Song> {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_item(&self, index: i32) -> Option<&Song> {
|
||||
self.items.iter().find(|s| s.id == index)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Song {
|
||||
pub fn get_lyrics(&self) -> Result<Vec<String>> {
|
||||
let mut lyric_list = Vec::new();
|
||||
if self.lyrics.is_none() {
|
||||
return Err(eyre!("There is no lyrics here"))
|
||||
return Err(eyre!("There is no lyrics here"));
|
||||
} else if self.verse_order.is_none() {
|
||||
return Err(eyre!("There is no verse_order here"))
|
||||
} else if self.verse_order.clone().is_some_and(|v| v.is_empty()) {
|
||||
return Err(eyre!("There is no verse_order here"))
|
||||
return Err(eyre!("There is no verse_order here"));
|
||||
} else if self
|
||||
.verse_order
|
||||
.clone()
|
||||
.is_some_and(|v| v.is_empty())
|
||||
{
|
||||
return Err(eyre!("There is no verse_order here"));
|
||||
}
|
||||
if let Some(raw_lyrics) = self.lyrics.clone() {
|
||||
let raw_lyrics = raw_lyrics.as_str();
|
||||
|
@ -232,14 +287,24 @@ You saved my soul"
|
|||
pub fn test_db_and_model() {
|
||||
let mut song_model: Model<Song> = Model::default();
|
||||
song_model.load_from_db();
|
||||
if let Some(song) = song_model.get_item(3) {
|
||||
if let Some(song) = song_model.get_item(7) {
|
||||
let test_song = test_song();
|
||||
assert_eq!(test_song.title, song.title);
|
||||
assert_eq!(&test_song, song);
|
||||
} else {
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_song_from_db() {
|
||||
let song = test_song();
|
||||
let result = get_song_from_db(7);
|
||||
match result {
|
||||
Ok(db_song) => assert_eq!(song, db_song),
|
||||
Err(e) => assert!(false, "{e}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_update() {
|
||||
let song = test_song();
|
||||
|
@ -252,14 +317,38 @@ You saved my soul"
|
|||
&cloned_song,
|
||||
song_model.get_item(2).unwrap()
|
||||
),
|
||||
Err(e) => assert!(false, "{:?}", e),
|
||||
Err(e) => assert!(false, "{e}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn test_song() -> Song {
|
||||
Song {
|
||||
id: 7,
|
||||
title: "Death Was Arrested".to_string(),
|
||||
..Default::default()
|
||||
lyrics: Some("Intro 1\nDeath Was Arrested\nNorth Point Worship\n\nVerse 1\nAlone in my sorrow\nAnd dead in my sin\n\nLost without hope\nWith no place to begin\n\nYour love made a way\nTo let mercy come in\n\nWhen death was arrested\nAnd my life began\n\nVerse 2\nAsh was redeemed\nOnly beauty remains\n\nMy orphan heart\nWas given a name\n\nMy mourning grew quiet,\nMy feet rose to dance\n\nWhen death was arrested\nAnd my life began\n\nChorus 1\nOh, Your grace so free,\nWashes over me\n\nYou have made me new,\nNow life begins with You\n\nIt's Your endless love,\nPouring down on us\n\nYou have made us new,\nNow life begins with You\n\nVerse 3\nReleased from my chains,\nI'm a prisoner no more\n\nMy shame was a ransom\nHe faithfully bore\n\nHe cancelled my debt and\nHe called me His friend\n\nWhen death was arrested\nAnd my life began\n\nVerse 4\nOur Savior displayed\nOn a criminal's cross\n\nDarkness rejoiced as though\nHeaven had lost\n\nBut then Jesus arose\nWith our freedom in hand\n\nThat's when death was arrested\nAnd my life began\n\nThat's when death was arrested\nAnd my life began\n\nBridge 1\nOh, we're free, free,\nForever we're free\n\nCome join the song\nOf all the redeemed\n\nYes, we're free, free,\nForever amen\n\nWhen death was arrested\nAnd my life began\n\nOh, we're free, free,\nForever we're free\n\nCome join the song\nOf all the redeemed\n\nYes, we're free, free,\nForever amen\n\nWhen death was arrested\nAnd my life began\n\nEnding 1\nWhen death was arrested\nAnd my life began\n\nThat's when death was arrested\nAnd my life began".to_string()),
|
||||
author: Some(
|
||||
"North Point Worship".to_string(),
|
||||
),
|
||||
ccli: None,
|
||||
audio: Some("file:///home/chris/music/North Point InsideOut/Nothing Ordinary, Pt. 1 (Live)/05 Death Was Arrested (feat. Seth Condrey).mp3".into()),
|
||||
verse_order: Some(vec![
|
||||
"I1".to_string(),
|
||||
"V1".to_string(),
|
||||
"V2".to_string(),
|
||||
"C1".to_string(),
|
||||
"V3".to_string(),
|
||||
"C1".to_string(),
|
||||
"V4".to_string(),
|
||||
"C1".to_string(),
|
||||
"B1".to_string(),
|
||||
"B1".to_string(),
|
||||
"E1".to_string(),
|
||||
"E2".to_string(),
|
||||
]),
|
||||
background: Some(Background::try_from("file:///home/chris/nc/tfc/openlp/CMG - Bright Mountains 01.jpg".to_string()).unwrap()),
|
||||
text_alignment: Some(TextAlignment::MiddleCenter),
|
||||
font: Some("Quicksand Bold".to_string()),
|
||||
font_size: Some(60)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue