Continue actions refactoring #24
					 10 changed files with 162 additions and 38 deletions
				
			
		
							
								
								
									
										43
									
								
								src/actions/confirm.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/actions/confirm.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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<Self::Output> {
 | 
			
		||||
        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)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								src/actions/fetch_album_assets.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/actions/fetch_album_assets.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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<Asset>;
 | 
			
		||||
 | 
			
		||||
    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<Self::Output> {
 | 
			
		||||
        Ok(ctx
 | 
			
		||||
            .client
 | 
			
		||||
            .get_album_info(&self.album.id, None, Some(false))
 | 
			
		||||
            .await?
 | 
			
		||||
            .assets
 | 
			
		||||
            .clone()
 | 
			
		||||
            .into_iter()
 | 
			
		||||
            .map(Into::into)
 | 
			
		||||
            .collect())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								src/actions/fetch_all_albums.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/actions/fetch_all_albums.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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<Album>;
 | 
			
		||||
 | 
			
		||||
    fn new(_input: Self::Input) -> Self {
 | 
			
		||||
        Self {}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn describe(&self) -> String {
 | 
			
		||||
        String::from("Fetching all albums")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn execute(&self, ctx: &Context) -> Result<Self::Output> {
 | 
			
		||||
        Ok(ctx
 | 
			
		||||
            .client
 | 
			
		||||
            .get_all_albums(None, None)
 | 
			
		||||
            .await?
 | 
			
		||||
            .clone()
 | 
			
		||||
            .into_iter()
 | 
			
		||||
            .map(Into::into)
 | 
			
		||||
            .collect())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<Vec<_>, 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(())
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								src/models/album.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/models/album.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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<AlbumResponseDto> 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,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/models/asset.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/models/asset.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
use uuid::Uuid;
 | 
			
		||||
 | 
			
		||||
use crate::types::AssetResponseDto;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct Asset {
 | 
			
		||||
    pub id: Uuid,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<AssetResponseDto> for Asset {
 | 
			
		||||
    fn from(value: AssetResponseDto) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            id: Uuid::parse_str(&value.id).expect("Unable to parse an asset's UUID"),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +1,3 @@
 | 
			
		|||
pub mod album;
 | 
			
		||||
pub mod asset;
 | 
			
		||||
pub mod person;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<Vec<AlbumResponseDto>> {
 | 
			
		||||
    Ok(client.get_all_albums(None, None).await?.to_vec())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub async fn fetch_album_assets(
 | 
			
		||||
    album_uuid: &Uuid,
 | 
			
		||||
    client: &Client,
 | 
			
		||||
) -> Result<Vec<AssetResponseDto>> {
 | 
			
		||||
    Ok(client
 | 
			
		||||
        .get_album_info(album_uuid, None, Some(false))
 | 
			
		||||
        .await?
 | 
			
		||||
        .assets
 | 
			
		||||
        .clone())
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +1 @@
 | 
			
		|||
pub mod albums;
 | 
			
		||||
pub mod assets;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue