fixing lots of bugs
This commit is contained in:
parent
da735aa00b
commit
0ba3e7588b
24 changed files with 781 additions and 486 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1464,7 +1464,7 @@ dependencies = [
|
|||
"cxx-qt-lib",
|
||||
"dirs",
|
||||
"fastrand 2.1.1",
|
||||
"lumina-core",
|
||||
"lumina_core",
|
||||
"obws",
|
||||
"qt-build-utils",
|
||||
"quote",
|
||||
|
@ -1549,7 +1549,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "lumina-core"
|
||||
name = "lumina_core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"color-eyre",
|
||||
|
|
|
@ -21,7 +21,7 @@ path = "src/rust/lib.rs"
|
|||
# path = "src/rust/main.rs"
|
||||
|
||||
[dependencies]
|
||||
lumina-core = { path = "src/rust/core" }
|
||||
lumina_core = { path = "src/rust/core" }
|
||||
configparser = "3.0.2"
|
||||
serde = "1.0.152"
|
||||
serde_derive = "1.0.152"
|
||||
|
|
2
justfile
2
justfile
|
@ -15,7 +15,7 @@ test:
|
|||
RUST_LOG=debug cargo test --benches --tests --all-features -- --nocapture
|
||||
|
||||
testcore:
|
||||
RUST_LOG=debug cargo test -p core --benches --tests --all-features -- --nocapture
|
||||
RUST_LOG=debug cargo test -p lumina_core --benches --tests --all-features -- --nocapture
|
||||
|
||||
alias b := build
|
||||
alias r := run
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "lumina-core"
|
||||
name = "lumina_core"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = [
|
||||
|
|
|
@ -1,86 +1,131 @@
|
|||
use tar::{Archive, Builder};
|
||||
use tracing::error;
|
||||
use zstd::Encoder;
|
||||
use std::{fs::{self, File}, iter, path::{Path, PathBuf}};
|
||||
use crate::{
|
||||
images::{get_image_from_db, Image},
|
||||
kinds::ServiceItemKind,
|
||||
model::get_db,
|
||||
presentations::{
|
||||
get_presentation_from_db, PresKind, Presentation,
|
||||
},
|
||||
service_items::ServiceItem,
|
||||
slides::Background,
|
||||
songs::{get_song_from_db, Song},
|
||||
videos::{get_video_from_db, Video},
|
||||
};
|
||||
use color_eyre::eyre::{eyre, Context, Result};
|
||||
use serde_json::Value;
|
||||
use sqlx::{query, query_as, FromRow, SqliteConnection};
|
||||
use crate::{images::{get_image_from_db, Image}, kinds::ServiceItemKind, model::get_db, presentations::{get_presentation_from_db, PresKind, Presentation}, service_items::ServiceItem, slides::Background, songs::{get_song_from_db, Song}, videos::{get_video_from_db, Video}};
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
iter,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use tar::{Archive, Builder};
|
||||
use tracing::error;
|
||||
use zstd::Encoder;
|
||||
|
||||
pub async fn save(list: Vec<ServiceItem>, path: impl AsRef<Path>) -> Result<()> {
|
||||
pub async fn save(
|
||||
list: Vec<ServiceItem>,
|
||||
path: impl AsRef<Path>,
|
||||
) -> Result<()> {
|
||||
let path = path.as_ref();
|
||||
let save_file = File::create(path)?;
|
||||
let mut db = get_db().await;
|
||||
let json = process_service_items(&list, &mut db).await?;
|
||||
let archive = store_service_items(&list, &mut db, &save_file, &json).await?;
|
||||
let archive =
|
||||
store_service_items(&list, &mut db, &save_file, &json)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn store_service_items(items: &Vec<ServiceItem>, db: &mut SqliteConnection, save_file: &File, json: &Value) -> Result<()> {
|
||||
async fn store_service_items(
|
||||
items: &Vec<ServiceItem>,
|
||||
db: &mut SqliteConnection,
|
||||
save_file: &File,
|
||||
json: &Value,
|
||||
) -> Result<()> {
|
||||
let encoder = Encoder::new(save_file, 3).unwrap();
|
||||
let mut tar = Builder::new(encoder);
|
||||
let mut temp_dir = dirs::data_dir().unwrap();
|
||||
temp_dir.push("lumina");
|
||||
let mut s: String =
|
||||
iter::repeat_with(fastrand::alphanumeric)
|
||||
.take(5)
|
||||
.collect();
|
||||
iter::repeat_with(fastrand::alphanumeric).take(5).collect();
|
||||
s.insert_str(0, "temp_");
|
||||
temp_dir.push(s);
|
||||
fs::create_dir_all(&temp_dir)?;
|
||||
let service_file = temp_dir.join("serviceitems.json");
|
||||
fs::File::create(&service_file)?;
|
||||
match fs::File::options().read(true).write(true).open(service_file) {
|
||||
match fs::File::options()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open(service_file)
|
||||
{
|
||||
Ok(f) => {
|
||||
serde_json::to_writer_pretty(f, json)?;
|
||||
},
|
||||
Err(e) => error!("There were problems making a file i guess: {e}"),
|
||||
}
|
||||
Err(e) => {
|
||||
error!("There were problems making a file i guess: {e}")
|
||||
}
|
||||
};
|
||||
for item in items {
|
||||
let background;
|
||||
let audio: Option<PathBuf>;
|
||||
match item.kind {
|
||||
ServiceItemKind::Song => {
|
||||
let song = get_song_from_db(item.database_id, db).await?;
|
||||
let song =
|
||||
get_song_from_db(item.database_id, db).await?;
|
||||
background = song.background;
|
||||
audio = song.audio;
|
||||
},
|
||||
}
|
||||
ServiceItemKind::Image => {
|
||||
let image = get_image_from_db(item.database_id, db).await?;
|
||||
let image =
|
||||
get_image_from_db(item.database_id, db).await?;
|
||||
background = Some(Background::try_from(image.path)?);
|
||||
audio = None;
|
||||
},
|
||||
}
|
||||
ServiceItemKind::Video => {
|
||||
let video = get_video_from_db(item.database_id, db).await?;
|
||||
let video =
|
||||
get_video_from_db(item.database_id, db).await?;
|
||||
background = Some(Background::try_from(video.path)?);
|
||||
audio = None;
|
||||
},
|
||||
}
|
||||
ServiceItemKind::Presentation(_) => {
|
||||
let presentation = get_presentation_from_db(item.database_id, db).await?;
|
||||
background = Some(Background::try_from(presentation.path)?);
|
||||
let presentation =
|
||||
get_presentation_from_db(item.database_id, db)
|
||||
.await?;
|
||||
background =
|
||||
Some(Background::try_from(presentation.path)?);
|
||||
audio = None;
|
||||
},
|
||||
}
|
||||
ServiceItemKind::Content => {
|
||||
todo!()
|
||||
},
|
||||
}
|
||||
};
|
||||
if let Some(file) = audio {
|
||||
let audio_file = temp_dir.join(file.file_name().expect("Audio file couldn't be added to temp_dir"));
|
||||
let audio_file =
|
||||
temp_dir.join(file.file_name().expect(
|
||||
"Audio file couldn't be added to temp_dir",
|
||||
));
|
||||
if let Ok(file) = file.strip_prefix("file://") {
|
||||
fs::File::create(&audio_file).wrap_err("Couldn't create audio file")?;
|
||||
fs::File::create(&audio_file)
|
||||
.wrap_err("Couldn't create audio file")?;
|
||||
fs::copy(file, audio_file).wrap_err("Audio file could not be copied, the source file doesn't exist not be found");
|
||||
} else {
|
||||
fs::File::create(&audio_file).wrap_err("Couldn't create audio file")?;
|
||||
fs::File::create(&audio_file)
|
||||
.wrap_err("Couldn't create audio file")?;
|
||||
fs::copy(file, audio_file).wrap_err("Audio file could not be copied, the source file doesn't exist not be found");
|
||||
}
|
||||
};
|
||||
if let Some(file) = background {
|
||||
let background_file = temp_dir.join(file.path.file_name().expect("Background file couldn't be added to temp_dir"));
|
||||
let background_file =
|
||||
temp_dir.join(file.path.file_name().expect(
|
||||
"Background file couldn't be added to temp_dir",
|
||||
));
|
||||
if let Ok(file) = file.path.strip_prefix("file://") {
|
||||
fs::File::create(&background_file).wrap_err("Couldn't create background file")?;
|
||||
fs::File::create(&background_file)
|
||||
.wrap_err("Couldn't create background file")?;
|
||||
fs::copy(file, background_file).wrap_err("Background file could not be copied, the source file doesn't exist not be found");
|
||||
} else {
|
||||
fs::File::create(&background_file).wrap_err("Couldn't create background file")?;
|
||||
fs::File::create(&background_file)
|
||||
.wrap_err("Couldn't create background file")?;
|
||||
fs::copy(file.path, background_file).wrap_err("Background file could not be copied, the source file doesn't exist not be found");
|
||||
}
|
||||
}
|
||||
|
@ -92,66 +137,96 @@ async fn clear_temp_dir(temp_dir: &Path) -> Result<()> {
|
|||
todo!()
|
||||
}
|
||||
|
||||
async fn process_service_items(items: &Vec<ServiceItem>, db: &mut SqliteConnection) -> Result<Value> {
|
||||
async fn process_service_items(
|
||||
items: &Vec<ServiceItem>,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Value> {
|
||||
let mut values: Vec<Value> = vec![];
|
||||
for item in items {
|
||||
match item.kind {
|
||||
ServiceItemKind::Song => {
|
||||
let value = process_song(item.database_id, db).await?;
|
||||
let value =
|
||||
process_song(item.database_id, db).await?;
|
||||
values.push(value);
|
||||
},
|
||||
}
|
||||
ServiceItemKind::Image => {
|
||||
let value = process_image(item.database_id, db).await?;
|
||||
let value =
|
||||
process_image(item.database_id, db).await?;
|
||||
values.push(value);
|
||||
},
|
||||
}
|
||||
ServiceItemKind::Video => {
|
||||
let value = process_video(item.database_id, db).await?;
|
||||
let value =
|
||||
process_video(item.database_id, db).await?;
|
||||
values.push(value);
|
||||
},
|
||||
}
|
||||
ServiceItemKind::Presentation(_) => {
|
||||
let value = process_presentation(item.database_id, db).await?;
|
||||
let value =
|
||||
process_presentation(item.database_id, db)
|
||||
.await?;
|
||||
values.push(value);
|
||||
},
|
||||
}
|
||||
ServiceItemKind::Content => {
|
||||
todo!()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
let json = Value::from(values);
|
||||
Ok(json)
|
||||
}
|
||||
|
||||
async fn process_song(database_id: i32, db: &mut SqliteConnection) -> Result<Value> {
|
||||
async fn process_song(
|
||||
database_id: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Value> {
|
||||
let song = get_song_from_db(database_id, db).await?;
|
||||
let song_json = serde_json::to_value(&song)?;
|
||||
let kind_json = serde_json::to_value(ServiceItemKind::Song)?;
|
||||
let json = serde_json::json!({"item": song_json, "kind": kind_json});
|
||||
let json =
|
||||
serde_json::json!({"item": song_json, "kind": kind_json});
|
||||
Ok(json)
|
||||
}
|
||||
|
||||
async fn process_image(database_id: i32, db: &mut SqliteConnection) -> Result<Value> {
|
||||
async fn process_image(
|
||||
database_id: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Value> {
|
||||
let image = get_image_from_db(database_id, db).await?;
|
||||
let image_json = serde_json::to_value(&image)?;
|
||||
let kind_json = serde_json::to_value(ServiceItemKind::Image)?;
|
||||
let json = serde_json::json!({"item": image_json, "kind": kind_json});
|
||||
let json =
|
||||
serde_json::json!({"item": image_json, "kind": kind_json});
|
||||
Ok(json)
|
||||
}
|
||||
|
||||
async fn process_video(database_id: i32, db: &mut SqliteConnection) -> Result<Value> {
|
||||
async fn process_video(
|
||||
database_id: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Value> {
|
||||
let video = get_video_from_db(database_id, db).await?;
|
||||
let video_json = serde_json::to_value(&video)?;
|
||||
let kind_json = serde_json::to_value(ServiceItemKind::Video)?;
|
||||
let json = serde_json::json!({"item": video_json, "kind": kind_json});
|
||||
let json =
|
||||
serde_json::json!({"item": video_json, "kind": kind_json});
|
||||
Ok(json)
|
||||
}
|
||||
|
||||
async fn process_presentation(database_id: i32, db: &mut SqliteConnection) -> Result<Value> {
|
||||
let presentation = get_presentation_from_db(database_id, db).await?;
|
||||
async fn process_presentation(
|
||||
database_id: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Value> {
|
||||
let presentation =
|
||||
get_presentation_from_db(database_id, db).await?;
|
||||
let presentation_json = serde_json::to_value(&presentation)?;
|
||||
let kind_json = match presentation.kind {
|
||||
PresKind::Html => serde_json::to_value(ServiceItemKind::Presentation(PresKind::Html))?,
|
||||
PresKind::Pdf => serde_json::to_value(ServiceItemKind::Presentation(PresKind::Pdf))?,
|
||||
PresKind::Generic => serde_json::to_value(ServiceItemKind::Presentation(PresKind::Generic))?,
|
||||
PresKind::Html => serde_json::to_value(
|
||||
ServiceItemKind::Presentation(PresKind::Html),
|
||||
)?,
|
||||
PresKind::Pdf => serde_json::to_value(
|
||||
ServiceItemKind::Presentation(PresKind::Pdf),
|
||||
)?,
|
||||
PresKind::Generic => serde_json::to_value(
|
||||
ServiceItemKind::Presentation(PresKind::Generic),
|
||||
)?,
|
||||
};
|
||||
let json = serde_json::json!({"item": presentation_json, "kind": kind_json});
|
||||
Ok(json)
|
||||
|
@ -161,11 +236,11 @@ async fn process_presentation(database_id: i32, db: &mut SqliteConnection) -> Re
|
|||
mod test {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use fs::canonicalize;
|
||||
use sqlx::Connection;
|
||||
use pretty_assertions::assert_eq;
|
||||
use tracing::debug;
|
||||
use super::*;
|
||||
use fs::canonicalize;
|
||||
use pretty_assertions::assert_eq;
|
||||
use sqlx::Connection;
|
||||
use tracing::debug;
|
||||
|
||||
async fn get_db() -> SqliteConnection {
|
||||
let mut data = dirs::data_local_dir().unwrap();
|
||||
|
@ -173,9 +248,7 @@ mod test {
|
|||
data.push("library-db.sqlite3");
|
||||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
SqliteConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("problems")
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
|
@ -245,7 +318,8 @@ mod test {
|
|||
async fn test_process_presentation() {
|
||||
let mut db = get_db().await;
|
||||
let result = process_presentation(54, &mut db).await;
|
||||
let json_presentation_file = PathBuf::from("./test/test_presentation.json");
|
||||
let json_presentation_file =
|
||||
PathBuf::from("./test/test_presentation.json");
|
||||
if let Ok(path) = canonicalize(json_presentation_file) {
|
||||
debug!(file = ?&path);
|
||||
if let Ok(s) = fs::read_to_string(path) {
|
||||
|
@ -258,7 +332,9 @@ mod test {
|
|||
panic!("String wasn't read from file");
|
||||
}
|
||||
} else {
|
||||
panic!("Cannot find absolute path to test_presentation.json");
|
||||
panic!(
|
||||
"Cannot find absolute path to test_presentation.json"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,7 +363,8 @@ mod test {
|
|||
async fn test_service_items() {
|
||||
let mut db = get_db().await;
|
||||
let items = get_items();
|
||||
let json_item_file = PathBuf::from("./test/test_service_items.json");
|
||||
let json_item_file =
|
||||
PathBuf::from("./test/test_service_items.json");
|
||||
let result = process_service_items(&items, &mut db).await;
|
||||
if let Ok(path) = canonicalize(json_item_file) {
|
||||
if let Ok(s) = fs::read_to_string(path) {
|
||||
|
@ -311,16 +388,23 @@ mod test {
|
|||
|
||||
#[tokio::test]
|
||||
async fn test_store() {
|
||||
let path = PathBuf::from("/home/chris/dev/lumina/src/rust/core/test.pres");
|
||||
let path = PathBuf::from(
|
||||
"/home/chris/dev/lumina/src/rust/core/test.pres",
|
||||
);
|
||||
let save_file = match File::create(path) {
|
||||
Ok(f) => f,
|
||||
Err(e) => panic!("Couldn't create save_file: {e}"),
|
||||
};
|
||||
let mut db = get_db().await;
|
||||
let list = get_items();
|
||||
if let Ok(json) = process_service_items(&list, &mut db).await {
|
||||
if let Ok(json) = process_service_items(&list, &mut db).await
|
||||
{
|
||||
println!("{:?}", json);
|
||||
match store_service_items(&list, &mut db, &save_file, &json).await {
|
||||
match store_service_items(
|
||||
&list, &mut db, &save_file, &json,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => assert!(true),
|
||||
Err(e) => panic!("There was an error: {e}"),
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@ use sqlx::{query_as, SqliteConnection};
|
|||
use std::path::PathBuf;
|
||||
use tracing::error;
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, PartialEq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct Image {
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
|
@ -16,7 +18,7 @@ impl Model<Image> {
|
|||
pub fn load_from_db(&mut self) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query_as!(Image, r#"SELECT title as "title!", filePath as "path!", id as "id: i32" from images"#).fetch_all(&mut self.db).await;
|
||||
let result = query_as!(Image, r#"SELECT title as "title!", file_path as "path!", id as "id: i32" from images"#).fetch_all(&mut self.db).await;
|
||||
match result {
|
||||
Ok(v) => {
|
||||
for image in v.into_iter() {
|
||||
|
@ -29,9 +31,11 @@ impl Model<Image> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn get_image_from_db(database_id: i32, db: &mut SqliteConnection) -> Result<Image> {
|
||||
Ok(query_as!(Image, r#"SELECT title as "title!", filePath as "path!", id as "id: i32" from images where id = ?"#, database_id).fetch_one(db).await?)
|
||||
pub async fn get_image_from_db(
|
||||
database_id: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Image> {
|
||||
Ok(query_as!(Image, r#"SELECT title as "title!", file_path as "path!", id as "id: i32" from images where id = ?"#, database_id).fetch_one(db).await?)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -67,7 +71,10 @@ mod test {
|
|||
let new_image = test_image("A newer image".into());
|
||||
match result {
|
||||
Ok(_) => {
|
||||
assert_eq!(&image, image_model.find(|i| i.id == 0).unwrap());
|
||||
assert_eq!(
|
||||
&image,
|
||||
image_model.find(|i| i.id == 0).unwrap()
|
||||
);
|
||||
assert_ne!(
|
||||
&new_image,
|
||||
image_model.find(|i| i.id == 0).unwrap()
|
||||
|
|
|
@ -4,7 +4,9 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::presentations::PresKind;
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub enum ServiceItemKind {
|
||||
#[default]
|
||||
Song,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
pub mod file;
|
||||
pub mod images;
|
||||
pub mod kinds;
|
||||
pub mod model;
|
||||
|
@ -6,4 +7,3 @@ pub mod service_items;
|
|||
pub mod slides;
|
||||
pub mod songs;
|
||||
pub mod videos;
|
||||
pub mod file;
|
||||
|
|
|
@ -36,8 +36,7 @@ impl<T> Model<T> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_item(&self, index: i32) -> Option<&T>
|
||||
{
|
||||
pub fn get_item(&self, index: i32) -> Option<&T> {
|
||||
self.items.get(index as usize)
|
||||
}
|
||||
|
||||
|
@ -60,10 +59,8 @@ impl<T> Default for Model<T> {
|
|||
items: vec![],
|
||||
db: {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
get_db().await
|
||||
})
|
||||
}
|
||||
rt.block_on(async { get_db().await })
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,9 +71,7 @@ pub async fn get_db() -> SqliteConnection {
|
|||
data.push("library-db.sqlite3");
|
||||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
SqliteConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("problems")
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
}
|
||||
|
||||
pub trait Modeling {
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
use std::path::PathBuf;
|
||||
use color_eyre::eyre::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{prelude::FromRow, query, sqlite::SqliteRow, Row, SqliteConnection};
|
||||
use sqlx::{
|
||||
prelude::FromRow, query, sqlite::SqliteRow, Row, SqliteConnection,
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
use tracing::error;
|
||||
|
||||
use crate::model::Model;
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub enum PresKind {
|
||||
Html,
|
||||
#[default]
|
||||
|
@ -14,7 +18,9 @@ pub enum PresKind {
|
|||
Generic,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct Presentation {
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
|
@ -57,7 +63,7 @@ impl Model<Presentation> {
|
|||
pub fn load_from_db(&mut self) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!(r#"SELECT id as "id: i32", title, filePath as "path", html from presentations"#).fetch_all(&mut self.db).await;
|
||||
let result = query!(r#"SELECT id as "id: i32", title, file_path as "path", html from presentations"#).fetch_all(&mut self.db).await;
|
||||
match result {
|
||||
Ok(v) => {
|
||||
for presentation in v.into_iter() {
|
||||
|
@ -79,8 +85,11 @@ impl Model<Presentation> {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn get_presentation_from_db(database_id: i32, db: &mut SqliteConnection) -> Result<Presentation> {
|
||||
let row = query(r#"SELECT id as "id: i32", title, filePath as "path", html from presentations where id = $1"#).bind(database_id).fetch_one(db).await?;
|
||||
pub async fn get_presentation_from_db(
|
||||
database_id: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Presentation> {
|
||||
let row = query(r#"SELECT id as "id: i32", title, file_path as "path", html from presentations where id = $1"#).bind(database_id).fetch_one(db).await?;
|
||||
Ok(Presentation::from_row(&row)?)
|
||||
}
|
||||
|
||||
|
@ -111,7 +120,9 @@ mod test {
|
|||
let mut presentation_model: Model<Presentation> =
|
||||
Model::default();
|
||||
presentation_model.load_from_db();
|
||||
if let Some(presentation) = presentation_model.find(|p| p.id == 54) {
|
||||
if let Some(presentation) =
|
||||
presentation_model.find(|p| p.id == 54)
|
||||
{
|
||||
let test_presentation = test_presentation();
|
||||
assert_eq!(&test_presentation, presentation);
|
||||
} else {
|
||||
|
|
|
@ -52,7 +52,9 @@ impl From<&Image> for ServiceItem {
|
|||
impl From<&Presentation> for ServiceItem {
|
||||
fn from(presentation: &Presentation) -> Self {
|
||||
Self {
|
||||
kind: ServiceItemKind::Presentation(presentation.kind.clone()),
|
||||
kind: ServiceItemKind::Presentation(
|
||||
presentation.kind.clone(),
|
||||
),
|
||||
database_id: presentation.id,
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -60,7 +62,10 @@ impl From<&Presentation> for ServiceItem {
|
|||
}
|
||||
|
||||
impl ServiceItemModel {
|
||||
fn add_item(&mut self, item: impl Into<ServiceItem>) -> Result<()> {
|
||||
fn add_item(
|
||||
&mut self,
|
||||
item: impl Into<ServiceItem>,
|
||||
) -> Result<()> {
|
||||
let service_item: ServiceItem = item.into();
|
||||
self.items.push(service_item);
|
||||
Ok(())
|
||||
|
@ -94,7 +99,6 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
pub fn test_service_item() {
|
||||
let song = test_song();
|
||||
|
@ -104,10 +108,16 @@ mod test {
|
|||
let mut service_model = ServiceItemModel::default();
|
||||
match service_model.add_item(&song) {
|
||||
Ok(_) => {
|
||||
assert_eq!(ServiceItemKind::Song, service_model.items[0].kind);
|
||||
assert_eq!(ServiceItemKind::Presentation(PresKind::Html), pres_item.kind);
|
||||
assert_eq!(
|
||||
ServiceItemKind::Song,
|
||||
service_model.items[0].kind
|
||||
);
|
||||
assert_eq!(
|
||||
ServiceItemKind::Presentation(PresKind::Html),
|
||||
pres_item.kind
|
||||
);
|
||||
assert_eq!(service_item, service_model.items[0]);
|
||||
},
|
||||
}
|
||||
Err(e) => panic!("Problem adding item: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use std::{error::Error, fmt::Display, path::{Path, PathBuf}};
|
||||
use std::{
|
||||
error::Error,
|
||||
fmt::Display,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use color_eyre::eyre::{eyre, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -10,7 +14,9 @@ use crate::{
|
|||
presentations::Presentation, songs::Song, videos::Video,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub enum TextAlignment {
|
||||
TopLeft,
|
||||
TopCenter,
|
||||
|
@ -24,7 +30,9 @@ pub enum TextAlignment {
|
|||
BottomRight,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct Background {
|
||||
pub path: PathBuf,
|
||||
pub kind: BackgroundKind,
|
||||
|
@ -36,7 +44,7 @@ impl TryFrom<String> for Background {
|
|||
let value = value.trim_start_matches("file://");
|
||||
let path = PathBuf::from(value);
|
||||
if !path.exists() {
|
||||
return Err(ParseError::DoesNotExist)
|
||||
return Err(ParseError::DoesNotExist);
|
||||
}
|
||||
let extension = value.rsplit_once('.').unwrap_or_default();
|
||||
match extension.1 {
|
||||
|
@ -106,11 +114,15 @@ impl DatabaseError for ParseError {
|
|||
todo!()
|
||||
}
|
||||
|
||||
fn as_error_mut(&mut self) -> &mut (dyn Error + Send + Sync + 'static) {
|
||||
fn as_error_mut(
|
||||
&mut self,
|
||||
) -> &mut (dyn Error + Send + Sync + 'static) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn into_error(self: Box<Self>) -> Box<dyn Error + Send + Sync + 'static> {
|
||||
fn into_error(
|
||||
self: Box<Self>,
|
||||
) -> Box<dyn Error + Send + Sync + 'static> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
@ -128,15 +140,15 @@ impl Display for ParseError {
|
|||
Self::NonBackgroundFile => {
|
||||
"The file is not a recognized image or video type"
|
||||
}
|
||||
Self::DoesNotExist => {
|
||||
"This file doesn't exist"
|
||||
}
|
||||
Self::DoesNotExist => "This file doesn't exist",
|
||||
};
|
||||
write!(f, "Error: {message}")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub enum BackgroundKind {
|
||||
#[default]
|
||||
Image,
|
||||
|
|
|
@ -2,7 +2,10 @@ use std::{collections::HashMap, path::PathBuf};
|
|||
|
||||
use color_eyre::eyre::{eyre, Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{query, query_as, sqlite::SqliteRow, FromRow, Row, SqliteConnection};
|
||||
use sqlx::{
|
||||
query, query_as, sqlite::SqliteRow, FromRow, Row,
|
||||
SqliteConnection,
|
||||
};
|
||||
use tracing::{debug, error};
|
||||
|
||||
use crate::{
|
||||
|
@ -10,7 +13,9 @@ use crate::{
|
|||
slides::{Background, TextAlignment},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct Song {
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
|
@ -56,17 +61,24 @@ impl FromRow<'_, SqliteRow> for Song {
|
|||
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()) {
|
||||
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,
|
||||
("center", "center") => {
|
||||
TextAlignment::MiddleCenter
|
||||
}
|
||||
("center", "bottom") => {
|
||||
TextAlignment::BottomCenter
|
||||
}
|
||||
("right", "top") => TextAlignment::TopRight,
|
||||
("right", "center") => TextAlignment::MiddleRight,
|
||||
("right", "bottom") => TextAlignment::BottomRight,
|
||||
_ => TextAlignment::MiddleCenter
|
||||
_ => TextAlignment::MiddleCenter,
|
||||
}
|
||||
}),
|
||||
font: row.try_get(6)?,
|
||||
|
@ -75,19 +87,20 @@ impl FromRow<'_, SqliteRow> for Song {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn get_song_from_db(index: i32, db: &mut SqliteConnection) -> Result<Song> {
|
||||
let row = 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(db).await?;
|
||||
pub async fn get_song_from_db(
|
||||
index: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Song> {
|
||||
let row = query(r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment 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(db).await?;
|
||||
Ok(Song::from_row(&row)?)
|
||||
}
|
||||
|
||||
|
||||
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 verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment 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() {
|
||||
|
|
|
@ -5,7 +5,9 @@ use sqlx::{query_as, SqliteConnection};
|
|||
use std::path::PathBuf;
|
||||
use tracing::error;
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, PartialEq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct Video {
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
|
@ -19,7 +21,7 @@ impl Model<Video> {
|
|||
pub fn load_from_db(&mut self) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query_as!(Video, r#"SELECT title as "title!", filePath as "path!", startTime as "start_time!: f32", endTime as "end_time!: f32", loop as "looping!", id as "id: i32" from videos"#).fetch_all(&mut self.db).await;
|
||||
let result = query_as!(Video, r#"SELECT title as "title!", file_path as "path!", start_time as "start_time!: f32", end_time as "end_time!: f32", loop as "looping!", id as "id: i32" from videos"#).fetch_all(&mut self.db).await;
|
||||
match result {
|
||||
Ok(v) => {
|
||||
for video in v.into_iter() {
|
||||
|
@ -32,12 +34,13 @@ impl Model<Video> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn get_video_from_db(database_id: i32, db: &mut SqliteConnection) -> Result<Video> {
|
||||
Ok(query_as!(Video, r#"SELECT title as "title!", filePath as "path!", startTime as "start_time!: f32", endTime as "end_time!: f32", loop as "looping!", id as "id: i32" from videos where id = ?"#, database_id).fetch_one(db).await?)
|
||||
pub async fn get_video_from_db(
|
||||
database_id: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Video> {
|
||||
Ok(query_as!(Video, r#"SELECT title as "title!", file_path as "path!", start_time as "start_time!: f32", end_time as "end_time!: f32", loop as "looping!", id as "id: i32" from videos where id = ?"#, database_id).fetch_one(db).await?)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
@ -71,7 +74,10 @@ mod test {
|
|||
let new_video = test_video("A newer video".into());
|
||||
match result {
|
||||
Ok(_) => {
|
||||
assert_eq!(&video, video_model.find(|v| v.id == 0).unwrap());
|
||||
assert_eq!(
|
||||
&video,
|
||||
video_model.find(|v| v.id == 0).unwrap()
|
||||
);
|
||||
assert_ne!(
|
||||
&new_video,
|
||||
video_model.find(|v| v.id == 0).unwrap()
|
||||
|
|
|
@ -181,7 +181,7 @@ pub struct ImageModelRust {
|
|||
highest_id: i32,
|
||||
images: Vec<Image>,
|
||||
inner_images: Vec<Image>,
|
||||
db: SqliteConnection
|
||||
db: SqliteConnection,
|
||||
}
|
||||
|
||||
impl Default for ImageModelRust {
|
||||
|
@ -199,9 +199,11 @@ impl Default for ImageModelRust {
|
|||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
rt.block_on(async {
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
SqliteConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("problems")
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -215,11 +217,13 @@ pub fn get_image(index: i32) -> color_eyre::Result<Image> {
|
|||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
rt.block_on(async {
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
SqliteConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("problems")
|
||||
})
|
||||
};
|
||||
rt.block_on(async {
|
||||
let result = query_as!(Image, r#"SELECT id as "id: i32", title as "title!", filePath as "path!" from images where id = ?"#, index).fetch_one(&mut db).await?;
|
||||
let result = query_as!(Image, r#"SELECT id as "id: i32", title as "title!", file_path as "path!" from images where id = ?"#, index).fetch_one(&mut db).await?;
|
||||
Ok(result)
|
||||
})
|
||||
}
|
||||
|
@ -236,7 +240,7 @@ impl image_model::ImageModel {
|
|||
pub fn setup(mut self: Pin<&mut Self>) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query_as!(Image, r#"SELECT id as "id: i32", title as "title!", filePath as "path!" from images"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
||||
let result = query_as!(Image, r#"SELECT id as "id: i32", title as "title!", file_path as "path!" from images"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
||||
match result {
|
||||
Ok(i) => i.into_iter().for_each(|i| self.as_mut().add_image(i)),
|
||||
Err(e) => error!("There was an error in converting songs: {e}"),
|
||||
|
@ -251,7 +255,10 @@ impl image_model::ImageModel {
|
|||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
rt.block_on(async {
|
||||
let result = query!("delete from images where id = ?", index).execute(&mut self.as_mut().rust_mut().db).await;
|
||||
let result =
|
||||
query!("delete from images where id = ?", index)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
Ok(_i) => {
|
||||
unsafe {
|
||||
|
@ -308,7 +315,7 @@ impl image_model::ImageModel {
|
|||
rt.block_on(async {
|
||||
let image_title = image_title.to_string();
|
||||
let image_path = image_path.to_string();
|
||||
let result = query!(r#"INSERT into images (id, title, filePath) VALUES (?, ?, ?)"#,
|
||||
let result = query!(r#"INSERT into images (id, title, file_path) VALUES (?, ?, ?)"#,
|
||||
image_id,
|
||||
image_title,
|
||||
image_path)
|
||||
|
@ -367,7 +374,11 @@ impl image_model::ImageModel {
|
|||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let title = updated_title.to_string();
|
||||
let result = query!("UPDATE images SET title = ? where id = ?", title, index)
|
||||
let result = query!(
|
||||
"UPDATE images SET title = ? where id = ?",
|
||||
title,
|
||||
index
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
|
@ -380,9 +391,11 @@ impl image_model::ImageModel {
|
|||
.filter(|x| x.id == index)
|
||||
{
|
||||
image.title = title.clone();
|
||||
debug!(title = image.title,
|
||||
debug!(
|
||||
title = image.title,
|
||||
title = title,
|
||||
"updated image title");
|
||||
"updated image title"
|
||||
);
|
||||
}
|
||||
self.as_mut().data_changed(
|
||||
model_index,
|
||||
|
@ -394,7 +407,7 @@ impl image_model::ImageModel {
|
|||
Err(e) => {
|
||||
error!("Error connecting to db: {e}");
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
true
|
||||
|
@ -414,7 +427,11 @@ impl image_model::ImageModel {
|
|||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let updated_path = updated_path.to_string();
|
||||
let result = query!("UPDATE images SET filePath = ? where id = ?", updated_path, index)
|
||||
let result = query!(
|
||||
"UPDATE images SET file_path = ? where id = ?",
|
||||
updated_path,
|
||||
index
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
|
@ -427,9 +444,11 @@ impl image_model::ImageModel {
|
|||
.filter(|x| x.id == index)
|
||||
{
|
||||
image.path = updated_path.clone();
|
||||
debug!(title = image.title,
|
||||
debug!(
|
||||
title = image.title,
|
||||
path = updated_path,
|
||||
"updated image path");
|
||||
"updated image path"
|
||||
);
|
||||
}
|
||||
self.as_mut().data_changed(
|
||||
model_index,
|
||||
|
@ -441,7 +460,7 @@ impl image_model::ImageModel {
|
|||
Err(e) => {
|
||||
error!("Error connecting to db: {e}");
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
true
|
||||
|
|
|
@ -8,10 +8,9 @@ pub mod service_item_model;
|
|||
pub mod settings;
|
||||
pub mod slide_model;
|
||||
pub mod slide_object;
|
||||
pub mod slide_types;
|
||||
pub mod songs;
|
||||
pub mod utils;
|
||||
pub mod video_model;
|
||||
pub mod ytdl;
|
||||
pub mod slide_types;
|
||||
// pub mod core;
|
||||
// mod video_thumbnail;
|
||||
|
|
|
@ -4,7 +4,6 @@ use cxx_qt_lib::{QString, QStringList};
|
|||
use obws::responses::scenes::{CurrentProgramScene, Scenes};
|
||||
use obws::Client;
|
||||
|
||||
|
||||
use std::{error::Error, pin::Pin};
|
||||
use tracing::{debug, error};
|
||||
|
||||
|
@ -22,7 +21,10 @@ impl fmt::Debug for Obs {
|
|||
f.debug_struct("Client")
|
||||
.field("scenes", &self.scenes)
|
||||
.field("client", &self.client.is_some())
|
||||
.field("current_program_scene", &self.current_program_scene)
|
||||
.field(
|
||||
"current_program_scene",
|
||||
&self.current_program_scene,
|
||||
)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
@ -37,8 +39,6 @@ impl Clone for Obs {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl Obs {
|
||||
pub async fn new() -> Result<Self, Box<dyn Error>> {
|
||||
let client =
|
||||
|
|
|
@ -208,7 +208,7 @@ pub struct PresentationModelRust {
|
|||
highest_id: i32,
|
||||
presentations: Vec<Presentation>,
|
||||
inner_presentations: Vec<Presentation>,
|
||||
db: SqliteConnection
|
||||
db: SqliteConnection,
|
||||
}
|
||||
|
||||
impl Default for PresentationModelRust {
|
||||
|
@ -226,14 +226,18 @@ impl Default for PresentationModelRust {
|
|||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
rt.block_on(async {
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
SqliteConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("problems")
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_presentation(index: i32) -> color_eyre::Result<Presentation> {
|
||||
pub fn get_presentation(
|
||||
index: i32,
|
||||
) -> color_eyre::Result<Presentation> {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let mut db = {
|
||||
let mut data = dirs::data_local_dir().unwrap();
|
||||
|
@ -242,11 +246,13 @@ pub fn get_presentation(index: i32) -> color_eyre::Result<Presentation> {
|
|||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
rt.block_on(async {
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
SqliteConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("problems")
|
||||
})
|
||||
};
|
||||
rt.block_on(async {
|
||||
let result = query_as!(Presentation, r#"SELECT id as "id: i32", title as "title!", filePath as "path!", html as "html!", pageCount as "page_count!: i32" from presentations where id = ?"#, index).fetch_one(&mut db).await?;
|
||||
let result = query_as!(Presentation, r#"SELECT id as "id: i32", title as "title!", file_path as "path!", html as "html!", pageCount as "page_count!: i32" from presentations where id = ?"#, index).fetch_one(&mut db).await?;
|
||||
Ok(result)
|
||||
})
|
||||
}
|
||||
|
@ -263,7 +269,7 @@ impl presentation_model::PresentationModel {
|
|||
pub fn setup(mut self: Pin<&mut Self>) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query_as!(Presentation, r#"SELECT id as "id: i32", title as "title!", filePath as "path!", html as "html!", pageCount as "page_count!: i32" from presentations"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
||||
let result = query_as!(Presentation, r#"SELECT id as "id: i32", title as "title!", file_path as "path!", html as "html!", pageCount as "page_count!: i32" from presentations"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
||||
match result {
|
||||
Ok(p) => p.into_iter().for_each(|p| self.as_mut().add_presentation(p)),
|
||||
Err(e) => error!("There was an error in converting songs: {e}"),
|
||||
|
@ -278,7 +284,12 @@ impl presentation_model::PresentationModel {
|
|||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
rt.block_on(async {
|
||||
let result = query!("delete from presentations where id = ?", index).execute(&mut self.as_mut().rust_mut().db).await;
|
||||
let result = query!(
|
||||
"delete from presentations where id = ?",
|
||||
index
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
Ok(_i) => {
|
||||
unsafe {
|
||||
|
@ -365,7 +376,7 @@ impl presentation_model::PresentationModel {
|
|||
rt.block_on(async {
|
||||
let presentation_title = presentation_title.to_string();
|
||||
let presentation_path = presentation_path.to_string();
|
||||
let result = query!(r#"INSERT into presentations (id, title, filePath, html, pageCount) VALUES (?, ?, ?, ?, ?)"#,
|
||||
let result = query!(r#"INSERT into presentations (id, title, file_path, html, pageCount) VALUES (?, ?, ?, ?, ?)"#,
|
||||
presentation_id,
|
||||
presentation_title,
|
||||
presentation_path,
|
||||
|
@ -503,7 +514,11 @@ impl presentation_model::PresentationModel {
|
|||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let title = updated_title.to_string();
|
||||
let result = query!("UPDATE presentations SET title = ? where id = ?", title, index)
|
||||
let result = query!(
|
||||
"UPDATE presentations SET title = ? where id = ?",
|
||||
title,
|
||||
index
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
|
@ -516,9 +531,11 @@ impl presentation_model::PresentationModel {
|
|||
.filter(|x| x.id == index)
|
||||
{
|
||||
presentation.title = title.clone();
|
||||
debug!(title = presentation.title,
|
||||
debug!(
|
||||
title = presentation.title,
|
||||
title = title,
|
||||
"updated presentation title");
|
||||
"updated presentation title"
|
||||
);
|
||||
}
|
||||
self.as_mut().data_changed(
|
||||
model_index,
|
||||
|
@ -530,7 +547,7 @@ impl presentation_model::PresentationModel {
|
|||
Err(e) => {
|
||||
error!("Error connecting to db: {e}");
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
true
|
||||
|
@ -549,7 +566,11 @@ impl presentation_model::PresentationModel {
|
|||
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!("UPDATE presentations SET pageCount = ? where id = ?", updated_page_count, index)
|
||||
let result = query!(
|
||||
"UPDATE presentations SET pageCount = ? where id = ?",
|
||||
updated_page_count,
|
||||
index
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
|
@ -561,10 +582,13 @@ impl presentation_model::PresentationModel {
|
|||
.iter_mut()
|
||||
.filter(|x| x.id == index)
|
||||
{
|
||||
presentation.page_count = updated_page_count.clone();
|
||||
debug!(title = presentation.title,
|
||||
presentation.page_count =
|
||||
updated_page_count.clone();
|
||||
debug!(
|
||||
title = presentation.title,
|
||||
page_count = updated_page_count,
|
||||
"updated presentation page_count");
|
||||
"updated presentation page_count"
|
||||
);
|
||||
}
|
||||
self.as_mut().data_changed(
|
||||
model_index,
|
||||
|
@ -576,7 +600,7 @@ impl presentation_model::PresentationModel {
|
|||
Err(e) => {
|
||||
error!("Error connecting to db: {e}");
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
true
|
||||
|
|
|
@ -271,7 +271,12 @@ mod service_item_model {
|
|||
}
|
||||
}
|
||||
|
||||
use self::service_item_model::{
|
||||
QHash_i32_QByteArray, QMap_QString_QVariant, QVector_i32,
|
||||
ServiceRoles,
|
||||
};
|
||||
use crate::service_item_model::service_item_model::QList_QString;
|
||||
use crate::slide_types::SlideType;
|
||||
use crate::songs::song_model::{get_song, Song};
|
||||
use crate::{image_model, presentation_model, video_model};
|
||||
use cxx_qt::{CxxQtType, Threading};
|
||||
|
@ -279,6 +284,7 @@ use cxx_qt_lib::{
|
|||
QByteArray, QModelIndex, QString, QStringList, QUrl, QVariant,
|
||||
};
|
||||
use dirs;
|
||||
// use lumina_core::service_items::ServiceItem as SI;
|
||||
use serde_json::{json, Value};
|
||||
use std::iter;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -288,12 +294,6 @@ use std::{fs, println};
|
|||
use tar::{Archive, Builder};
|
||||
use tracing::{debug, error};
|
||||
use zstd::{Decoder, Encoder};
|
||||
use self::service_item_model::{
|
||||
QHash_i32_QByteArray, QMap_QString_QVariant, QVector_i32,
|
||||
ServiceRoles,
|
||||
};
|
||||
use crate::slide_types::SlideType;
|
||||
use lumina_core::service_items::ServiceItem as SI;
|
||||
|
||||
use super::service_item_model::service_item_model::ServiceItemModel;
|
||||
|
||||
|
@ -377,7 +377,9 @@ impl service_item_model::ServiceItemModel {
|
|||
pub fn remove_items(mut self: Pin<&mut Self>) {
|
||||
let mut indices = vec![];
|
||||
let mut items = self.service_items.clone();
|
||||
for (index, _item) in items.iter_mut().enumerate().filter(|(_y, x)| x.selected) {
|
||||
for (index, _item) in
|
||||
items.iter_mut().enumerate().filter(|(_y, x)| x.selected)
|
||||
{
|
||||
let index = index as i32;
|
||||
indices.push(index);
|
||||
}
|
||||
|
@ -436,7 +438,10 @@ impl service_item_model::ServiceItemModel {
|
|||
self.as_mut().end_insert_rows();
|
||||
}
|
||||
debug!("ADDING: {:?}", &service_item);
|
||||
self.as_mut().item_added(&service_item.database_id.unwrap_or_default(), &QString::from(&service_item.ty.to_string()));
|
||||
self.as_mut().item_added(
|
||||
&service_item.database_id.unwrap_or_default(),
|
||||
&QString::from(&service_item.ty.to_string()),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn insert_item(
|
||||
|
@ -475,7 +480,11 @@ impl service_item_model::ServiceItemModel {
|
|||
self.as_mut().end_insert_rows();
|
||||
}
|
||||
debug!("ADDING: {:?}", &service_item);
|
||||
self.as_mut().item_inserted(&index, &service_item.database_id.unwrap_or_default(), &QString::from(&service_item.ty.to_string()));
|
||||
self.as_mut().item_inserted(
|
||||
&index,
|
||||
&service_item.database_id.unwrap_or_default(),
|
||||
&QString::from(&service_item.ty.to_string()),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn get_item(
|
||||
|
@ -876,8 +885,7 @@ impl service_item_model::ServiceItemModel {
|
|||
Some(name) => {
|
||||
println!("audio: {:?}", &name);
|
||||
if name.to_str().unwrap() != "temp" {
|
||||
flat_audio =
|
||||
name.to_str().unwrap()
|
||||
flat_audio = name.to_str().unwrap()
|
||||
} else {
|
||||
flat_audio = "";
|
||||
}
|
||||
|
@ -961,12 +969,18 @@ impl service_item_model::ServiceItemModel {
|
|||
debug!(time = ?now.elapsed(), "file written");
|
||||
std::thread::spawn(move || {
|
||||
debug!(time = ?now.elapsed(), "idk");
|
||||
let dir = fs::read_dir(&temp_dir).expect("idk");
|
||||
let dir = fs::read_dir(&temp_dir)
|
||||
.expect("idk");
|
||||
for (index, file) in dir.enumerate() {
|
||||
if let Ok(file) = file {
|
||||
let file_name = file.file_name();
|
||||
let file_name =
|
||||
file.file_name();
|
||||
debug!(?file, ?file_name);
|
||||
let mut file = std::fs::File::open(file.path()).expect("missing file");
|
||||
let mut file =
|
||||
std::fs::File::open(
|
||||
file.path(),
|
||||
)
|
||||
.expect("missing file");
|
||||
tar.append_file(file_name, &mut file).expect("Error in moving file to tar");
|
||||
thread.queue(move |mut service| {
|
||||
service
|
||||
|
@ -977,10 +991,11 @@ impl service_item_model::ServiceItemModel {
|
|||
)
|
||||
}).expect("Problem queuing on cxx thread");
|
||||
}
|
||||
|
||||
}
|
||||
if let Ok(encoder) = tar.into_inner() {
|
||||
if let Ok(done) = encoder.finish() {
|
||||
if let Ok(encoder) = tar.into_inner()
|
||||
{
|
||||
if let Ok(done) = encoder.finish()
|
||||
{
|
||||
debug!(time = ?now.elapsed(), ?done, "tar finished");
|
||||
thread.queue(move |mut service| {
|
||||
service.as_mut().set_save_progress(100.0);
|
||||
|
@ -1000,9 +1015,7 @@ impl service_item_model::ServiceItemModel {
|
|||
}
|
||||
} else {
|
||||
fs::remove_dir_all(&temp_dir)
|
||||
.expect(
|
||||
"error in removal",
|
||||
);
|
||||
.expect("error in removal");
|
||||
false
|
||||
}
|
||||
});
|
||||
|
@ -1058,7 +1071,9 @@ impl service_item_model::ServiceItemModel {
|
|||
if !file_path.exists() {
|
||||
match file.unpack_in(&datadir) {
|
||||
Ok(_t) => (),
|
||||
Err(e) => error!("Error unpacking archive: {}", e),
|
||||
Err(e) => {
|
||||
error!("Error unpacking archive: {}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1341,7 +1356,9 @@ impl service_item_model::ServiceItemModel {
|
|||
let mut vector_roles = QVector_i32::default();
|
||||
vector_roles.append(self.as_ref().get_role(role));
|
||||
if let Some(index) =
|
||||
self.as_ref().service_items.iter().position(|x| x.database_id.unwrap_or_default() == item_id)
|
||||
self.as_ref().service_items.iter().position(|x| {
|
||||
x.database_id.unwrap_or_default() == item_id
|
||||
})
|
||||
{
|
||||
let model_index = self.as_ref().index(
|
||||
index as i32,
|
||||
|
@ -1355,7 +1372,6 @@ impl service_item_model::ServiceItemModel {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn load_last_saved(self: Pin<&mut Self>) -> bool {
|
||||
todo!();
|
||||
// Don't actually need
|
||||
|
@ -1394,9 +1410,9 @@ impl service_item_model::ServiceItemModel {
|
|||
ServiceRoles::Name => {
|
||||
QVariant::from(&service_item.name)
|
||||
}
|
||||
ServiceRoles::Type => {
|
||||
QVariant::from(&QString::from(&service_item.ty.clone().to_string()))
|
||||
}
|
||||
ServiceRoles::Type => QVariant::from(&QString::from(
|
||||
&service_item.ty.clone().to_string(),
|
||||
)),
|
||||
ServiceRoles::Audio => {
|
||||
QVariant::from(&service_item.audio)
|
||||
}
|
||||
|
@ -1433,9 +1449,9 @@ impl service_item_model::ServiceItemModel {
|
|||
ServiceRoles::VideoEndTime => {
|
||||
QVariant::from(&service_item.video_end_time)
|
||||
}
|
||||
ServiceRoles::Id => {
|
||||
QVariant::from(&service_item.database_id.unwrap_or_default())
|
||||
}
|
||||
ServiceRoles::Id => QVariant::from(
|
||||
&service_item.database_id.unwrap_or_default(),
|
||||
),
|
||||
_ => QVariant::default(),
|
||||
};
|
||||
}
|
||||
|
@ -1503,22 +1519,21 @@ impl service_item_model::ServiceItemModel {
|
|||
ServiceRoles::VideoEndTime.repr,
|
||||
QByteArray::from("videoEndTime"),
|
||||
);
|
||||
roles.insert(
|
||||
ServiceRoles::Id.repr,
|
||||
QByteArray::from("id"),
|
||||
);
|
||||
roles.insert(ServiceRoles::Id.repr, QByteArray::from("id"));
|
||||
roles
|
||||
}
|
||||
|
||||
pub fn row_count(&self, _parent: &QModelIndex) -> i32 {
|
||||
|
||||
// println!("row count is {cnt}");
|
||||
self.service_items.len() as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl ServiceItemModelRust {
|
||||
pub fn save(_model: Pin<&mut ServiceItemModel>, _file: QUrl) -> bool {
|
||||
pub fn save(
|
||||
_model: Pin<&mut ServiceItemModel>,
|
||||
_file: QUrl,
|
||||
) -> bool {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,11 @@ pub mod slide_model {
|
|||
include!("cxx-qt-lib/qlist.h");
|
||||
type QList_QString = cxx_qt_lib::QList<QString>;
|
||||
include!("cxx-qt-gen/slide_object.cxxqt.h");
|
||||
type SlideObject = crate::slide_object::slide_object::SlideObject;
|
||||
type SlideObject =
|
||||
crate::slide_object::slide_object::SlideObject;
|
||||
include!("cxx-qt-gen/song_model.cxxqt.h");
|
||||
type SongModel = crate::songs::song_model::song_model::SongModel;
|
||||
type SongModel =
|
||||
crate::songs::song_model::song_model::SongModel;
|
||||
include!("cxx-qt-gen/video_model.cxxqt.h");
|
||||
type VideoModel = crate::video_model::video_model::VideoModel;
|
||||
include!("cxx-qt-gen/image_model.cxxqt.h");
|
||||
|
@ -229,26 +231,29 @@ pub mod slide_model {
|
|||
|
||||
use crate::image_model::image_model::ImageModel;
|
||||
use crate::image_model::{self, Image, ImageModelRust};
|
||||
use crate::obs::Obs;
|
||||
use crate::presentation_model::presentation_model::PresentationModel;
|
||||
use crate::presentation_model::{self, Presentation, PresentationModelRust};
|
||||
use crate::presentation_model::{
|
||||
self, Presentation, PresentationModelRust,
|
||||
};
|
||||
use crate::slide_model::slide_model::QList_QString;
|
||||
use crate::songs::song_model::song_model::{self, SongModel};
|
||||
use crate::songs::song_model::{get_song, Song, SongModelRust};
|
||||
use crate::video_model::video_model::VideoModel;
|
||||
use crate::video_model::{self, Video, VideoModelRust};
|
||||
use crate::{ffmpeg, slide_types::SlideType};
|
||||
use crate::obs::Obs;
|
||||
use crate::slide_model::slide_model::QList_QString;
|
||||
use color_eyre::eyre::Result;
|
||||
use color_eyre::Section;
|
||||
use cxx_qt::{CxxQtType, Threading};
|
||||
use cxx_qt_lib::{
|
||||
CaseSensitivity, QByteArray, QList, QModelIndex, QString, QStringList, QVariant
|
||||
CaseSensitivity, QByteArray, QList, QModelIndex, QString,
|
||||
QStringList, QVariant,
|
||||
};
|
||||
use slide_model::SlideObject;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Display};
|
||||
use std::fmt::Display;
|
||||
use std::{path::PathBuf, pin::Pin};
|
||||
use tracing::{debug, error};
|
||||
use tracing::{debug, error, warn};
|
||||
|
||||
use self::slide_model::{
|
||||
QHash_i32_QByteArray, QMap_QString_QVariant, QVector_i32,
|
||||
|
@ -336,45 +341,40 @@ impl Slide {
|
|||
fn slides_from_song(song: Song) -> Result<Vec<Self>> {
|
||||
let list = song.get_lyric_list();
|
||||
let total = list.len();
|
||||
let mut vector: Vec<Slide> = vec![];
|
||||
list.iter().map(|t| t.to_string()).enumerate()
|
||||
.for_each(|(i, s)| {
|
||||
if song.background_type == "image" {
|
||||
vector.push(
|
||||
Self {
|
||||
let vector = list
|
||||
.iter()
|
||||
.map(|t| {
|
||||
let s = t.to_string();
|
||||
warn!(s);
|
||||
s
|
||||
})
|
||||
.enumerate()
|
||||
.map(|(i, s)| Self {
|
||||
text: s,
|
||||
ty: SlideType::Song,
|
||||
audio: song.audio.clone(),
|
||||
image_background: song.background.clone(),
|
||||
video_background: "".to_owned(),
|
||||
htext_alignment: song.horizontal_text_alignment.clone(),
|
||||
vtext_alignment: song.vertical_text_alignment.clone(),
|
||||
font: song.font.clone(),
|
||||
font_size: song.font_size,
|
||||
slide_count: total as i32,
|
||||
slide_index: i as i32,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
image_background: if song.background_type == "image" {
|
||||
song.background.clone()
|
||||
} else {
|
||||
vector.push(
|
||||
Self {
|
||||
text: s,
|
||||
ty: SlideType::Song,
|
||||
audio: song.audio.clone(),
|
||||
image_background: "".to_owned(),
|
||||
video_background: song.background.clone(),
|
||||
htext_alignment: song.horizontal_text_alignment.clone(),
|
||||
"".into()
|
||||
},
|
||||
video_background: if song.background_type == "video" {
|
||||
song.background.clone()
|
||||
} else {
|
||||
"".to_owned()
|
||||
},
|
||||
htext_alignment: song
|
||||
.horizontal_text_alignment
|
||||
.clone(),
|
||||
vtext_alignment: song.vertical_text_alignment.clone(),
|
||||
font: song.font.clone(),
|
||||
font_size: song.font_size,
|
||||
slide_count: total as i32,
|
||||
slide_index: i as i32,
|
||||
..Default::default()
|
||||
}
|
||||
)
|
||||
}
|
||||
});
|
||||
})
|
||||
.collect();
|
||||
warn!(?vector);
|
||||
Ok(vector)
|
||||
}
|
||||
|
||||
|
@ -395,7 +395,9 @@ impl Slide {
|
|||
})
|
||||
}
|
||||
|
||||
fn slides_from_presentation(presentation: Presentation) -> Result<Vec<Self>> {
|
||||
fn slides_from_presentation(
|
||||
presentation: Presentation,
|
||||
) -> Result<Vec<Self>> {
|
||||
let total = presentation.page_count;
|
||||
let mut slides: Vec<Slide> = vec![];
|
||||
for i in 0..total {
|
||||
|
@ -406,7 +408,7 @@ impl Slide {
|
|||
image_background: presentation.path.clone(),
|
||||
..Default::default()
|
||||
})
|
||||
};
|
||||
}
|
||||
Ok(slides)
|
||||
}
|
||||
}
|
||||
|
@ -456,9 +458,12 @@ impl slide_model::SlideModel {
|
|||
index: i32,
|
||||
) -> bool {
|
||||
let mut vector_roles = QVector_i32::default();
|
||||
vector_roles.append(self.get_role(SlideRoles::VideoThumbnail));
|
||||
vector_roles.append(self.get_role(SlideRoles::VideoBackground));
|
||||
vector_roles.append(self.get_role(SlideRoles::ImageBackground));
|
||||
vector_roles
|
||||
.append(self.get_role(SlideRoles::VideoThumbnail));
|
||||
vector_roles
|
||||
.append(self.get_role(SlideRoles::VideoBackground));
|
||||
vector_roles
|
||||
.append(self.get_role(SlideRoles::ImageBackground));
|
||||
let rc = self.as_ref().count() - 1;
|
||||
let tl = self.as_ref().index(0, 0, &QModelIndex::default());
|
||||
let br = self.as_ref().index(rc, 0, &QModelIndex::default());
|
||||
|
@ -470,7 +475,11 @@ impl slide_model::SlideModel {
|
|||
let path =
|
||||
PathBuf::from(slide.video_background.to_string());
|
||||
let screenshot = ffmpeg::bg_path_from_video(&path);
|
||||
let mut screenshot_string = screenshot.clone().into_os_string().into_string().unwrap_or_default();
|
||||
let mut screenshot_string = screenshot
|
||||
.clone()
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap_or_default();
|
||||
screenshot_string.insert_str(0, "file://");
|
||||
slide.video_thumbnail = screenshot_string;
|
||||
std::thread::spawn(move || {
|
||||
|
@ -616,37 +625,56 @@ impl slide_model::SlideModel {
|
|||
SlideType::Song => {
|
||||
let song = get_song(item_model_id)?;
|
||||
let slides = Slide::slides_from_song(song)?;
|
||||
slides.iter().for_each(|slide| self.as_mut().insert_slide(slide, index));
|
||||
slides.iter().enumerate().for_each(|(i, slide)| {
|
||||
self.as_mut()
|
||||
.insert_slide(slide, index + i as i32)
|
||||
});
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
SlideType::Video => {
|
||||
let video = video_model::get_video(item_model_id)?;
|
||||
self.insert_slide(&Slide::slide_from_video(video)?, index);
|
||||
self.insert_slide(
|
||||
&Slide::slide_from_video(video)?,
|
||||
index,
|
||||
);
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
SlideType::Image => {
|
||||
let result = image_model::get_image(item_model_id);
|
||||
match result {
|
||||
Ok(image) => self.insert_slide(&Slide::slide_from_image(image)?, index),
|
||||
Ok(image) => self.insert_slide(
|
||||
&Slide::slide_from_image(image)?,
|
||||
index,
|
||||
),
|
||||
Err(e) => {
|
||||
e.with_note(|| {
|
||||
format!("This might fail if we are loading the items from a file")
|
||||
});
|
||||
let mut slide = Slide::default();
|
||||
slide.image_background = "qrc:/assets/black.jpg".to_owned();
|
||||
slide.image_background =
|
||||
"qrc:/assets/black.jpg".to_owned();
|
||||
self.insert_slide(&slide, index);
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
SlideType::Content => {
|
||||
todo!();
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
SlideType::Presentation(_) => {
|
||||
let presentation = presentation_model::get_presentation(item_model_id)?;
|
||||
let slides = Slide::slides_from_presentation(presentation)?;
|
||||
slides.iter().for_each(|slide| self.as_mut().insert_slide(slide, slide.slide_index + index));
|
||||
let presentation =
|
||||
presentation_model::get_presentation(
|
||||
item_model_id,
|
||||
)?;
|
||||
let slides =
|
||||
Slide::slides_from_presentation(presentation)?;
|
||||
slides.iter().for_each(|slide| {
|
||||
self.as_mut().insert_slide(
|
||||
slide,
|
||||
slide.slide_index + index,
|
||||
)
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -656,7 +684,7 @@ impl slide_model::SlideModel {
|
|||
self: Pin<&mut Self>,
|
||||
item_model_id: i32,
|
||||
kind: &QString,
|
||||
) -> Result<()>{
|
||||
) -> Result<()> {
|
||||
let index = self.count;
|
||||
self.insert_item_from_service(index, item_model_id, kind)
|
||||
}
|
||||
|
@ -692,7 +720,8 @@ impl slide_model::SlideModel {
|
|||
|
||||
if let Some((i, slide)) = slides_iter
|
||||
.clone()
|
||||
.enumerate().find(|slide| slide.1.service_item_id == source_index)
|
||||
.enumerate()
|
||||
.find(|slide| slide.1.service_item_id == source_index)
|
||||
{
|
||||
debug!(index = i, ?slide);
|
||||
first_slide = i as i32;
|
||||
|
@ -705,11 +734,8 @@ impl slide_model::SlideModel {
|
|||
|
||||
// lets get the dest_slide and count
|
||||
if move_down {
|
||||
if let Some((i, slide)) = slides_iter
|
||||
.clone()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.find(|slide| {
|
||||
if let Some((i, slide)) =
|
||||
slides_iter.clone().enumerate().rev().find(|slide| {
|
||||
slide.1.service_item_id == destination_index
|
||||
})
|
||||
{
|
||||
|
@ -724,9 +750,8 @@ impl slide_model::SlideModel {
|
|||
dest_slide, dest_count
|
||||
);
|
||||
}
|
||||
} else if let Some((i, slide)) = slides_iter
|
||||
.enumerate()
|
||||
.find(|slide| {
|
||||
} else if let Some((i, slide)) =
|
||||
slides_iter.enumerate().find(|slide| {
|
||||
slide.1.service_item_id == destination_index
|
||||
})
|
||||
{
|
||||
|
@ -1001,7 +1026,8 @@ impl slide_model::SlideModel {
|
|||
debug!(service_item = index, "Getting slide from this item");
|
||||
let mut id = 0;
|
||||
if let Some((i, slide)) = slides_iter
|
||||
.enumerate().find(|(_i, slide)| slide.service_item_id == index)
|
||||
.enumerate()
|
||||
.find(|(_i, slide)| slide.service_item_id == index)
|
||||
{
|
||||
debug!(slide_id = i, ?slide);
|
||||
id = i as i32;
|
||||
|
@ -1105,7 +1131,6 @@ impl slide_model::SlideModel {
|
|||
(0, QModelIndex::default(), vector_roles)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// QAbstractListModel implementation
|
||||
|
@ -1114,22 +1139,30 @@ impl slide_model::SlideModel {
|
|||
let role = SlideRoles { repr: role };
|
||||
if let Some(slide) = self.slides.get(index.row() as usize) {
|
||||
return match role {
|
||||
SlideRoles::Ty => QVariant::from(&QString::from(&slide.ty.to_string())),
|
||||
SlideRoles::Text => QVariant::from(&QString::from(&slide.text)),
|
||||
SlideRoles::Audio => QVariant::from(&QString::from(&slide.audio)),
|
||||
SlideRoles::ImageBackground => {
|
||||
QVariant::from(&QString::from(&slide.image_background))
|
||||
SlideRoles::Ty => QVariant::from(&QString::from(
|
||||
&slide.ty.to_string(),
|
||||
)),
|
||||
SlideRoles::Text => {
|
||||
QVariant::from(&QString::from(&slide.text))
|
||||
}
|
||||
SlideRoles::VideoBackground => {
|
||||
QVariant::from(&QString::from(&slide.video_background))
|
||||
SlideRoles::Audio => {
|
||||
QVariant::from(&QString::from(&slide.audio))
|
||||
}
|
||||
SlideRoles::HTextAlignment => {
|
||||
QVariant::from(&QString::from(&slide.htext_alignment))
|
||||
SlideRoles::ImageBackground => QVariant::from(
|
||||
&QString::from(&slide.image_background),
|
||||
),
|
||||
SlideRoles::VideoBackground => QVariant::from(
|
||||
&QString::from(&slide.video_background),
|
||||
),
|
||||
SlideRoles::HTextAlignment => QVariant::from(
|
||||
&QString::from(&slide.htext_alignment),
|
||||
),
|
||||
SlideRoles::VTextAlignment => QVariant::from(
|
||||
&QString::from(&slide.vtext_alignment),
|
||||
),
|
||||
SlideRoles::Font => {
|
||||
QVariant::from(&QString::from(&slide.font))
|
||||
}
|
||||
SlideRoles::VTextAlignment => {
|
||||
QVariant::from(&QString::from(&slide.vtext_alignment))
|
||||
}
|
||||
SlideRoles::Font => QVariant::from(&QString::from(&slide.font)),
|
||||
SlideRoles::FontSize => {
|
||||
QVariant::from(&slide.font_size)
|
||||
}
|
||||
|
@ -1147,9 +1180,9 @@ impl slide_model::SlideModel {
|
|||
QVariant::from(&slide.selected)
|
||||
}
|
||||
SlideRoles::Looping => QVariant::from(&slide.looping),
|
||||
SlideRoles::VideoThumbnail => {
|
||||
QVariant::from(&QString::from(&slide.video_thumbnail))
|
||||
}
|
||||
SlideRoles::VideoThumbnail => QVariant::from(
|
||||
&QString::from(&slide.video_thumbnail),
|
||||
),
|
||||
SlideRoles::VideoStartTime => {
|
||||
QVariant::from(&slide.video_start_time)
|
||||
}
|
||||
|
@ -1256,7 +1289,8 @@ impl slide_model::SlideModel {
|
|||
fn extract_string(item: &QMap_QString_QVariant, key: &str) -> String {
|
||||
item.get(&QString::from(key))
|
||||
.unwrap_or(QVariant::from(&QString::default()))
|
||||
.value_or_default::<QString>().to_string()
|
||||
.value_or_default::<QString>()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn extract_value(item: &QMap_QString_QVariant, key: &str) -> i32 {
|
||||
|
@ -1277,12 +1311,11 @@ fn extract_bool(item: &QMap_QString_QVariant, key: &str) -> bool {
|
|||
.value_or_default::<bool>()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
// #[cfg(test)]
|
||||
// mod test {
|
||||
|
||||
|
||||
#[test]
|
||||
pub fn test_obs_setting_scene() {
|
||||
assert_eq!(true, true)
|
||||
}
|
||||
}
|
||||
// #[test]
|
||||
// pub fn test_obs_setting_scene() {
|
||||
// assert_eq!(true, true)
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -89,7 +89,8 @@ use cxx_qt_lib::{CaseSensitivity, QString, QVariant};
|
|||
use tracing::{debug, error};
|
||||
|
||||
use crate::{
|
||||
slide_model::{slide_model, Slide}, slide_types::SlideType
|
||||
slide_model::{slide_model, Slide},
|
||||
slide_types::SlideType,
|
||||
};
|
||||
|
||||
use self::slide_object::QMap_QString_QVariant;
|
||||
|
@ -484,10 +485,18 @@ impl slide_object::SlideObject {
|
|||
self.as_mut().set_text(QString::from(&slide.text));
|
||||
self.as_mut().set_ty(QString::from(&slide.ty.to_string()));
|
||||
self.as_mut().set_audio(QString::from(&slide.audio));
|
||||
self.as_mut().set_image_background(QString::from(&slide.image_background));
|
||||
self.as_mut().set_video_background(QString::from(&slide.video_background));
|
||||
self.as_mut().set_vtext_alignment(QString::from(&slide.vtext_alignment));
|
||||
self.as_mut().set_htext_alignment(QString::from(&slide.htext_alignment));
|
||||
self.as_mut().set_image_background(QString::from(
|
||||
&slide.image_background,
|
||||
));
|
||||
self.as_mut().set_video_background(QString::from(
|
||||
&slide.video_background,
|
||||
));
|
||||
self.as_mut().set_vtext_alignment(QString::from(
|
||||
&slide.vtext_alignment,
|
||||
));
|
||||
self.as_mut().set_htext_alignment(QString::from(
|
||||
&slide.htext_alignment,
|
||||
));
|
||||
self.as_mut().set_font(QString::from(&slide.font));
|
||||
self.as_mut().set_font_size(slide.font_size);
|
||||
self.as_mut().set_video_start_time(slide.video_start_time);
|
||||
|
|
|
@ -241,6 +241,7 @@ pub mod song_model {
|
|||
}
|
||||
|
||||
use crate::songs::song_editor::song_editor::QList_QString;
|
||||
use color_eyre::Result;
|
||||
use cxx_qt::{CxxQtType, Threading};
|
||||
use cxx_qt_lib::{
|
||||
QByteArray, QModelIndex, QString, QStringList, QVariant,
|
||||
|
@ -249,7 +250,6 @@ use sqlx::{query, query_as, Connection, SqliteConnection};
|
|||
use std::collections::HashMap;
|
||||
use std::pin::Pin;
|
||||
use tracing::{debug, error};
|
||||
use color_eyre::Result;
|
||||
|
||||
use self::song_model::{
|
||||
QHash_i32_QByteArray, QMap_QString_QVariant, QVector_i32,
|
||||
|
@ -293,15 +293,13 @@ impl Song {
|
|||
}
|
||||
let raw_lyrics = self.lyrics.clone();
|
||||
println!("raw-lyrics: {:?}", raw_lyrics);
|
||||
let vorder: Vec<&str> =
|
||||
self.verse_order.split(' ').collect();
|
||||
let vorder: Vec<&str> = self.verse_order.split(' ').collect();
|
||||
let keywords = vec![
|
||||
"Verse 1", "Verse 2", "Verse 3", "Verse 4",
|
||||
"Verse 5", "Verse 6", "Verse 7", "Verse 8",
|
||||
"Chorus 1", "Chorus 2", "Chorus 3", "Chorus 4",
|
||||
"Bridge 1", "Bridge 2", "Bridge 3", "Bridge 4",
|
||||
"Intro 1", "Intro 2", "Ending 1", "Ending 2",
|
||||
"Other 1", "Other 2", "Other 3", "Other 4",
|
||||
"Verse 1", "Verse 2", "Verse 3", "Verse 4", "Verse 5",
|
||||
"Verse 6", "Verse 7", "Verse 8", "Chorus 1", "Chorus 2",
|
||||
"Chorus 3", "Chorus 4", "Bridge 1", "Bridge 2",
|
||||
"Bridge 3", "Bridge 4", "Intro 1", "Intro 2", "Ending 1",
|
||||
"Ending 2", "Other 1", "Other 2", "Other 3", "Other 4",
|
||||
];
|
||||
let _first_item = true;
|
||||
|
||||
|
@ -335,10 +333,8 @@ impl Song {
|
|||
let mut verse_name = "";
|
||||
// debug!(verse = verse);
|
||||
for word in keywords.clone() {
|
||||
let end_verse =
|
||||
verse.get(1..2).unwrap_or_default();
|
||||
let beg_verse =
|
||||
verse.get(0..1).unwrap_or_default();
|
||||
let end_verse = verse.get(1..2).unwrap_or_default();
|
||||
let beg_verse = verse.get(0..1).unwrap_or_default();
|
||||
// println!(
|
||||
// "verse: {:?}, beginning: {:?}, end: {:?}, word: {:?}",
|
||||
// verse, beg_verse, end_verse, word
|
||||
|
@ -400,9 +396,11 @@ impl Default for SongModelRust {
|
|||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
rt.block_on(async {
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
SqliteConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("problems")
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -416,12 +414,14 @@ pub fn get_song(id: i32) -> Result<Song> {
|
|||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
rt.block_on(async {
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
SqliteConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("problems")
|
||||
})
|
||||
};
|
||||
debug!("getting song with id: {id}");
|
||||
rt.block_on(async {
|
||||
let result = query_as!(Song, 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 = ?"#, id).fetch_one(&mut db).await?;
|
||||
let result = query_as!(Song, r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment 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"#, id).fetch_one(&mut db).await?;
|
||||
debug!(?result);
|
||||
Ok(result)
|
||||
})
|
||||
|
@ -440,7 +440,7 @@ impl song_model::SongModel {
|
|||
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_as!(Song, 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.as_mut().rust_mut().db).await;
|
||||
let result = query_as!(Song, r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment 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.as_mut().rust_mut().db).await;
|
||||
match result {
|
||||
Ok(s) => s.into_iter().for_each(|s| self.as_mut().add_song(s)),
|
||||
Err(e) => error!("There was an error in converting songs: {e}"),
|
||||
|
@ -453,7 +453,13 @@ impl song_model::SongModel {
|
|||
return false;
|
||||
}
|
||||
|
||||
let song_id = self.as_mut().rust_mut().songs.get(index as usize).unwrap().id;
|
||||
let song_id = self
|
||||
.as_mut()
|
||||
.rust_mut()
|
||||
.songs
|
||||
.get(index as usize)
|
||||
.unwrap()
|
||||
.id;
|
||||
let thread = self.qt_thread();
|
||||
let db = &mut self.as_mut().rust_mut().db;
|
||||
|
||||
|
@ -504,7 +510,7 @@ impl song_model::SongModel {
|
|||
};
|
||||
|
||||
rt.block_on(async {
|
||||
let result = query!(r#"INSERT into songs (vorder, fontSize, backgroundType, horizontalTextAlignment, verticalTextAlignment, title, font, background, lyrics, ccli, author, audio, id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"#,
|
||||
let result = query!(r#"INSERT into songs (verse_order, font_size, background_type, horizontal_text_alignment, vertical_text_alignment, title, font, background, lyrics, ccli, author, audio, id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"#,
|
||||
song.verse_order,
|
||||
song.font_size,
|
||||
song.background_type,
|
||||
|
@ -758,7 +764,11 @@ impl song_model::SongModel {
|
|||
let db_string = updated_ccli.clone().to_string();
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!("UPDATE songs SET ccli = ? where id = ?", db_string, song_id)
|
||||
let result = query!(
|
||||
"UPDATE songs SET ccli = ? where id = ?",
|
||||
db_string,
|
||||
song_id
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
|
||||
|
@ -783,9 +793,11 @@ impl song_model::SongModel {
|
|||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("There was an error updating ccli in db: {e}");
|
||||
error!(
|
||||
"There was an error updating ccli in db: {e}"
|
||||
);
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
true
|
||||
|
@ -802,7 +814,7 @@ impl song_model::SongModel {
|
|||
let db_string = updated_verse_order.clone().to_string();
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!("UPDATE songs SET vorder = ? where id = ?", db_string, song_id)
|
||||
let result = query!("UPDATE songs SET verse_order = ? where id = ?", db_string, song_id)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
|
||||
|
@ -891,7 +903,7 @@ impl song_model::SongModel {
|
|||
let db_string = updated_background_type.clone().to_string();
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!("UPDATE songs SET backgroundType = ? where id = ?", db_string, song_id)
|
||||
let result = query!("UPDATE songs SET background_type = ? where id = ?", db_string, song_id)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
|
||||
|
@ -933,10 +945,11 @@ impl song_model::SongModel {
|
|||
.as_mut()
|
||||
.get_indices(song_id, SongRoles::HorizontalTextAlignment);
|
||||
|
||||
let db_string = updated_horizontal_text_alignment.clone().to_string();
|
||||
let db_string =
|
||||
updated_horizontal_text_alignment.clone().to_string();
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!("UPDATE songs SET horizontalTextAlignment = ? where id = ?", db_string, song_id)
|
||||
let result = query!("UPDATE songs SET horizontal_text_alignment = ? where id = ?", db_string, song_id)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
|
||||
|
@ -978,10 +991,11 @@ impl song_model::SongModel {
|
|||
.as_mut()
|
||||
.get_indices(song_id, SongRoles::VerticalTextAlignment);
|
||||
|
||||
let db_string = updated_vertical_text_alignment.clone().to_string();
|
||||
let db_string =
|
||||
updated_vertical_text_alignment.clone().to_string();
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!("UPDATE songs SET verticalTextAlignment = ? where id = ?", db_string, song_id)
|
||||
let result = query!("UPDATE songs SET vertical_text_alignment = ? where id = ?", db_string, song_id)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
|
||||
|
@ -1025,7 +1039,11 @@ impl song_model::SongModel {
|
|||
let db_string = updated_font.clone().to_string();
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!("UPDATE songs SET font = ? where id = ?", db_string, song_id)
|
||||
let result = query!(
|
||||
"UPDATE songs SET font = ? where id = ?",
|
||||
db_string,
|
||||
song_id
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
|
||||
|
@ -1050,9 +1068,11 @@ impl song_model::SongModel {
|
|||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("There was an error updating font in db: {e}");
|
||||
error!(
|
||||
"There was an error updating font in db: {e}"
|
||||
);
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
true
|
||||
|
@ -1069,7 +1089,7 @@ impl song_model::SongModel {
|
|||
let db_string = updated_font_size.clone().to_string();
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!("UPDATE songs SET fontSize = ? where id = ?", db_string, song_id)
|
||||
let result = query!("UPDATE songs SET font_size = ? where id = ?", db_string, song_id)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@ pub mod video_model {
|
|||
}
|
||||
}
|
||||
|
||||
use color_eyre::eyre::Error;
|
||||
use cxx_qt::{CxxQtType, Threading};
|
||||
use cxx_qt_lib::{QByteArray, QModelIndex, QString, QUrl, QVariant};
|
||||
use sqlx::{query, query_as, Connection, SqliteConnection};
|
||||
|
@ -224,9 +225,11 @@ impl Default for VideoModelRust {
|
|||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
rt.block_on(async {
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
SqliteConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("problems")
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -240,12 +243,20 @@ pub fn get_video(index: i32) -> color_eyre::Result<Video> {
|
|||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
rt.block_on(async {
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
SqliteConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("problems")
|
||||
})
|
||||
};
|
||||
rt.block_on(async {
|
||||
let result = query_as!(Video, r#"SELECT id as "id: i32", title as "title!", filePath as "path!", startTime as "start_time!: f32", endTime as "end_time!: f32", loop as "looping!" from videos where id = ?"#, index).fetch_one(&mut db).await?;
|
||||
Ok(result)
|
||||
let result = query_as!(Video, r#"SELECT id as "id: i32", title as "title!", file_path as "path!", start_time as "start_time!: f32", end_time as "end_time!: f32", loop as "looping!" from videos where id = ?"#, index).fetch_one(&mut db).await;
|
||||
match result {
|
||||
Ok(v) => Ok(v),
|
||||
Err(e) => {
|
||||
error!(?e);
|
||||
Err(color_eyre::Report::from(e))
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -261,7 +272,7 @@ impl video_model::VideoModel {
|
|||
pub fn setup(mut self: Pin<&mut Self>) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query_as!(Video, r#"SELECT id as "id: i32", title as "title!", filePath as "path!", startTime as "start_time!: f32", endTime as "end_time!: f32", loop as "looping!" from videos"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
||||
let result = query_as!(Video, r#"SELECT id as "id: i32", title as "title!", file_path as "path!", start_time as "start_time!: f32", end_time as "end_time!: f32", loop as "looping!" from videos"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
||||
match result {
|
||||
Ok(v) => v.into_iter().for_each(|v| self.as_mut().add_video(v)),
|
||||
Err(e) => error!("There was an error in converting songs: {e}"),
|
||||
|
@ -277,7 +288,10 @@ impl video_model::VideoModel {
|
|||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
rt.block_on(async {
|
||||
let result = query!("delete from videos where id = ?", video_id).execute(&mut self.as_mut().rust_mut().db).await;
|
||||
let result =
|
||||
query!("delete from videos where id = ?", video_id)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
Ok(_i) => {
|
||||
unsafe {
|
||||
|
@ -334,7 +348,7 @@ impl video_model::VideoModel {
|
|||
rt.block_on(async {
|
||||
let video_title = video_title.to_string();
|
||||
let video_path = video_path.to_string();
|
||||
let result = query!(r#"INSERT into videos (id, title, filePath, startTime, endTime, loop) VALUES (?, ?, ?, ?, ?, ?)"#,
|
||||
let result = query!(r#"INSERT into videos (id, title, file_path, start_time, end_time, loop) VALUES (?, ?, ?, ?, ?, ?)"#,
|
||||
video_id,
|
||||
video_title,
|
||||
video_path,
|
||||
|
@ -435,7 +449,11 @@ impl video_model::VideoModel {
|
|||
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!("UPDATE videos SET loop = ? where id = ?", loop_value, index)
|
||||
let result = query!(
|
||||
"UPDATE videos SET loop = ? where id = ?",
|
||||
loop_value,
|
||||
index
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
|
@ -448,9 +466,11 @@ impl video_model::VideoModel {
|
|||
.filter(|x| x.id == index)
|
||||
{
|
||||
video.looping = loop_value;
|
||||
debug!(title = video.title,
|
||||
debug!(
|
||||
title = video.title,
|
||||
looping = loop_value,
|
||||
"updated video loop");
|
||||
"updated video loop"
|
||||
);
|
||||
}
|
||||
self.as_mut().data_changed(
|
||||
model_index,
|
||||
|
@ -462,7 +482,7 @@ impl video_model::VideoModel {
|
|||
Err(e) => {
|
||||
error!("Error connecting to db: {e}");
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
true
|
||||
|
@ -481,7 +501,11 @@ impl video_model::VideoModel {
|
|||
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!("UPDATE videos SET endTime = ? where id = ?", updated_end_time, index)
|
||||
let result = query!(
|
||||
"UPDATE videos SET end_time = ? where id = ?",
|
||||
updated_end_time,
|
||||
index
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
|
@ -494,9 +518,11 @@ impl video_model::VideoModel {
|
|||
.filter(|x| x.id == index)
|
||||
{
|
||||
video.end_time = updated_end_time;
|
||||
debug!(title = video.title,
|
||||
debug!(
|
||||
title = video.title,
|
||||
end_time = updated_end_time,
|
||||
"updated video end_time");
|
||||
"updated video end_time"
|
||||
);
|
||||
}
|
||||
self.as_mut().data_changed(
|
||||
model_index,
|
||||
|
@ -508,7 +534,7 @@ impl video_model::VideoModel {
|
|||
Err(e) => {
|
||||
error!("Error connecting to db: {e}");
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
true
|
||||
|
@ -527,7 +553,11 @@ impl video_model::VideoModel {
|
|||
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let result = query!("UPDATE videos SET startTime = ? where id = ?", updated_start_time, index)
|
||||
let result = query!(
|
||||
"UPDATE videos SET start_time = ? where id = ?",
|
||||
updated_start_time,
|
||||
index
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
|
@ -540,9 +570,11 @@ impl video_model::VideoModel {
|
|||
.filter(|x| x.id == index)
|
||||
{
|
||||
video.start_time = updated_start_time;
|
||||
debug!(title = video.title,
|
||||
debug!(
|
||||
title = video.title,
|
||||
start_time = updated_start_time,
|
||||
"updated video start_time");
|
||||
"updated video start_time"
|
||||
);
|
||||
}
|
||||
self.as_mut().data_changed(
|
||||
model_index,
|
||||
|
@ -554,7 +586,7 @@ impl video_model::VideoModel {
|
|||
Err(e) => {
|
||||
error!("Error connecting to db: {e}");
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
true
|
||||
|
@ -574,7 +606,11 @@ impl video_model::VideoModel {
|
|||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let title = updated_title.to_string();
|
||||
let result = query!("UPDATE videos SET title = ? where id = ?", title, index)
|
||||
let result = query!(
|
||||
"UPDATE videos SET title = ? where id = ?",
|
||||
title,
|
||||
index
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
|
@ -587,9 +623,11 @@ impl video_model::VideoModel {
|
|||
.filter(|x| x.id == index)
|
||||
{
|
||||
video.title = title.clone();
|
||||
debug!(title = video.title,
|
||||
debug!(
|
||||
title = video.title,
|
||||
title = title,
|
||||
"updated video title");
|
||||
"updated video title"
|
||||
);
|
||||
}
|
||||
self.as_mut().data_changed(
|
||||
model_index,
|
||||
|
@ -601,7 +639,7 @@ impl video_model::VideoModel {
|
|||
Err(e) => {
|
||||
error!("Error connecting to db: {e}");
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
true
|
||||
|
@ -620,7 +658,11 @@ impl video_model::VideoModel {
|
|||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let updated_path = updated_path.to_string();
|
||||
let result = query!("UPDATE videos SET filePath = ? where id = ?", updated_path, index)
|
||||
let result = query!(
|
||||
"UPDATE videos SET file_path = ? where id = ?",
|
||||
updated_path,
|
||||
index
|
||||
)
|
||||
.execute(&mut self.as_mut().rust_mut().db)
|
||||
.await;
|
||||
match result {
|
||||
|
@ -633,9 +675,11 @@ impl video_model::VideoModel {
|
|||
.filter(|x| x.id == index)
|
||||
{
|
||||
video.path = updated_path.clone();
|
||||
debug!(title = video.title,
|
||||
debug!(
|
||||
title = video.title,
|
||||
path = updated_path,
|
||||
"updated video path");
|
||||
"updated video path"
|
||||
);
|
||||
}
|
||||
self.as_mut().data_changed(
|
||||
model_index,
|
||||
|
@ -647,7 +691,7 @@ impl video_model::VideoModel {
|
|||
Err(e) => {
|
||||
error!("Error connecting to db: {e}");
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
true
|
||||
|
|
|
@ -67,14 +67,10 @@ impl ytdl::Ytdl {
|
|||
.run()
|
||||
.unwrap();
|
||||
let output = ytdl.into_single_video().unwrap();
|
||||
debug!(
|
||||
output.title,
|
||||
output.thumbnail, output.url
|
||||
);
|
||||
debug!(output.title, output.thumbnail, output.url);
|
||||
let title = QString::from(&output.title);
|
||||
let thumbnail = QUrl::from(
|
||||
&output.thumbnail.unwrap_or_default(),
|
||||
);
|
||||
let thumbnail =
|
||||
QUrl::from(&output.thumbnail.unwrap_or_default());
|
||||
let mut file = String::from(output_dirs);
|
||||
file.push('/');
|
||||
file.push_str(&output.title);
|
||||
|
@ -86,12 +82,8 @@ impl ytdl::Ytdl {
|
|||
qobject_ytdl.as_mut().set_loaded(true);
|
||||
qobject_ytdl.as_mut().set_loading(false);
|
||||
qobject_ytdl.as_mut().set_title(title);
|
||||
qobject_ytdl
|
||||
.as_mut()
|
||||
.set_thumbnail(thumbnail);
|
||||
qobject_ytdl
|
||||
.as_mut()
|
||||
.set_file(QUrl::from(&file));
|
||||
qobject_ytdl.as_mut().set_thumbnail(thumbnail);
|
||||
qobject_ytdl.as_mut().set_file(QUrl::from(&file));
|
||||
})
|
||||
});
|
||||
true
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue