- Add SaveMetaFn callback pattern: meta plugins receive a closure instead of
&Connection, enabling the same plugin code to work in local, client, and
server contexts (collect-to-Vec, collect-to-HashMap, or direct DB write)
- Client save now runs meta plugins locally during streaming (smart client
sets meta=false, server skips its own plugins)
- Add POST /api/item/{id}/update endpoint for re-running plugins on stored
content without downloading compressed data
- Add client update mode (--update with --meta-plugin flags)
- Extract shared utilities: stream_copy, print_serialized, build_path_table,
ensure_default_tag to reduce duplication across modes
- Add upsert_tag for idempotent tag addition (INSERT OR IGNORE)
- Add warn logging on save_meta lock failure in BaseMetaPlugin and MetaService
92 lines
3.4 KiB
Rust
92 lines
3.4 KiB
Rust
use crate::client::KeepClient;
|
|
use crate::modes::common::OutputFormat;
|
|
use crate::modes::common::settings_output_format;
|
|
use clap::Command;
|
|
use comfy_table::{Attribute, Cell, Table};
|
|
use log::debug;
|
|
|
|
pub fn mode(
|
|
client: &KeepClient,
|
|
_cmd: &mut Command,
|
|
settings: &crate::config::Settings,
|
|
) -> Result<(), anyhow::Error> {
|
|
debug!("CLIENT_STATUS: Getting status from remote server");
|
|
|
|
let status_info = client.get_status()?;
|
|
|
|
let output_format = settings_output_format(settings);
|
|
|
|
match output_format {
|
|
OutputFormat::Json | OutputFormat::Yaml => {
|
|
crate::modes::common::print_serialized(&status_info, &output_format)?;
|
|
}
|
|
OutputFormat::Table => {
|
|
// Paths
|
|
let path_table =
|
|
crate::modes::common::build_path_table(&status_info.paths, &settings.table_config);
|
|
println!("PATHS:");
|
|
println!(
|
|
"{}",
|
|
crate::modes::common::trim_lines_end(&path_table.trim_fmt())
|
|
);
|
|
println!();
|
|
|
|
// Configured meta plugins
|
|
if let Some(ref configured) = status_info.configured_meta_plugins
|
|
&& !configured.is_empty()
|
|
{
|
|
let mut sorted = configured.clone();
|
|
sorted.sort_by(|a, b| a.name.cmp(&b.name));
|
|
|
|
let mut table =
|
|
crate::modes::common::create_table_with_config(&settings.table_config);
|
|
table.set_header(vec![
|
|
Cell::new("Plugin Name").add_attribute(Attribute::Bold),
|
|
Cell::new("Enabled").add_attribute(Attribute::Bold),
|
|
]);
|
|
for plugin in &sorted {
|
|
let enabled = status_info.enabled_meta_plugins.contains(&plugin.name);
|
|
table.add_row(vec![
|
|
plugin.name.clone(),
|
|
if enabled { "Yes" } else { "No" }.to_string(),
|
|
]);
|
|
}
|
|
println!("META PLUGINS:");
|
|
println!(
|
|
"{}",
|
|
crate::modes::common::trim_lines_end(&table.trim_fmt())
|
|
);
|
|
println!();
|
|
}
|
|
|
|
// Compression
|
|
if !status_info.compression.is_empty() {
|
|
let mut table =
|
|
crate::modes::common::create_table_with_config(&settings.table_config);
|
|
table.set_header(vec![
|
|
Cell::new("Type").add_attribute(Attribute::Bold),
|
|
Cell::new("Found").add_attribute(Attribute::Bold),
|
|
Cell::new("Default").add_attribute(Attribute::Bold),
|
|
Cell::new("Binary").add_attribute(Attribute::Bold),
|
|
]);
|
|
for comp in &status_info.compression {
|
|
table.add_row(vec![
|
|
comp.compression_type.clone(),
|
|
if comp.found { "Yes" } else { "No" }.to_string(),
|
|
if comp.default { "Yes" } else { "No" }.to_string(),
|
|
comp.binary.clone(),
|
|
]);
|
|
}
|
|
println!("COMPRESSION:");
|
|
println!(
|
|
"{}",
|
|
crate::modes::common::trim_lines_end(&table.trim_fmt())
|
|
);
|
|
println!();
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|