Add an assets list command
This commit is contained in:
parent
a8796b2728
commit
c026375ce1
5 changed files with 109 additions and 5 deletions
19
src/args.rs
19
src/args.rs
|
@ -27,6 +27,14 @@ pub(crate) struct Opts {
|
|||
|
||||
#[derive(Serialize, Subcommand)]
|
||||
pub(crate) enum Commands {
|
||||
/// Assets related commands
|
||||
#[serde(rename = "assets")]
|
||||
Assets {
|
||||
#[command(subcommand)]
|
||||
#[serde(flatten)]
|
||||
assets_command: AssetsCommands,
|
||||
},
|
||||
|
||||
/// People related commands
|
||||
#[serde(rename = "people")]
|
||||
People {
|
||||
|
@ -43,6 +51,17 @@ pub(crate) enum Commands {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Subcommand)]
|
||||
pub(crate) enum AssetsCommands {
|
||||
/// List all assets
|
||||
#[serde(rename = "list")]
|
||||
List {
|
||||
/// List only offline assets
|
||||
#[arg(short, long, action)]
|
||||
offline: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Subcommand)]
|
||||
pub(crate) enum PeopleCommands {
|
||||
/// Synchronises date of births from a vcard file
|
||||
|
|
59
src/commands/list_assets.rs
Normal file
59
src/commands/list_assets.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use crate::{
|
||||
utils::assets::{fetch_all_assets, AssetQuery},
|
||||
Client,
|
||||
};
|
||||
use color_eyre::eyre::Result;
|
||||
use tabled::{
|
||||
settings::{
|
||||
object::{Columns, Object, Rows},
|
||||
Format, Style,
|
||||
},
|
||||
Table, Tabled,
|
||||
};
|
||||
#[derive(Tabled)]
|
||||
struct Asset {
|
||||
#[tabled(rename = "Path")]
|
||||
original_file_path: String,
|
||||
#[tabled(rename = "Is offline")]
|
||||
is_offline: bool,
|
||||
#[tabled(rename = "Camera")]
|
||||
model: String,
|
||||
}
|
||||
|
||||
pub async fn list_assets(offline: bool, client: &Client) -> Result<()> {
|
||||
let query = AssetQuery {
|
||||
is_offline: if offline { Some(true) } else { None },
|
||||
with_exif: true,
|
||||
};
|
||||
|
||||
let mut assets: Vec<_> = fetch_all_assets(query, client)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|asset| Asset {
|
||||
is_offline: asset.is_offline,
|
||||
model: asset
|
||||
.exif_info
|
||||
.clone()
|
||||
.and_then(|exif| exif.model)
|
||||
.unwrap_or(String::from("(Unknown)")),
|
||||
original_file_path: asset.original_path,
|
||||
})
|
||||
.collect();
|
||||
|
||||
assets.sort_by_key(|asset| asset.original_file_path.clone());
|
||||
|
||||
println!(
|
||||
"{}",
|
||||
Table::new(assets).with(Style::rounded()).modify(
|
||||
Columns::single(1).not(Rows::first()),
|
||||
Format::content(|s| {
|
||||
match s {
|
||||
"true" => "Yes".to_string(),
|
||||
_ => "No".to_string(),
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
pub mod list_assets;
|
||||
pub mod missing_date_of_birth;
|
||||
pub mod server_features;
|
||||
pub mod server_version;
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
|
||||
|
||||
use crate::args::Commands;
|
||||
use args::{PeopleCommands, ServerCommands};
|
||||
use args::{AssetsCommands, PeopleCommands, ServerCommands};
|
||||
use clap::Parser;
|
||||
use color_eyre::eyre::{Result, WrapErr};
|
||||
use color_eyre::Section;
|
||||
use commands::list_assets::list_assets;
|
||||
use commands::missing_date_of_birth::missing_date_of_birth;
|
||||
use commands::server_features::server_features;
|
||||
use commands::server_version::server_version;
|
||||
|
@ -51,6 +52,9 @@ async fn main() -> Result<()> {
|
|||
validate_client_connection(&client).await?;
|
||||
|
||||
match &args.command {
|
||||
Commands::Assets { assets_command } => match assets_command {
|
||||
AssetsCommands::List { offline } => list_assets(*offline, &client).await,
|
||||
},
|
||||
Commands::People { people_command } => match people_command {
|
||||
PeopleCommands::MissingDateOfBirths {} => missing_date_of_birth(&client).await,
|
||||
PeopleCommands::SyncDateOfBirths { vcard: _ } => {
|
||||
|
|
|
@ -2,9 +2,26 @@ use crate::{
|
|||
types::{AssetResponseDto, MetadataSearchDto},
|
||||
Client,
|
||||
};
|
||||
use chrono::{TimeZone, Utc};
|
||||
use color_eyre::eyre::Result;
|
||||
use log::debug;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct AssetQuery {
|
||||
pub is_offline: Option<bool>,
|
||||
pub with_exif: bool,
|
||||
}
|
||||
|
||||
pub async fn fetch_all_assets(query: AssetQuery, client: &Client) -> Result<Vec<AssetResponseDto>> {
|
||||
debug!("Fetching assets with query {:?}", query);
|
||||
|
||||
// is_offline is ignored, let's fetch trashed assets instead and filter them later
|
||||
let trashed_after = if query.is_offline == Some(true) {
|
||||
Some(Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
pub async fn fetch_all_assets(client: &Client) -> Result<Vec<AssetResponseDto>> {
|
||||
let mut all_assets = Vec::new();
|
||||
let mut page_number = None;
|
||||
let mut has_next_page = true;
|
||||
|
@ -26,7 +43,7 @@ pub async fn fetch_all_assets(client: &Client) -> Result<Vec<AssetResponseDto>>
|
|||
is_favorite: None,
|
||||
is_motion: None,
|
||||
is_not_in_album: None,
|
||||
is_offline: None,
|
||||
is_offline: query.is_offline,
|
||||
is_visible: None,
|
||||
lens_model: None,
|
||||
library_id: None,
|
||||
|
@ -43,14 +60,14 @@ pub async fn fetch_all_assets(client: &Client) -> Result<Vec<AssetResponseDto>>
|
|||
taken_after: None,
|
||||
taken_before: None,
|
||||
thumbnail_path: None,
|
||||
trashed_after: None,
|
||||
trashed_after,
|
||||
trashed_before: None,
|
||||
type_: None,
|
||||
updated_after: None,
|
||||
updated_before: None,
|
||||
with_archived: true,
|
||||
with_deleted: None,
|
||||
with_exif: None,
|
||||
with_exif: Some(query.with_exif),
|
||||
with_people: None,
|
||||
with_stacked: None,
|
||||
})
|
||||
|
@ -64,5 +81,9 @@ pub async fn fetch_all_assets(client: &Client) -> Result<Vec<AssetResponseDto>>
|
|||
.map(|page| page.parse::<f64>().unwrap());
|
||||
}
|
||||
|
||||
if query.is_offline == Some(true) {
|
||||
all_assets.retain(|asset| asset.is_offline);
|
||||
}
|
||||
|
||||
Ok(all_assets)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue