Merge branch 'delete-albums' into 'main'
Add command to delete albums See merge request kernald/immich-tools!25
This commit is contained in:
		
						commit
						85d60dac3d
					
				
					 7 changed files with 152 additions and 1 deletions
				
			
		
							
								
								
									
										115
									
								
								src/actions/delete_album.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								src/actions/delete_album.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,115 @@
 | 
				
			||||||
 | 
					use color_eyre::eyre::Result;
 | 
				
			||||||
 | 
					use log::info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::{context::Context, models::album::Album};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use super::action::Action;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct DeleteAlbum {
 | 
				
			||||||
 | 
					    album: Album,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Action for DeleteAlbum {
 | 
				
			||||||
 | 
					    type Input = Album;
 | 
				
			||||||
 | 
					    type Output = ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn new(input: Self::Input) -> Self {
 | 
				
			||||||
 | 
					        Self { album: input }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn describe(&self) -> String {
 | 
				
			||||||
 | 
					        format!("Deleting album {}", self.album.name,)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async fn execute(&self, ctx: &Context) -> Result<Self::Output> {
 | 
				
			||||||
 | 
					        info!("{}", self.describe());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if !ctx.dry_run {
 | 
				
			||||||
 | 
					            ctx.client.delete_album(&self.album.id).await?;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					mod tests {
 | 
				
			||||||
 | 
					    use std::str::FromStr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use crate::tests::apimock::MockServerExt;
 | 
				
			||||||
 | 
					    use chrono::{DateTime, Utc};
 | 
				
			||||||
 | 
					    use httpmock::MockServer;
 | 
				
			||||||
 | 
					    use uuid::Uuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use crate::Client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_describe() {
 | 
				
			||||||
 | 
					        let album = Album {
 | 
				
			||||||
 | 
					            id: Uuid::parse_str("123e4567-e89b-12d3-a456-426655440000").unwrap(),
 | 
				
			||||||
 | 
					            name: String::from("My christmas holidays"),
 | 
				
			||||||
 | 
					            assets_count: 473,
 | 
				
			||||||
 | 
					            updated_at: DateTime::<Utc>::from_str("2024-11-17T12:55:12Z").unwrap(),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        let action = DeleteAlbum::new(album);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let description = action.describe();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert_eq!(description, "Deleting album My christmas holidays");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[tokio::test]
 | 
				
			||||||
 | 
					    async fn calls_server() {
 | 
				
			||||||
 | 
					        let id = "123e4567-e89b-12d3-a456-426655440000";
 | 
				
			||||||
 | 
					        let server = MockServer::start();
 | 
				
			||||||
 | 
					        let mock = server.delete_album(|when, then| {
 | 
				
			||||||
 | 
					            when.id(&Uuid::from_str(id).unwrap());
 | 
				
			||||||
 | 
					            then.ok();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        let client = Client::new(&server.url(""));
 | 
				
			||||||
 | 
					        let ctx = Context::builder()
 | 
				
			||||||
 | 
					            .client(client)
 | 
				
			||||||
 | 
					            .dry_run(false)
 | 
				
			||||||
 | 
					            .no_confirm(true)
 | 
				
			||||||
 | 
					            .build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        DeleteAlbum::new(Album {
 | 
				
			||||||
 | 
					            id: Uuid::from_str(id).unwrap(),
 | 
				
			||||||
 | 
					            name: String::from("My christmas holidays"),
 | 
				
			||||||
 | 
					            assets_count: 473,
 | 
				
			||||||
 | 
					            updated_at: DateTime::<Utc>::from_str("2024-11-17T12:55:12Z").unwrap(),
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .execute(&ctx)
 | 
				
			||||||
 | 
					        .await
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mock.assert_async().await;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[tokio::test]
 | 
				
			||||||
 | 
					    async fn does_not_call_server_in_dry_run() {
 | 
				
			||||||
 | 
					        let id = "123e4567-e89b-12d3-a456-426655440000";
 | 
				
			||||||
 | 
					        let server = MockServer::start();
 | 
				
			||||||
 | 
					        let mock = server.delete_album(|_when, _then| {});
 | 
				
			||||||
 | 
					        let client = Client::new(&server.url(""));
 | 
				
			||||||
 | 
					        let ctx = Context::builder()
 | 
				
			||||||
 | 
					            .client(client)
 | 
				
			||||||
 | 
					            .dry_run(true)
 | 
				
			||||||
 | 
					            .no_confirm(true)
 | 
				
			||||||
 | 
					            .build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        DeleteAlbum::new(Album {
 | 
				
			||||||
 | 
					            id: Uuid::from_str(id).unwrap(),
 | 
				
			||||||
 | 
					            name: String::from("My christmas holidays"),
 | 
				
			||||||
 | 
					            assets_count: 473,
 | 
				
			||||||
 | 
					            updated_at: DateTime::<Utc>::from_str("2024-11-17T12:55:12Z").unwrap(),
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .execute(&ctx)
 | 
				
			||||||
 | 
					        .await
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mock.assert_hits_async(0).await;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
pub mod action;
 | 
					pub mod action;
 | 
				
			||||||
pub mod confirm;
 | 
					pub mod confirm;
 | 
				
			||||||
 | 
					pub mod delete_album;
 | 
				
			||||||
pub mod fetch_album_assets;
 | 
					pub mod fetch_album_assets;
 | 
				
			||||||
pub mod fetch_all_albums;
 | 
					pub mod fetch_all_albums;
 | 
				
			||||||
pub mod fetch_all_libraries;
 | 
					pub mod fetch_all_libraries;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,6 +78,9 @@ pub(crate) enum Commands {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Serialize, Subcommand)]
 | 
					#[derive(Serialize, Subcommand)]
 | 
				
			||||||
pub(crate) enum AlbumsCommands {
 | 
					pub(crate) enum AlbumsCommands {
 | 
				
			||||||
 | 
					    /// Delete all albums
 | 
				
			||||||
 | 
					    #[serde(rename = "delete")]
 | 
				
			||||||
 | 
					    Delete {},
 | 
				
			||||||
    /// List all albums
 | 
					    /// List all albums
 | 
				
			||||||
    #[serde(rename = "list")]
 | 
					    #[serde(rename = "list")]
 | 
				
			||||||
    List {},
 | 
					    List {},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										29
									
								
								src/commands/delete_albums.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/commands/delete_albums.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					use crate::{
 | 
				
			||||||
 | 
					    actions::{
 | 
				
			||||||
 | 
					        action::Action,
 | 
				
			||||||
 | 
					        confirm::{Confirm, ConfirmResult},
 | 
				
			||||||
 | 
					        delete_album::DeleteAlbum,
 | 
				
			||||||
 | 
					        fetch_all_albums::FetchAllAlbums,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    context::Context,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use color_eyre::eyre::Result;
 | 
				
			||||||
 | 
					use log::info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn delete_albums(ctx: Context) -> Result<()> {
 | 
				
			||||||
 | 
					    let albums = FetchAllAlbums::new(()).execute(&ctx).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if let ConfirmResult::Positive = Confirm::new(None).execute(&ctx).await? {
 | 
				
			||||||
 | 
					        for album in &albums {
 | 
				
			||||||
 | 
					            DeleteAlbum::new(album.clone()).execute(&ctx).await?;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        info!(
 | 
				
			||||||
 | 
					            "Deleted {} albums{}",
 | 
				
			||||||
 | 
					            albums.len(),
 | 
				
			||||||
 | 
					            if ctx.dry_run { " (dry run)" } else { "" }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,4 @@
 | 
				
			||||||
 | 
					pub mod delete_albums;
 | 
				
			||||||
pub mod delete_assets;
 | 
					pub mod delete_assets;
 | 
				
			||||||
pub mod list_albums;
 | 
					pub mod list_albums;
 | 
				
			||||||
pub mod list_assets;
 | 
					pub mod list_assets;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@ use args::{AlbumsCommands, AssetsCommands, LibrariesCommands, PeopleCommands, Se
 | 
				
			||||||
use clap::Parser;
 | 
					use clap::Parser;
 | 
				
			||||||
use color_eyre::eyre::{Result, WrapErr};
 | 
					use color_eyre::eyre::{Result, WrapErr};
 | 
				
			||||||
use color_eyre::Section;
 | 
					use color_eyre::Section;
 | 
				
			||||||
 | 
					use commands::delete_albums::delete_albums;
 | 
				
			||||||
use commands::delete_assets::delete_assets;
 | 
					use commands::delete_assets::delete_assets;
 | 
				
			||||||
use commands::list_albums::list_albums;
 | 
					use commands::list_albums::list_albums;
 | 
				
			||||||
use commands::list_assets::list_assets;
 | 
					use commands::list_assets::list_assets;
 | 
				
			||||||
| 
						 | 
					@ -78,6 +79,7 @@ async fn main() -> Result<()> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    match &args.command {
 | 
					    match &args.command {
 | 
				
			||||||
        Commands::Albums { albums_command } => match albums_command {
 | 
					        Commands::Albums { albums_command } => match albums_command {
 | 
				
			||||||
 | 
					            AlbumsCommands::Delete {} => delete_albums(ctx).await,
 | 
				
			||||||
            AlbumsCommands::List {} => list_albums(ctx).await,
 | 
					            AlbumsCommands::List {} => list_albums(ctx).await,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        Commands::Assets { assets_command } => match assets_command {
 | 
					        Commands::Assets { assets_command } => match assets_command {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
use chrono::{DateTime, NaiveDate, Utc};
 | 
					use chrono::{DateTime, Utc};
 | 
				
			||||||
use uuid::Uuid;
 | 
					use uuid::Uuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::types::AlbumResponseDto;
 | 
					use crate::types::AlbumResponseDto;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue