diff --git a/src/actions/confirm.rs b/src/actions/confirm.rs new file mode 100644 index 0000000..cdcbd85 --- /dev/null +++ b/src/actions/confirm.rs @@ -0,0 +1,43 @@ +use color_eyre::eyre::Result; +use dialoguer::theme::ColorfulTheme; + +use crate::context::Context; + +use super::action::Action; + +pub struct Confirm<'a> { + prompt: &'a str, +} + +pub enum ConfirmResult { + Positive, + Negative, +} + +impl<'a> Action for Confirm<'a> { + type Input = Option<&'a str>; + type Output = ConfirmResult; + + fn new(input: Self::Input) -> Self { + Self { + prompt: input.unwrap_or("Do you want to continue?"), + } + } + + fn describe(&self) -> String { + String::from("Requesting confirmation") + } + + async fn execute(&self, ctx: &Context) -> Result { + if ctx.dry_run + || ctx.no_confirm + || dialoguer::Confirm::with_theme(&ColorfulTheme::default()) + .with_prompt(self.prompt) + .interact()? + { + Ok(ConfirmResult::Positive) + } else { + Ok(ConfirmResult::Negative) + } + } +} diff --git a/src/actions/fetch_album_assets.rs b/src/actions/fetch_album_assets.rs new file mode 100644 index 0000000..85ba472 --- /dev/null +++ b/src/actions/fetch_album_assets.rs @@ -0,0 +1,38 @@ +use color_eyre::eyre::Result; + +use crate::{ + context::Context, + models::{album::Album, asset::Asset}, +}; + +use super::action::Action; + +pub struct FetchAlbumAssets { + album: Album, +} + +impl Action for FetchAlbumAssets { + type Input = Album; + type Output = Vec; + + fn new(input: Self::Input) -> Self { + Self { album: input } + } + + fn describe(&self) -> String { + // TODO: derive Display for Album and use this here + format!("Fetching all assets for album {}", self.album.name) + } + + async fn execute(&self, ctx: &Context) -> Result { + Ok(ctx + .client + .get_album_info(&self.album.id, None, Some(false)) + .await? + .assets + .clone() + .into_iter() + .map(Into::into) + .collect()) + } +} diff --git a/src/actions/fetch_all_albums.rs b/src/actions/fetch_all_albums.rs new file mode 100644 index 0000000..a1ae5b5 --- /dev/null +++ b/src/actions/fetch_all_albums.rs @@ -0,0 +1,31 @@ +use color_eyre::eyre::Result; + +use crate::{context::Context, models::album::Album}; + +use super::action::Action; + +pub struct FetchAllAlbums {} + +impl Action for FetchAllAlbums { + type Input = (); + type Output = Vec; + + fn new(_input: Self::Input) -> Self { + Self {} + } + + fn describe(&self) -> String { + String::from("Fetching all albums") + } + + async fn execute(&self, ctx: &Context) -> Result { + Ok(ctx + .client + .get_all_albums(None, None) + .await? + .clone() + .into_iter() + .map(Into::into) + .collect()) + } +} diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 03f2599..0c570d0 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -1,3 +1,6 @@ pub mod action; +pub mod confirm; +pub mod fetch_album_assets; +pub mod fetch_all_albums; pub mod fetch_all_persons; pub mod update_person_date_of_birth; diff --git a/src/commands/delete_assets.rs b/src/commands/delete_assets.rs index c04f7a5..0afd9bd 100644 --- a/src/commands/delete_assets.rs +++ b/src/commands/delete_assets.rs @@ -1,9 +1,12 @@ use crate::{ + actions::{ + action::Action, + confirm::{Confirm, ConfirmResult}, + }, context::Context, utils::assets::{fetch_all_assets, AssetQuery}, }; use color_eyre::eyre::Result; -use dialoguer::{theme::ColorfulTheme, Confirm}; use log::info; use uuid::Uuid; @@ -22,15 +25,7 @@ pub async fn delete_assets(ctx: Context, offline: bool) -> Result<()> { ); } - if !ctx.dry_run { - if !(ctx.no_confirm - || Confirm::with_theme(&ColorfulTheme::default()) - .with_prompt("Do you want to continue?") - .interact()?) - { - return Ok(()); - } - + if let ConfirmResult::Positive = Confirm::new(None).execute(&ctx).await? { let asset_ids: Result, uuid::Error> = assets .iter() .map(|asset| Uuid::parse_str(&asset.id)) @@ -41,13 +36,13 @@ pub async fn delete_assets(ctx: Context, offline: bool) -> Result<()> { ids: asset_ids?, }) .await?; - } - info!( - "Deleted {} assets{}", - assets.len(), - if ctx.dry_run { " (dry run)" } else { "" } - ); + info!( + "Deleted {} assets{}", + assets.len(), + if ctx.dry_run { " (dry run)" } else { "" } + ); + } Ok(()) } diff --git a/src/models/album.rs b/src/models/album.rs new file mode 100644 index 0000000..f151b5d --- /dev/null +++ b/src/models/album.rs @@ -0,0 +1,18 @@ +use uuid::Uuid; + +use crate::types::AlbumResponseDto; + +#[derive(Debug, Clone)] +pub struct Album { + pub id: Uuid, + pub name: String, +} + +impl From for Album { + fn from(value: AlbumResponseDto) -> Self { + Self { + id: Uuid::parse_str(&value.id).expect("Unable to parse an album's UUID"), + name: value.album_name, + } + } +} diff --git a/src/models/asset.rs b/src/models/asset.rs new file mode 100644 index 0000000..668d877 --- /dev/null +++ b/src/models/asset.rs @@ -0,0 +1,16 @@ +use uuid::Uuid; + +use crate::types::AssetResponseDto; + +#[derive(Debug, Clone)] +pub struct Asset { + pub id: Uuid, +} + +impl From for Asset { + fn from(value: AssetResponseDto) -> Self { + Self { + id: Uuid::parse_str(&value.id).expect("Unable to parse an asset's UUID"), + } + } +} diff --git a/src/models/mod.rs b/src/models/mod.rs index 4a45102..2bd864d 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1 +1,3 @@ +pub mod album; +pub mod asset; pub mod person; diff --git a/src/utils/albums.rs b/src/utils/albums.rs deleted file mode 100644 index f892063..0000000 --- a/src/utils/albums.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::{ - types::{AlbumResponseDto, AssetResponseDto}, - Client, -}; -use color_eyre::eyre::Result; -use uuid::Uuid; - -pub async fn fetch_all_albums(client: &Client) -> Result> { - Ok(client.get_all_albums(None, None).await?.to_vec()) -} - -pub async fn fetch_album_assets( - album_uuid: &Uuid, - client: &Client, -) -> Result> { - Ok(client - .get_album_info(album_uuid, None, Some(false)) - .await? - .assets - .clone()) -} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 07eb6a1..5d8c80b 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,2 +1 @@ -pub mod albums; pub mod assets;