ServiceItems are loaded from lisp and converted to slides
This commit is contained in:
parent
cb7fa372a9
commit
db39eb12b8
9 changed files with 283 additions and 125 deletions
|
@ -39,7 +39,11 @@ impl From<&Value> for Image {
|
|||
};
|
||||
|
||||
let title = path.clone().map(|p| {
|
||||
p.to_str().unwrap_or_default().to_string()
|
||||
let path =
|
||||
p.to_str().unwrap_or_default().to_string();
|
||||
let title =
|
||||
path.rsplit_once("/").unwrap_or_default().1;
|
||||
title.to_string()
|
||||
});
|
||||
Self {
|
||||
title: title.unwrap_or_default(),
|
||||
|
|
|
@ -16,7 +16,7 @@ pub enum ServiceItemKind {
|
|||
Song(Song),
|
||||
Video(Video),
|
||||
Image(Image),
|
||||
Presentation((Presentation, PresKind)),
|
||||
Presentation(Presentation),
|
||||
Content(Slide),
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ impl std::fmt::Display for ServiceItemKind {
|
|||
Self::Song(s) => "song".to_owned(),
|
||||
Self::Image(i) => "image".to_owned(),
|
||||
Self::Video(v) => "video".to_owned(),
|
||||
Self::Presentation((p, k)) => "html".to_owned(),
|
||||
Self::Presentation(p) => "html".to_owned(),
|
||||
Self::Content(s) => "content".to_owned(),
|
||||
};
|
||||
write!(f, "{s}")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crisp::types::Value;
|
||||
use crisp::types::{Keyword, Value};
|
||||
use miette::{miette, IntoDiagnostic, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{
|
||||
|
@ -39,7 +39,30 @@ impl From<Value> for Presentation {
|
|||
|
||||
impl From<&Value> for Presentation {
|
||||
fn from(value: &Value) -> Self {
|
||||
todo!()
|
||||
match value {
|
||||
Value::List(list) => {
|
||||
let path = if let Some(path_pos) =
|
||||
list.iter().position(|v| {
|
||||
v == &Value::Keyword(Keyword::from("source"))
|
||||
}) {
|
||||
let pos = path_pos + 1;
|
||||
list.get(pos)
|
||||
.map(|p| PathBuf::from(String::from(p)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let title = path.clone().map(|p| {
|
||||
p.to_str().unwrap_or_default().to_string()
|
||||
});
|
||||
Self {
|
||||
title: title.unwrap_or_default(),
|
||||
path: path.unwrap_or_default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use crisp::types::{Keyword, Symbol, Value};
|
||||
use miette::Result;
|
||||
use tracing::error;
|
||||
use tracing::{debug, error};
|
||||
|
||||
use crate::Slide;
|
||||
|
||||
|
@ -21,12 +23,16 @@ pub struct ServiceItem {
|
|||
}
|
||||
|
||||
impl ServiceItem {
|
||||
pub fn to_slide(&self) -> Result<Vec<Slide>> {
|
||||
pub fn title(&self) -> String {
|
||||
self.title.clone()
|
||||
}
|
||||
|
||||
pub fn to_slides(&self) -> Result<Vec<Slide>> {
|
||||
match &self.kind {
|
||||
ServiceItemKind::Song(song) => song.to_slides(),
|
||||
ServiceItemKind::Video(video) => video.to_slides(),
|
||||
ServiceItemKind::Image(image) => image.to_slides(),
|
||||
ServiceItemKind::Presentation((presentation, _)) => {
|
||||
ServiceItemKind::Presentation(presentation) => {
|
||||
presentation.to_slides()
|
||||
}
|
||||
ServiceItemKind::Content(slide) => {
|
||||
|
@ -124,11 +130,27 @@ impl From<&Value> for ServiceItem {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct ServiceItemModel {
|
||||
items: Vec<ServiceItem>,
|
||||
}
|
||||
|
||||
impl Deref for ServiceItemModel {
|
||||
type Target = Vec<ServiceItem>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.items
|
||||
}
|
||||
}
|
||||
|
||||
// impl Iterator for ServiceItemModel {
|
||||
// type Item = ServiceItem;
|
||||
|
||||
// fn next(&mut self) -> Option<Self::Item> {
|
||||
// *self.items.iter().next()
|
||||
// }
|
||||
// }
|
||||
|
||||
impl From<Vec<ServiceItem>> for ServiceItemModel {
|
||||
fn from(items: Vec<ServiceItem>) -> Self {
|
||||
Self { items }
|
||||
|
@ -171,10 +193,7 @@ impl From<&Image> for ServiceItem {
|
|||
impl From<&Presentation> for ServiceItem {
|
||||
fn from(presentation: &Presentation) -> Self {
|
||||
Self {
|
||||
kind: ServiceItemKind::Presentation((
|
||||
presentation.clone(),
|
||||
presentation.kind.clone(),
|
||||
)),
|
||||
kind: ServiceItemKind::Presentation(presentation.clone()),
|
||||
database_id: presentation.id,
|
||||
title: presentation.title.clone(),
|
||||
..Default::default()
|
||||
|
@ -196,7 +215,11 @@ impl ServiceItemModel {
|
|||
Ok(self
|
||||
.items
|
||||
.iter()
|
||||
.filter_map(|item| item.to_slide().ok())
|
||||
.filter_map(|item| {
|
||||
let slides = item.to_slides().ok();
|
||||
debug!(?slides);
|
||||
slides
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<Slide>>())
|
||||
}
|
||||
|
@ -251,26 +274,26 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// pub fn test_service_item() {
|
||||
// let song = test_song();
|
||||
// let service_item = ServiceItem::from(&song);
|
||||
// let pres = test_presentation();
|
||||
// let pres_item = ServiceItem::from(&pres);
|
||||
// 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!(service_item, service_model.items[0]);
|
||||
// }
|
||||
// Err(e) => panic!("Problem adding item: {:?}", e),
|
||||
// }
|
||||
// }
|
||||
#[test]
|
||||
pub fn test_service_item() {
|
||||
let song = test_song();
|
||||
let service_item = ServiceItem::from(&song);
|
||||
let pres = test_presentation();
|
||||
let pres_item = ServiceItem::from(&pres);
|
||||
let mut service_model = ServiceItemModel::default();
|
||||
match service_model.add_item(&song) {
|
||||
Ok(_) => {
|
||||
assert_eq!(
|
||||
ServiceItemKind::Song(song),
|
||||
service_model.items[0].kind
|
||||
);
|
||||
assert_eq!(
|
||||
ServiceItemKind::Presentation(pres),
|
||||
pres_item.kind
|
||||
);
|
||||
assert_eq!(service_item, service_model.items[0]);
|
||||
}
|
||||
Err(e) => panic!("Problem adding item: {:?}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,8 +60,22 @@ impl TryFrom<String> for Background {
|
|||
|
||||
impl TryFrom<PathBuf> for Background {
|
||||
type Error = ParseError;
|
||||
fn try_from(value: PathBuf) -> Result<Self, Self::Error> {
|
||||
match value.canonicalize() {
|
||||
fn try_from(path: PathBuf) -> Result<Self, Self::Error> {
|
||||
let path = if path.starts_with("~") {
|
||||
let path = path.to_str().unwrap().to_string();
|
||||
let path = path.trim_start_matches("file://");
|
||||
let home = dirs::home_dir()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string();
|
||||
let path = path.replace("~", &home);
|
||||
PathBuf::from(path)
|
||||
} else {
|
||||
path
|
||||
};
|
||||
|
||||
match path.canonicalize() {
|
||||
Ok(value) => {
|
||||
let extension = value
|
||||
.extension()
|
||||
|
@ -83,7 +97,7 @@ impl TryFrom<PathBuf> for Background {
|
|||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Couldn't canonicalize: {e}");
|
||||
error!("Couldn't canonicalize: {e} {:?}", path);
|
||||
Err(ParseError::CannotCanonicalize)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use super::{
|
|||
model::Model, service_items::ServiceTrait, slide::Slide,
|
||||
};
|
||||
use cosmic::{executor, iced::Executor};
|
||||
use crisp::types::Value;
|
||||
use crisp::types::{Keyword, Value};
|
||||
use miette::{miette, IntoDiagnostic, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{query_as, SqliteConnection};
|
||||
|
@ -31,7 +31,76 @@ impl From<Value> for Video {
|
|||
|
||||
impl From<&Value> for Video {
|
||||
fn from(value: &Value) -> Self {
|
||||
todo!()
|
||||
match value {
|
||||
Value::List(list) => {
|
||||
let path = if let Some(path_pos) =
|
||||
list.iter().position(|v| {
|
||||
v == &Value::Keyword(Keyword::from("source"))
|
||||
}) {
|
||||
let pos = path_pos + 1;
|
||||
list.get(pos)
|
||||
.map(|p| PathBuf::from(String::from(p)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let title = path.clone().map(|p| {
|
||||
let path =
|
||||
p.to_str().unwrap_or_default().to_string();
|
||||
let title =
|
||||
path.rsplit_once("/").unwrap_or_default().1;
|
||||
title.to_string()
|
||||
});
|
||||
|
||||
let start_time = if let Some(start_pos) =
|
||||
list.iter().position(|v| {
|
||||
v == &Value::Keyword(Keyword::from(
|
||||
"start-time",
|
||||
))
|
||||
}) {
|
||||
let pos = start_pos + 1;
|
||||
list.get(pos).map(|p| i32::from(p) as f32)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let end_time = if let Some(end_pos) =
|
||||
list.iter().position(|v| {
|
||||
v == &Value::Keyword(Keyword::from(
|
||||
"end-time",
|
||||
))
|
||||
}) {
|
||||
let pos = end_pos + 1;
|
||||
list.get(pos).map(|p| i32::from(p) as f32)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let looping = if let Some(loop_pos) =
|
||||
list.iter().position(|v| {
|
||||
v == &Value::Keyword(Keyword::from("loop"))
|
||||
}) {
|
||||
let pos = loop_pos + 1;
|
||||
list.get(pos)
|
||||
.map(|l| {
|
||||
String::from(l) == "true".to_string()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
Self {
|
||||
title: title.unwrap_or_default(),
|
||||
path: path.unwrap_or_default(),
|
||||
start_time,
|
||||
end_time,
|
||||
looping,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue