Add command to delete albums #27
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