Merge branch 'delete-offline-assets' into 'main'

Delete offline assets

See merge request kernald/immich-tools!15
This commit is contained in:
Marc Plano-Lesay 2024-11-05 03:30:12 +00:00
commit 794a5195ec
7 changed files with 116 additions and 0 deletions

39
Cargo.lock generated
View file

@ -304,6 +304,19 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "console"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"unicode-width",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.9.4" version = "0.9.4"
@ -329,6 +342,19 @@ dependencies = [
"powerfmt", "powerfmt",
] ]
[[package]]
name = "dialoguer"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de"
dependencies = [
"console",
"shell-words",
"tempfile",
"thiserror",
"zeroize",
]
[[package]] [[package]]
name = "directories" name = "directories"
version = "5.0.1" version = "5.0.1"
@ -356,6 +382,12 @@ version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]] [[package]]
name = "encoding_rs" name = "encoding_rs"
version = "0.8.34" version = "0.8.34"
@ -758,6 +790,7 @@ dependencies = [
"chrono", "chrono",
"clap", "clap",
"color-eyre", "color-eyre",
"dialoguer",
"directories", "directories",
"figment", "figment",
"figment_file_provider_adapter", "figment_file_provider_adapter",
@ -1645,6 +1678,12 @@ dependencies = [
"lazy_static", "lazy_static",
] ]
[[package]]
name = "shell-words"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.3.0" version = "1.3.0"

View file

@ -15,6 +15,7 @@ ignored = ["progenitor-client", "regress"]
chrono = { version = "0.4.38", features = ["serde"] } chrono = { version = "0.4.38", features = ["serde"] }
clap = { version = "4.5.20", features = ["derive"] } clap = { version = "4.5.20", features = ["derive"] }
color-eyre = "0.6.3" color-eyre = "0.6.3"
dialoguer = "0.11.0"
directories = "5.0.1" directories = "5.0.1"
figment = { version = "0.10.19", features = ["env", "toml"] } figment = { version = "0.10.19", features = ["env", "toml"] }
figment_file_provider_adapter = "0.1.1" figment_file_provider_adapter = "0.1.1"

View file

@ -4,6 +4,8 @@
- List named faces that do not have an associated date of birth - List named faces that do not have an associated date of birth
- Synchronise date of births from a vcard file - Synchronise date of births from a vcard file
- List and delete assets, including filtering offline assets only
- Show details about the server
Some other features are planned, mainly around using external libraries. Feature ideas and contributions welcome. Some other features are planned, mainly around using external libraries. Feature ideas and contributions welcome.

View file

@ -20,6 +20,10 @@ pub(crate) struct Opts {
#[arg(short, long)] #[arg(short, long)]
pub dry_run: bool, pub dry_run: bool,
/// If enabled, don't ask for confirmation of destructive actions
#[arg(short, long)]
pub no_confirm: bool,
#[command(subcommand)] #[command(subcommand)]
#[serde(flatten)] #[serde(flatten)]
pub command: Commands, pub command: Commands,
@ -53,6 +57,13 @@ pub(crate) enum Commands {
#[derive(Serialize, Subcommand)] #[derive(Serialize, Subcommand)]
pub(crate) enum AssetsCommands { pub(crate) enum AssetsCommands {
/// Delete all assets
#[serde(rename = "delete")]
Delete {
/// Delete only offline assets
#[arg(short, long, action)]
offline: bool,
},
/// List all assets /// List all assets
#[serde(rename = "list")] #[serde(rename = "list")]
List { List {

View file

@ -0,0 +1,58 @@
use crate::{
utils::assets::{fetch_all_assets, AssetQuery},
Client,
};
use color_eyre::eyre::Result;
use dialoguer::{theme::ColorfulTheme, Confirm};
use log::info;
use uuid::Uuid;
pub async fn delete_assets(
client: &Client,
offline: bool,
dry_run: bool,
no_confirm: bool,
) -> Result<()> {
let query = AssetQuery {
is_offline: if offline { Some(true) } else { None },
..Default::default()
};
let assets = fetch_all_assets(query, client).await?;
for asset in &assets {
info!(
"Deleting asset {} located at {}",
asset.id, asset.original_path
);
}
if !dry_run {
if !(no_confirm
|| Confirm::with_theme(&ColorfulTheme::default())
.with_prompt("Do you want to continue?")
.interact()?)
{
return Ok(());
}
let asset_ids: Result<Vec<_>, uuid::Error> = assets
.iter()
.map(|asset| Uuid::parse_str(&asset.id))
.collect();
client
.delete_assets(&crate::types::AssetBulkDeleteDto {
force: Some(true),
ids: asset_ids?,
})
.await?;
}
info!(
"Deleted {} assets{}",
assets.len(),
if dry_run { " (dry run)" } else { "" }
);
Ok(())
}

View file

@ -1,3 +1,4 @@
pub mod delete_assets;
pub mod list_assets; pub mod list_assets;
pub mod missing_date_of_birth; pub mod missing_date_of_birth;
pub mod server_features; pub mod server_features;

View file

@ -5,6 +5,7 @@ use args::{AssetsCommands, PeopleCommands, ServerCommands};
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_assets::delete_assets;
use commands::list_assets::list_assets; use commands::list_assets::list_assets;
use commands::missing_date_of_birth::missing_date_of_birth; use commands::missing_date_of_birth::missing_date_of_birth;
use commands::server_features::server_features; use commands::server_features::server_features;
@ -54,6 +55,9 @@ async fn main() -> Result<()> {
match &args.command { match &args.command {
Commands::Assets { assets_command } => match assets_command { Commands::Assets { assets_command } => match assets_command {
AssetsCommands::Delete { offline } => {
delete_assets(&client, *offline, args.dry_run, args.no_confirm).await
}
AssetsCommands::List { offline } => list_assets(*offline, &client).await, AssetsCommands::List { offline } => list_assets(*offline, &client).await,
}, },
Commands::People { people_command } => match people_command { Commands::People { people_command } => match people_command {