adding a remove from db function
This commit is contained in:
parent
de0722b430
commit
e2406b5462
6 changed files with 245 additions and 29 deletions
|
|
@ -168,6 +168,17 @@ impl Model<Image> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn remove_from_db(
|
||||||
|
db: PoolConnection<Sqlite>,
|
||||||
|
id: i32,
|
||||||
|
) -> Result<()> {
|
||||||
|
query!("DELETE FROM images WHERE id = $1", id)
|
||||||
|
.execute(&mut db.detach())
|
||||||
|
.await
|
||||||
|
.into_diagnostic()
|
||||||
|
.map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_image_in_db(
|
pub async fn update_image_in_db(
|
||||||
image: Image,
|
image: Image,
|
||||||
db: PoolConnection<Sqlite>,
|
db: PoolConnection<Sqlite>,
|
||||||
|
|
|
||||||
|
|
@ -263,6 +263,17 @@ impl Model<Presentation> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn remove_from_db(
|
||||||
|
db: PoolConnection<Sqlite>,
|
||||||
|
id: i32,
|
||||||
|
) -> Result<()> {
|
||||||
|
query!("DELETE FROM presentations WHERE id = $1", id)
|
||||||
|
.execute(&mut db.detach())
|
||||||
|
.await
|
||||||
|
.into_diagnostic()
|
||||||
|
.map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_presentation_in_db(
|
pub async fn update_presentation_in_db(
|
||||||
presentation: Presentation,
|
presentation: Presentation,
|
||||||
db: PoolConnection<Sqlite>,
|
db: PoolConnection<Sqlite>,
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ impl TryFrom<PathBuf> for Background {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Couldn't canonicalize: {e} {:?}", path);
|
// error!("Couldn't canonicalize: {e} {:?}", path);
|
||||||
Err(ParseError::CannotCanonicalize)
|
Err(ParseError::CannotCanonicalize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -407,19 +407,17 @@ impl Model<Song> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn remove_from_db(
|
pub async fn remove_from_db(
|
||||||
&mut self,
|
db: PoolConnection<Sqlite>,
|
||||||
db: &mut SqlitePool,
|
id: i32,
|
||||||
id: i32,
|
) -> Result<()> {
|
||||||
) -> Result<()> {
|
query!("DELETE FROM songs WHERE id = $1", id)
|
||||||
let db = db.acquire().await.expect("probs");
|
.execute(&mut db.detach())
|
||||||
query!("delete from songs where id = $1", id)
|
.await
|
||||||
.execute(&mut db.detach())
|
.into_diagnostic()
|
||||||
.await
|
.map(|_| ())
|
||||||
.into_diagnostic()
|
|
||||||
.map(|_| ())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_song_in_db(
|
pub async fn update_song_in_db(
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ use crisp::types::{Keyword, Symbol, Value};
|
||||||
use miette::{IntoDiagnostic, Result};
|
use miette::{IntoDiagnostic, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{
|
use sqlx::{
|
||||||
Sqlite, SqliteConnection, SqlitePool, pool::PoolConnection,
|
pool::PoolConnection, query, query_as, Sqlite, SqliteConnection,
|
||||||
query, query_as,
|
SqlitePool,
|
||||||
};
|
};
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
|
@ -35,6 +35,25 @@ impl From<&Video> for Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<PathBuf> for Video {
|
||||||
|
fn from(value: PathBuf) -> Self {
|
||||||
|
let title: String = value.file_name().map_or_else(|| "Video".into(), |filename| {
|
||||||
|
filename.to_str().unwrap_or("Video").into()
|
||||||
|
});
|
||||||
|
Self {
|
||||||
|
title,
|
||||||
|
path: value,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Path> for Video {
|
||||||
|
fn from(value: &Path) -> Self {
|
||||||
|
Self::from(value.to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Content for Video {
|
impl Content for Video {
|
||||||
fn title(&self) -> String {
|
fn title(&self) -> String {
|
||||||
self.title.clone()
|
self.title.clone()
|
||||||
|
|
@ -205,6 +224,17 @@ impl Model<Video> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn remove_from_db(
|
||||||
|
db: PoolConnection<Sqlite>,
|
||||||
|
id: i32,
|
||||||
|
) -> Result<()> {
|
||||||
|
query!("DELETE FROM videos WHERE id = $1", id)
|
||||||
|
.execute(&mut db.detach())
|
||||||
|
.await
|
||||||
|
.into_diagnostic()
|
||||||
|
.map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_video_in_db(
|
pub async fn update_video_in_db(
|
||||||
video: Video,
|
video: Video,
|
||||||
db: PoolConnection<Sqlite>,
|
db: PoolConnection<Sqlite>,
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,35 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
Element, Task,
|
|
||||||
iced::{
|
iced::{
|
||||||
Background, Border, Color, Length, alignment::Vertical,
|
alignment::Vertical, clipboard::dnd::DndAction,
|
||||||
clipboard::dnd::DndAction, futures::FutureExt,
|
futures::FutureExt, Background, Border, Color, Length,
|
||||||
},
|
},
|
||||||
iced_core::widget::tree::State,
|
iced_core::widget::tree::State,
|
||||||
iced_widget::{column, row as rowm, text as textm},
|
iced_widget::{column, row as rowm, text as textm},
|
||||||
theme,
|
theme,
|
||||||
widget::{
|
widget::{
|
||||||
Container, DndSource, Space, button, container, context_menu,
|
button, container, context_menu, dnd_destination,
|
||||||
horizontal_space, icon,
|
horizontal_space, icon,
|
||||||
menu::{self, Action as MenuAction},
|
menu::{self, Action as MenuAction},
|
||||||
mouse_area, responsive, row, scrollable, text, text_input,
|
mouse_area, responsive, row, scrollable, text, text_input,
|
||||||
|
Container, DndSource, Space,
|
||||||
},
|
},
|
||||||
|
Element, Task,
|
||||||
};
|
};
|
||||||
use miette::{IntoDiagnostic, Result};
|
use miette::{IntoDiagnostic, Result};
|
||||||
use rapidfuzz::distance::levenshtein;
|
use rapidfuzz::distance::levenshtein;
|
||||||
use sqlx::{Sqlite, SqlitePool, pool::PoolConnection};
|
use sqlx::{pool::PoolConnection, Sqlite, SqlitePool};
|
||||||
use tracing::{debug, error, warn};
|
use tracing::{debug, error, warn};
|
||||||
|
|
||||||
use crate::core::{
|
use crate::core::{
|
||||||
content::Content,
|
content::Content,
|
||||||
images::{Image, update_image_in_db},
|
images::{self, update_image_in_db, Image},
|
||||||
model::{LibraryKind, Model},
|
model::{LibraryKind, Model},
|
||||||
presentations::{Presentation, update_presentation_in_db},
|
presentations::{self, update_presentation_in_db, Presentation},
|
||||||
service_items::ServiceItem,
|
service_items::ServiceItem,
|
||||||
songs::{Song, update_song_in_db},
|
songs::{self, update_song_in_db, Song},
|
||||||
videos::{Video, update_video_in_db},
|
videos::{self, update_video_in_db, Video},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -78,7 +79,7 @@ pub(crate) enum Action {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) enum Message {
|
pub(crate) enum Message {
|
||||||
AddItem,
|
AddItem(LibraryKind),
|
||||||
DeleteItem((LibraryKind, i32)),
|
DeleteItem((LibraryKind, i32)),
|
||||||
OpenItem(Option<(LibraryKind, i32)>),
|
OpenItem(Option<(LibraryKind, i32)>),
|
||||||
HoverLibrary(Option<LibraryKind>),
|
HoverLibrary(Option<LibraryKind>),
|
||||||
|
|
@ -128,37 +129,171 @@ impl<'a> Library {
|
||||||
|
|
||||||
pub fn update(&'a mut self, message: Message) -> Action {
|
pub fn update(&'a mut self, message: Message) -> Action {
|
||||||
match message {
|
match message {
|
||||||
Message::AddItem => (),
|
Message::AddItem(kind) => match kind {
|
||||||
|
LibraryKind::Song => todo!(),
|
||||||
|
LibraryKind::Video => {
|
||||||
|
let future = cosmic::dialog::file_chooser::open::Dialog::new().filter(cosmic::dialog::file_chooser::FileFilter::new("videos").extension("mp4").extension("mkv").extension("webm").extension(".mpeg")).open_file();
|
||||||
|
let task = Task::future(future).and_then(|r| {
|
||||||
|
if let Ok(video) = r
|
||||||
|
.url()
|
||||||
|
.to_file_path()
|
||||||
|
.and_then(|path| Ok(Video::from(path)))
|
||||||
|
{
|
||||||
|
self.video_library.add_item(video);
|
||||||
|
};
|
||||||
|
Task::none()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
LibraryKind::Image => todo!(),
|
||||||
|
LibraryKind::Presentation => todo!(),
|
||||||
|
},
|
||||||
Message::None => (),
|
Message::None => (),
|
||||||
Message::DeleteItem((kind, index)) => {
|
Message::DeleteItem((kind, index)) => {
|
||||||
match kind {
|
match kind {
|
||||||
LibraryKind::Song => {
|
LibraryKind::Song => {
|
||||||
|
let Some(song) =
|
||||||
|
self.song_library.get_item(index)
|
||||||
|
else {
|
||||||
|
error!(
|
||||||
|
"There appears to not be a song here"
|
||||||
|
);
|
||||||
|
return Action::None;
|
||||||
|
};
|
||||||
|
let song = song.clone();
|
||||||
if let Err(e) =
|
if let Err(e) =
|
||||||
self.song_library.remove_item(index)
|
self.song_library.remove_item(index)
|
||||||
{
|
{
|
||||||
error!(?e);
|
error!(?e);
|
||||||
|
} else {
|
||||||
|
let task =
|
||||||
|
Task::future(self.db.acquire())
|
||||||
|
.and_then(move |db| {
|
||||||
|
Task::perform(
|
||||||
|
songs::remove_from_db(
|
||||||
|
db, song.id,
|
||||||
|
),
|
||||||
|
|r| {
|
||||||
|
match r {
|
||||||
|
Err(e) => {
|
||||||
|
error!(?e)
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
Message::None
|
||||||
|
},
|
||||||
|
)
|
||||||
|
});
|
||||||
|
return Action::Task(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LibraryKind::Video => {
|
LibraryKind::Video => {
|
||||||
|
let Some(video) =
|
||||||
|
self.video_library.get_item(index)
|
||||||
|
else {
|
||||||
|
error!(
|
||||||
|
"There appears to not be a video here"
|
||||||
|
);
|
||||||
|
return Action::None;
|
||||||
|
};
|
||||||
|
let video = video.clone();
|
||||||
if let Err(e) =
|
if let Err(e) =
|
||||||
self.video_library.remove_item(index)
|
self.video_library.remove_item(index)
|
||||||
{
|
{
|
||||||
error!(?e);
|
error!(?e);
|
||||||
|
} else {
|
||||||
|
let task =
|
||||||
|
Task::future(self.db.acquire())
|
||||||
|
.and_then(move |db| {
|
||||||
|
Task::perform(
|
||||||
|
videos::remove_from_db(
|
||||||
|
db, video.id,
|
||||||
|
),
|
||||||
|
|r| {
|
||||||
|
match r {
|
||||||
|
Err(e) => {
|
||||||
|
error!(?e)
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
Message::None
|
||||||
|
},
|
||||||
|
)
|
||||||
|
});
|
||||||
|
return Action::Task(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LibraryKind::Image => {
|
LibraryKind::Image => {
|
||||||
|
let Some(image) =
|
||||||
|
self.image_library.get_item(index)
|
||||||
|
else {
|
||||||
|
error!(
|
||||||
|
"There appears to not be a image here"
|
||||||
|
);
|
||||||
|
return Action::None;
|
||||||
|
};
|
||||||
|
let image = image.clone();
|
||||||
if let Err(e) =
|
if let Err(e) =
|
||||||
self.image_library.remove_item(index)
|
self.image_library.remove_item(index)
|
||||||
{
|
{
|
||||||
error!(?e);
|
error!(?e);
|
||||||
|
} else {
|
||||||
|
let task =
|
||||||
|
Task::future(self.db.acquire())
|
||||||
|
.and_then(move |db| {
|
||||||
|
Task::perform(
|
||||||
|
images::remove_from_db(
|
||||||
|
db, image.id,
|
||||||
|
),
|
||||||
|
|r| {
|
||||||
|
match r {
|
||||||
|
Err(e) => {
|
||||||
|
error!(?e)
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
Message::None
|
||||||
|
},
|
||||||
|
)
|
||||||
|
});
|
||||||
|
return Action::Task(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LibraryKind::Presentation => {
|
LibraryKind::Presentation => {
|
||||||
|
let Some(presentation) =
|
||||||
|
self.presentation_library.get_item(index)
|
||||||
|
else {
|
||||||
|
error!(
|
||||||
|
"There appears to not be a presentation here"
|
||||||
|
);
|
||||||
|
return Action::None;
|
||||||
|
};
|
||||||
|
let presentation = presentation.clone();
|
||||||
if let Err(e) = self
|
if let Err(e) = self
|
||||||
.presentation_library
|
.presentation_library
|
||||||
.remove_item(index)
|
.remove_item(index)
|
||||||
{
|
{
|
||||||
error!(?e);
|
error!(?e);
|
||||||
|
} else {
|
||||||
|
let task =
|
||||||
|
Task::future(self.db.acquire())
|
||||||
|
.and_then(move |db| {
|
||||||
|
Task::perform(
|
||||||
|
presentations::remove_from_db(
|
||||||
|
db,
|
||||||
|
presentation.id,
|
||||||
|
),
|
||||||
|
|r| {
|
||||||
|
match r {
|
||||||
|
Err(e) => {
|
||||||
|
error!(?e)
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
Message::None
|
||||||
|
},
|
||||||
|
)
|
||||||
|
});
|
||||||
|
return Action::Task(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -515,11 +650,42 @@ impl<'a> Library {
|
||||||
let library_toolbar = rowm!(
|
let library_toolbar = rowm!(
|
||||||
text_input("Search...", ""),
|
text_input("Search...", ""),
|
||||||
button::icon(icon::from_name("add"))
|
button::icon(icon::from_name("add"))
|
||||||
|
.on_press(Message::AddItem(model.kind))
|
||||||
);
|
);
|
||||||
let library_column =
|
let library_column =
|
||||||
column![library_toolbar, items].spacing(3);
|
column![library_toolbar, items].spacing(3);
|
||||||
|
let library_dnd = dnd_destination(
|
||||||
Container::new(library_column).padding(5)
|
library_column,
|
||||||
|
vec![
|
||||||
|
"image/png".into(),
|
||||||
|
"image/jpg".into(),
|
||||||
|
"image/heif".into(),
|
||||||
|
"image/gif".into(),
|
||||||
|
"video/mp4".into(),
|
||||||
|
"video/AV1".into(),
|
||||||
|
"video/H264".into(),
|
||||||
|
"video/H265".into(),
|
||||||
|
"video/mpeg".into(),
|
||||||
|
"video/mkv".into(),
|
||||||
|
"video/webm".into(),
|
||||||
|
"video/ogg".into(),
|
||||||
|
"video/vnd.youtube.yt".into(),
|
||||||
|
"video/x-matroska".into(),
|
||||||
|
"application/pdf".into(),
|
||||||
|
"text/html".into(),
|
||||||
|
"text/md".into(),
|
||||||
|
"text/org".into(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.on_enter(|x, y, mimes| {
|
||||||
|
warn!(?mimes);
|
||||||
|
Message::None
|
||||||
|
})
|
||||||
|
.on_finish(|mime, data, action, x, y| {
|
||||||
|
warn!(?mime, ?data, ?action);
|
||||||
|
Message::None
|
||||||
|
});
|
||||||
|
Container::new(library_dnd).padding(5)
|
||||||
} else {
|
} else {
|
||||||
Container::new(Space::new(0, 0))
|
Container::new(Space::new(0, 0))
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue