feat: implement unified settings system
Co-authored-by: aider (openai/andrew/openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
This commit is contained in:
110
src/config.rs
110
src/config.rs
@@ -3,15 +3,21 @@ use std::fs;
|
|||||||
use anyhow::{Result, Context};
|
use anyhow::{Result, Context};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
use crate::args::{Args, KeyValue};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
|
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub dir: Option<PathBuf>,
|
pub dir: Option<PathBuf>,
|
||||||
pub list_format: Option<String>,
|
pub list_format: Option<String>,
|
||||||
pub human_readable: Option<bool>,
|
pub human_readable: Option<bool>,
|
||||||
|
pub output_format: Option<String>,
|
||||||
|
pub verbose: Option<u8>,
|
||||||
|
pub quiet: Option<bool>,
|
||||||
|
pub force: Option<bool>,
|
||||||
pub server: Option<ServerConfig>,
|
pub server: Option<ServerConfig>,
|
||||||
pub compression_plugin: Option<CompressionPluginConfig>,
|
pub compression_plugin: Option<CompressionPluginConfig>,
|
||||||
pub meta_plugins: Option<Vec<MetaPluginConfig>>,
|
pub meta_plugins: Option<Vec<MetaPluginConfig>>,
|
||||||
|
pub digest: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
@@ -31,6 +37,110 @@ pub struct MetaPluginConfig {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Unified settings that merges config file and CLI arguments
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Settings {
|
||||||
|
pub dir: PathBuf,
|
||||||
|
pub list_format: String,
|
||||||
|
pub human_readable: bool,
|
||||||
|
pub output_format: Option<String>,
|
||||||
|
pub verbose: u8,
|
||||||
|
pub quiet: bool,
|
||||||
|
pub force: bool,
|
||||||
|
pub server_password: Option<String>,
|
||||||
|
pub compression: Option<String>,
|
||||||
|
pub digest: Option<String>,
|
||||||
|
pub meta_plugins: Vec<String>,
|
||||||
|
pub meta: Vec<KeyValue>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Settings {
|
||||||
|
/// Create unified settings from config and args with proper priority
|
||||||
|
pub fn from_config_and_args(config: &Config, args: &Args, default_dir: PathBuf) -> Result<Self> {
|
||||||
|
// Apply priority: CLI args > env vars > config file > defaults
|
||||||
|
|
||||||
|
let dir = args.options.dir.clone()
|
||||||
|
.or_else(|| config.dir.clone())
|
||||||
|
.unwrap_or(default_dir);
|
||||||
|
|
||||||
|
let list_format = if args.options.list_format != "id,time,size,tags,meta:hostname" {
|
||||||
|
args.options.list_format.clone()
|
||||||
|
} else {
|
||||||
|
config.list_format.clone()
|
||||||
|
.unwrap_or_else(|| "id,time,size,tags,meta:hostname".to_string())
|
||||||
|
};
|
||||||
|
|
||||||
|
let human_readable = args.options.human_readable || config.human_readable.unwrap_or(false);
|
||||||
|
|
||||||
|
let output_format = args.options.output_format.clone()
|
||||||
|
.or_else(|| config.output_format.clone());
|
||||||
|
|
||||||
|
let verbose = if args.options.verbose > 0 {
|
||||||
|
args.options.verbose
|
||||||
|
} else {
|
||||||
|
config.verbose.unwrap_or(0)
|
||||||
|
};
|
||||||
|
|
||||||
|
let quiet = args.options.quiet || config.quiet.unwrap_or(false);
|
||||||
|
let force = args.options.force || config.force.unwrap_or(false);
|
||||||
|
|
||||||
|
let server_password = args.options.server_password.clone()
|
||||||
|
.or_else(|| config.get_server_password().ok().flatten());
|
||||||
|
|
||||||
|
let compression = args.item.compression.clone()
|
||||||
|
.or_else(|| config.compression_plugin.as_ref().map(|c| c.name.clone()));
|
||||||
|
|
||||||
|
let digest = args.item.digest.clone()
|
||||||
|
.or_else(|| config.digest.clone());
|
||||||
|
|
||||||
|
let meta_plugins = if !args.item.meta_plugins.is_empty() {
|
||||||
|
args.item.meta_plugins.clone()
|
||||||
|
} else {
|
||||||
|
config.meta_plugins.as_ref()
|
||||||
|
.map(|plugins| plugins.iter().map(|p| p.name.clone()).collect())
|
||||||
|
.unwrap_or_default()
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Settings {
|
||||||
|
dir,
|
||||||
|
list_format,
|
||||||
|
human_readable,
|
||||||
|
output_format,
|
||||||
|
verbose,
|
||||||
|
quiet,
|
||||||
|
force,
|
||||||
|
server_password,
|
||||||
|
compression,
|
||||||
|
digest,
|
||||||
|
meta_plugins,
|
||||||
|
meta: args.item.meta.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get server address from args or config
|
||||||
|
pub fn get_server_address(&self, args: &Args, config: &Config) -> Option<String> {
|
||||||
|
// CLI args take priority
|
||||||
|
if let Some(server_addr) = &args.mode.server {
|
||||||
|
return Some(server_addr.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then config file
|
||||||
|
if let Some(server_config) = &config.server {
|
||||||
|
let mut addr = server_config.address.clone().unwrap_or_else(|| "127.0.0.1".to_string());
|
||||||
|
if let Some(port) = server_config.port {
|
||||||
|
if !addr.contains(':') {
|
||||||
|
addr.push_str(&format!(":{}", port));
|
||||||
|
}
|
||||||
|
} else if !addr.contains(':') {
|
||||||
|
addr.push_str(":8080");
|
||||||
|
}
|
||||||
|
return Some(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
/// Load configuration from a file
|
/// Load configuration from a file
|
||||||
pub fn from_file(path: &PathBuf) -> Result<Self> {
|
pub fn from_file(path: &PathBuf) -> Result<Self> {
|
||||||
|
|||||||
101
src/main.rs
101
src/main.rs
@@ -29,7 +29,7 @@ extern crate serde_yaml;
|
|||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
|
||||||
use args::{Args, NumberOrString};
|
use args::{Args, NumberOrString};
|
||||||
use config::Config;
|
use config::{Config, Settings};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main function to handle command-line arguments and execute the appropriate mode.
|
* Main function to handle command-line arguments and execute the appropriate mode.
|
||||||
@@ -67,6 +67,16 @@ fn main() -> Result<(), Error> {
|
|||||||
|
|
||||||
debug!("MAIN: Loaded config: {:?}", config);
|
debug!("MAIN: Loaded config: {:?}", config);
|
||||||
|
|
||||||
|
// Determine default data directory
|
||||||
|
let default_dir = match proj_dirs {
|
||||||
|
Some(ref proj_dirs) => proj_dirs.data_dir().to_path_buf(),
|
||||||
|
None => return Err(anyhow!("Unable to determine data directory")),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create unified settings
|
||||||
|
let settings = Settings::from_config_and_args(&config, &args, default_dir)?;
|
||||||
|
debug!("MAIN: Unified settings: {:?}", settings);
|
||||||
|
|
||||||
let ids = &mut Vec::new();
|
let ids = &mut Vec::new();
|
||||||
let tags = &mut Vec::new();
|
let tags = &mut Vec::new();
|
||||||
|
|
||||||
@@ -114,24 +124,10 @@ fn main() -> Result<(), Error> {
|
|||||||
mode = KeepModes::Status;
|
mode = KeepModes::Status;
|
||||||
} else if args.mode.server.is_some() {
|
} else if args.mode.server.is_some() {
|
||||||
mode = KeepModes::Server;
|
mode = KeepModes::Server;
|
||||||
} else if config.server.is_some() && args.mode.server.is_none() {
|
} else if settings.get_server_address(&args, &config).is_some() && args.mode.server.is_none() {
|
||||||
// If server is configured in config file but not specified via CLI
|
// If server is configured in config file but not specified via CLI
|
||||||
if let Some(server_config) = &config.server {
|
|
||||||
let mut server_addr = String::new();
|
|
||||||
if let Some(address) = &server_config.address {
|
|
||||||
server_addr.push_str(address);
|
|
||||||
} else {
|
|
||||||
server_addr.push_str("127.0.0.1");
|
|
||||||
}
|
|
||||||
if let Some(port) = server_config.port {
|
|
||||||
server_addr.push_str(&format!(":{}", port));
|
|
||||||
} else {
|
|
||||||
server_addr.push_str(":8080");
|
|
||||||
}
|
|
||||||
args.mode.server = Some(server_addr);
|
|
||||||
mode = KeepModes::Server;
|
mode = KeepModes::Server;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if mode == KeepModes::Unknown {
|
if mode == KeepModes::Unknown {
|
||||||
if !ids.is_empty() {
|
if !ids.is_empty() {
|
||||||
@@ -142,7 +138,7 @@ fn main() -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate output format usage
|
// Validate output format usage
|
||||||
if let Some(output_format_str) = &args.options.output_format {
|
if let Some(output_format_str) = &settings.output_format {
|
||||||
if output_format_str != "table" && mode != KeepModes::Info && mode != KeepModes::Status && mode != KeepModes::List {
|
if output_format_str != "table" && mode != KeepModes::Info && mode != KeepModes::Status && mode != KeepModes::List {
|
||||||
cmd.error(
|
cmd.error(
|
||||||
ErrorKind::InvalidValue,
|
ErrorKind::InvalidValue,
|
||||||
@@ -152,7 +148,7 @@ fn main() -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate human-readable usage
|
// Validate human-readable usage
|
||||||
if args.options.human_readable && mode != KeepModes::List && mode != KeepModes::Info {
|
if settings.human_readable && mode != KeepModes::List && mode != KeepModes::Info {
|
||||||
cmd.error(
|
cmd.error(
|
||||||
ErrorKind::InvalidValue,
|
ErrorKind::InvalidValue,
|
||||||
"--human-readable can only be used with --list and --info modes"
|
"--human-readable can only be used with --list and --info modes"
|
||||||
@@ -160,7 +156,7 @@ fn main() -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate server password usage
|
// Validate server password usage
|
||||||
if args.options.server_password.is_some() && mode != KeepModes::Server {
|
if settings.server_password.is_some() && mode != KeepModes::Server {
|
||||||
cmd.error(
|
cmd.error(
|
||||||
ErrorKind::InvalidValue,
|
ErrorKind::InvalidValue,
|
||||||
"--server-password can only be used with --server mode"
|
"--server-password can only be used with --server mode"
|
||||||
@@ -172,58 +168,11 @@ fn main() -> Result<(), Error> {
|
|||||||
debug!("MAIN: tags: {:?}", tags);
|
debug!("MAIN: tags: {:?}", tags);
|
||||||
debug!("MAIN: mode: {:?}", mode);
|
debug!("MAIN: mode: {:?}", mode);
|
||||||
|
|
||||||
// Apply configuration priority: CLI args > env vars > config file > defaults
|
|
||||||
if args.options.dir.is_none() {
|
|
||||||
if let Some(config_dir) = &config.dir {
|
|
||||||
args.options.dir = Some(config_dir.clone());
|
|
||||||
} else {
|
|
||||||
match proj_dirs {
|
|
||||||
Some(proj_dirs) => args.options.dir = Some(proj_dirs.data_dir().to_path_buf()),
|
|
||||||
None => return Err(anyhow!("Unable to determine data directory")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply list_format from config if not set via CLI/env
|
|
||||||
if args.options.list_format == "id,time,size,tags,meta:hostname" {
|
|
||||||
if let Some(config_list_format) = &config.list_format {
|
|
||||||
args.options.list_format = config_list_format.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply human_readable from config if not set via CLI
|
|
||||||
if !args.options.human_readable {
|
|
||||||
if let Some(config_human_readable) = config.human_readable {
|
|
||||||
args.options.human_readable = config_human_readable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply server password from config file if not set via CLI/env
|
|
||||||
if args.options.server_password.is_none() {
|
|
||||||
if let Ok(Some(password)) = config.get_server_password() {
|
|
||||||
args.options.server_password = Some(password);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply compression from config if not set via CLI/env
|
|
||||||
if args.item.compression.is_none() {
|
|
||||||
if let Some(compression_plugin) = &config.compression_plugin {
|
|
||||||
args.item.compression = Some(compression_plugin.name.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply meta_plugins from config if not set via CLI/env
|
|
||||||
if args.item.meta_plugins.is_empty() {
|
|
||||||
if let Some(meta_plugins) = &config.meta_plugins {
|
|
||||||
args.item.meta_plugins = meta_plugins.iter().map(|p| p.name.clone()).collect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::umask(0o077);
|
libc::umask(0o077);
|
||||||
}
|
}
|
||||||
|
|
||||||
let data_path = args.options.dir.clone().unwrap();
|
let data_path = settings.dir.clone();
|
||||||
let mut db_path = data_path.clone();
|
let mut db_path = data_path.clone();
|
||||||
db_path.push("keep-1.db");
|
db_path.push("keep-1.db");
|
||||||
|
|
||||||
@@ -238,31 +187,31 @@ fn main() -> Result<(), Error> {
|
|||||||
|
|
||||||
match mode {
|
match mode {
|
||||||
KeepModes::Save => {
|
KeepModes::Save => {
|
||||||
crate::modes::save::mode_save(&mut cmd, &args, ids, tags, &mut conn, data_path)?
|
crate::modes::save::mode_save(&mut cmd, &settings, &config, ids, tags, &mut conn, data_path)?
|
||||||
}
|
}
|
||||||
KeepModes::Get => {
|
KeepModes::Get => {
|
||||||
crate::modes::get::mode_get(&mut cmd, &args, ids, tags, &mut conn, data_path)?
|
crate::modes::get::mode_get(&mut cmd, &settings, &config, ids, tags, &mut conn, data_path)?
|
||||||
}
|
}
|
||||||
KeepModes::Diff => {
|
KeepModes::Diff => {
|
||||||
crate::modes::diff::mode_diff(&mut cmd, &args, ids, tags, &mut conn, data_path)?
|
crate::modes::diff::mode_diff(&mut cmd, &settings, &config, ids, tags, &mut conn, data_path)?
|
||||||
}
|
}
|
||||||
KeepModes::List => {
|
KeepModes::List => {
|
||||||
crate::modes::list::mode_list(&mut cmd, &args, ids, tags, &mut conn, data_path)?
|
crate::modes::list::mode_list(&mut cmd, &settings, &config, ids, tags, &mut conn, data_path)?
|
||||||
}
|
}
|
||||||
KeepModes::Update => {
|
KeepModes::Update => {
|
||||||
crate::modes::update::mode_update(&mut cmd, &args, ids, tags, &mut conn, data_path)?
|
crate::modes::update::mode_update(&mut cmd, &settings, &config, ids, tags, &mut conn, data_path)?
|
||||||
}
|
}
|
||||||
KeepModes::Info => {
|
KeepModes::Info => {
|
||||||
crate::modes::info::mode_info(&mut cmd, &args, ids, tags, &mut conn, data_path)?
|
crate::modes::info::mode_info(&mut cmd, &settings, &config, ids, tags, &mut conn, data_path)?
|
||||||
}
|
}
|
||||||
KeepModes::Delete => {
|
KeepModes::Delete => {
|
||||||
crate::modes::delete::mode_delete(&mut cmd, &args, ids, tags, &mut conn, data_path)?
|
crate::modes::delete::mode_delete(&mut cmd, &settings, &config, ids, tags, &mut conn, data_path)?
|
||||||
}
|
}
|
||||||
KeepModes::Status => {
|
KeepModes::Status => {
|
||||||
crate::modes::status::mode_status(&mut cmd, &args, data_path, db_path)?
|
crate::modes::status::mode_status(&mut cmd, &settings, &config, data_path, db_path)?
|
||||||
}
|
}
|
||||||
KeepModes::Server => {
|
KeepModes::Server => {
|
||||||
crate::modes::server::mode_server(&mut cmd, &args, &mut conn, data_path)?
|
crate::modes::server::mode_server(&mut cmd, &settings, &config, &mut conn, data_path)?
|
||||||
}
|
}
|
||||||
KeepModes::Unknown => todo!(),
|
KeepModes::Unknown => todo!(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,12 +157,6 @@ impl FromStr for OutputFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_output_format(args: &Args) -> OutputFormat {
|
|
||||||
args.options.output_format
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|s| OutputFormat::from_str(s).ok())
|
|
||||||
.unwrap_or(OutputFormat::Table)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cmd_args_meta_plugin_types(cmd: &mut Command, args: &Args) -> Vec<MetaPluginType> {
|
pub fn cmd_args_meta_plugin_types(cmd: &mut Command, args: &Args) -> Vec<MetaPluginType> {
|
||||||
let mut meta_plugin_types = Vec::new();
|
let mut meta_plugin_types = Vec::new();
|
||||||
@@ -200,3 +194,83 @@ pub fn cmd_args_meta_plugin_types(cmd: &mut Command, args: &Args) -> Vec<MetaPlu
|
|||||||
|
|
||||||
meta_plugin_types
|
meta_plugin_types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn settings_meta_plugin_types(cmd: &mut Command, settings: &crate::config::Settings) -> Vec<MetaPluginType> {
|
||||||
|
let mut meta_plugin_types = Vec::new();
|
||||||
|
|
||||||
|
// Handle comma-separated values in each meta_plugins argument
|
||||||
|
for meta_plugin_names_str in &settings.meta_plugins {
|
||||||
|
let meta_plugin_names: Vec<&str> = meta_plugin_names_str.split(',').collect();
|
||||||
|
|
||||||
|
for name in meta_plugin_names {
|
||||||
|
let trimmed_name = name.trim();
|
||||||
|
if trimmed_name.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find the MetaPluginType by meta name
|
||||||
|
let mut found = false;
|
||||||
|
for meta_plugin_type in MetaPluginType::iter() {
|
||||||
|
let mut meta_plugin = crate::meta_plugin::get_meta_plugin(meta_plugin_type.clone());
|
||||||
|
if meta_plugin.meta_name() == trimmed_name {
|
||||||
|
meta_plugin_types.push(meta_plugin_type);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
cmd.error(
|
||||||
|
ErrorKind::InvalidValue,
|
||||||
|
format!("Unknown meta plugin type: {}", trimmed_name),
|
||||||
|
)
|
||||||
|
.exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_plugin_types
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn settings_digest_type(cmd: &mut Command, settings: &crate::config::Settings) -> MetaPluginType {
|
||||||
|
let digest_name = settings
|
||||||
|
.digest
|
||||||
|
.clone()
|
||||||
|
.unwrap_or(MetaPluginType::DigestSha256.to_string());
|
||||||
|
|
||||||
|
let digest_type_opt = MetaPluginType::from_str(&digest_name);
|
||||||
|
if digest_type_opt.is_err() {
|
||||||
|
cmd.error(
|
||||||
|
ErrorKind::InvalidValue,
|
||||||
|
format!("Invalid digest algorithm '{}'. Use 'sha256' or 'md5'", digest_name),
|
||||||
|
)
|
||||||
|
.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
digest_type_opt.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn settings_compression_type(cmd: &mut Command, settings: &crate::config::Settings) -> CompressionType {
|
||||||
|
let compression_name = settings
|
||||||
|
.compression
|
||||||
|
.clone()
|
||||||
|
.unwrap_or(CompressionType::LZ4.to_string());
|
||||||
|
|
||||||
|
let compression_type_opt = CompressionType::from_str(&compression_name);
|
||||||
|
if compression_type_opt.is_err() {
|
||||||
|
cmd.error(
|
||||||
|
ErrorKind::InvalidValue,
|
||||||
|
format!("Invalid compression algorithm '{}'. Supported algorithms: lz4, gzip, xz, zstd", compression_name),
|
||||||
|
)
|
||||||
|
.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
compression_type_opt.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn settings_output_format(settings: &crate::config::Settings) -> OutputFormat {
|
||||||
|
settings.output_format
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|s| OutputFormat::from_str(s).ok())
|
||||||
|
.unwrap_or(OutputFormat::Table)
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ use rusqlite::Connection;
|
|||||||
|
|
||||||
pub fn mode_delete(
|
pub fn mode_delete(
|
||||||
cmd: &mut Command,
|
cmd: &mut Command,
|
||||||
_args: &crate::Args,
|
_settings: &crate::config::Settings,
|
||||||
|
_config: &crate::config::Config,
|
||||||
ids: &mut Vec<i64>,
|
ids: &mut Vec<i64>,
|
||||||
tags: &mut Vec<String>,
|
tags: &mut Vec<String>,
|
||||||
conn: &mut Connection,
|
conn: &mut Connection,
|
||||||
|
|||||||
@@ -293,7 +293,8 @@ fn handle_diff_output(
|
|||||||
|
|
||||||
pub fn mode_diff(
|
pub fn mode_diff(
|
||||||
cmd: &mut Command,
|
cmd: &mut Command,
|
||||||
_args: &crate::Args,
|
_settings: &crate::config::Settings,
|
||||||
|
_config: &crate::config::Config,
|
||||||
ids: &mut Vec<i64>,
|
ids: &mut Vec<i64>,
|
||||||
tags: &mut Vec<String>,
|
tags: &mut Vec<String>,
|
||||||
conn: &mut rusqlite::Connection,
|
conn: &mut rusqlite::Connection,
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ use is_terminal::IsTerminal;
|
|||||||
|
|
||||||
pub fn mode_get(
|
pub fn mode_get(
|
||||||
cmd: &mut Command,
|
cmd: &mut Command,
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
|
_config: &crate::config::Config,
|
||||||
ids: &mut Vec<i64>,
|
ids: &mut Vec<i64>,
|
||||||
tags: &mut Vec<String>,
|
tags: &mut Vec<String>,
|
||||||
conn: &mut rusqlite::Connection,
|
conn: &mut rusqlite::Connection,
|
||||||
@@ -23,7 +24,7 @@ pub fn mode_get(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut meta: std::collections::HashMap<String, String> = std::collections::HashMap::new();
|
let mut meta: std::collections::HashMap<String, String> = std::collections::HashMap::new();
|
||||||
for item in args.item.meta.iter() {
|
for item in settings.meta.iter() {
|
||||||
let item = item.clone();
|
let item = item.clone();
|
||||||
meta.insert(item.key, item.value);
|
meta.insert(item.key, item.value);
|
||||||
}
|
}
|
||||||
@@ -47,7 +48,7 @@ pub fn mode_get(
|
|||||||
item_path.push(item_id.to_string());
|
item_path.push(item_id.to_string());
|
||||||
|
|
||||||
// Determine if we should detect binary data
|
// Determine if we should detect binary data
|
||||||
let mut detect_binary = !args.options.force && std::io::stdout().is_terminal();
|
let mut detect_binary = !settings.force && std::io::stdout().is_terminal();
|
||||||
|
|
||||||
// If we're detecting binary and there's binary metadata, check it
|
// If we're detecting binary and there's binary metadata, check it
|
||||||
if detect_binary {
|
if detect_binary {
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ use prettytable::{Attr, Cell, Row, Table};
|
|||||||
|
|
||||||
pub fn mode_info(
|
pub fn mode_info(
|
||||||
cmd: &mut Command,
|
cmd: &mut Command,
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
|
_config: &crate::config::Config,
|
||||||
ids: &mut Vec<i64>,
|
ids: &mut Vec<i64>,
|
||||||
tags: &mut Vec<String>,
|
tags: &mut Vec<String>,
|
||||||
conn: &mut rusqlite::Connection,
|
conn: &mut rusqlite::Connection,
|
||||||
@@ -32,7 +33,7 @@ pub fn mode_info(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut meta: std::collections::HashMap<String, String> = std::collections::HashMap::new();
|
let mut meta: std::collections::HashMap<String, String> = std::collections::HashMap::new();
|
||||||
for item in args.item.meta.iter() {
|
for item in settings.meta.iter() {
|
||||||
let item = item.clone();
|
let item = item.clone();
|
||||||
meta.insert(item.key, item.value);
|
meta.insert(item.key, item.value);
|
||||||
}
|
}
|
||||||
@@ -46,7 +47,7 @@ pub fn mode_info(
|
|||||||
};
|
};
|
||||||
|
|
||||||
match item_maybe {
|
match item_maybe {
|
||||||
Some(item) => show_item(item, args, conn, data_path),
|
Some(item) => show_item(item, settings, conn, data_path),
|
||||||
None => Err(anyhow!("Unable to find matching item in database")),
|
None => Err(anyhow!("Unable to find matching item in database")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +68,7 @@ struct ItemInfo {
|
|||||||
|
|
||||||
fn show_item(
|
fn show_item(
|
||||||
item: Item, // Using the provided struct definition
|
item: Item, // Using the provided struct definition
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
conn: &mut rusqlite::Connection,
|
conn: &mut rusqlite::Connection,
|
||||||
data_path: PathBuf,
|
data_path: PathBuf,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
@@ -78,10 +79,10 @@ fn show_item(
|
|||||||
.map(|x| x.name)
|
.map(|x| x.name)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let output_format = get_output_format(args);
|
let output_format = crate::modes::common::settings_output_format(settings);
|
||||||
|
|
||||||
if output_format != OutputFormat::Table {
|
if output_format != OutputFormat::Table {
|
||||||
return show_item_structured(item, args, conn, data_path, output_format);
|
return show_item_structured(item, settings, conn, data_path, output_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut table = Table::new();
|
let mut table = Table::new();
|
||||||
@@ -111,7 +112,7 @@ fn show_item(
|
|||||||
]));
|
]));
|
||||||
|
|
||||||
let size_cell = match item.size {
|
let size_cell = match item.size {
|
||||||
Some(size) => Cell::new(format_size(size as u64, args.options.human_readable).as_str()),
|
Some(size) => Cell::new(format_size(size as u64, settings.human_readable).as_str()),
|
||||||
None => Cell::new("Missing")
|
None => Cell::new("Missing")
|
||||||
.with_style(Attr::ForegroundColor(prettytable::color::RED))
|
.with_style(Attr::ForegroundColor(prettytable::color::RED))
|
||||||
.with_style(Attr::Bold),
|
.with_style(Attr::Bold),
|
||||||
@@ -132,7 +133,7 @@ fn show_item(
|
|||||||
|
|
||||||
let file_size_cell = match item_path_buf.metadata() {
|
let file_size_cell = match item_path_buf.metadata() {
|
||||||
Ok(metadata) => {
|
Ok(metadata) => {
|
||||||
Cell::new(format_size(metadata.len(), args.options.human_readable).as_str())
|
Cell::new(format_size(metadata.len(), settings.human_readable).as_str())
|
||||||
}
|
}
|
||||||
Err(_) => Cell::new("Missing")
|
Err(_) => Cell::new("Missing")
|
||||||
.with_style(Attr::ForegroundColor(prettytable::color::RED))
|
.with_style(Attr::ForegroundColor(prettytable::color::RED))
|
||||||
@@ -162,7 +163,7 @@ fn show_item(
|
|||||||
|
|
||||||
fn show_item_structured(
|
fn show_item_structured(
|
||||||
item: Item,
|
item: Item,
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
conn: &mut rusqlite::Connection,
|
conn: &mut rusqlite::Connection,
|
||||||
data_path: PathBuf,
|
data_path: PathBuf,
|
||||||
output_format: OutputFormat,
|
output_format: OutputFormat,
|
||||||
@@ -178,12 +179,12 @@ fn show_item_structured(
|
|||||||
|
|
||||||
let file_size = item_path_buf.metadata().map(|m| m.len()).ok();
|
let file_size = item_path_buf.metadata().map(|m| m.len()).ok();
|
||||||
let file_size_formatted = match file_size {
|
let file_size_formatted = match file_size {
|
||||||
Some(size) => format_size(size, args.options.human_readable),
|
Some(size) => format_size(size, settings.human_readable),
|
||||||
None => "Missing".to_string(),
|
None => "Missing".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let stream_size_formatted = match item.size {
|
let stream_size_formatted = match item.size {
|
||||||
Some(size) => format_size(size as u64, args.options.human_readable),
|
Some(size) => format_size(size as u64, settings.human_readable),
|
||||||
None => "Missing".to_string(),
|
None => "Missing".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ struct ListItem {
|
|||||||
|
|
||||||
pub fn mode_list(
|
pub fn mode_list(
|
||||||
cmd: &mut clap::Command,
|
cmd: &mut clap::Command,
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
|
_config: &crate::config::Config,
|
||||||
ids: &mut Vec<i64>,
|
ids: &mut Vec<i64>,
|
||||||
tags: &Vec<String>,
|
tags: &Vec<String>,
|
||||||
conn: &mut rusqlite::Connection,
|
conn: &mut rusqlite::Connection,
|
||||||
@@ -42,7 +43,7 @@ pub fn mode_list(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut meta: std::collections::HashMap<String, String> = std::collections::HashMap::new();
|
let mut meta: std::collections::HashMap<String, String> = std::collections::HashMap::new();
|
||||||
for item in args.item.meta.iter() {
|
for item in settings.meta.iter() {
|
||||||
let item = item.clone();
|
let item = item.clone();
|
||||||
meta.insert(item.key, item.value);
|
meta.insert(item.key, item.value);
|
||||||
}
|
}
|
||||||
@@ -71,16 +72,16 @@ pub fn mode_list(
|
|||||||
// Fetch all metadata for all items in a single query
|
// Fetch all metadata for all items in a single query
|
||||||
let meta_by_item = crate::db::get_meta_for_items(conn, &item_ids)?;
|
let meta_by_item = crate::db::get_meta_for_items(conn, &item_ids)?;
|
||||||
|
|
||||||
let output_format = get_output_format(args);
|
let output_format = crate::modes::common::settings_output_format(settings);
|
||||||
|
|
||||||
if output_format != OutputFormat::Table {
|
if output_format != OutputFormat::Table {
|
||||||
return show_list_structured(items, tags_by_item, meta_by_item, data_path, args, output_format);
|
return show_list_structured(items, tags_by_item, meta_by_item, data_path, settings, output_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut table = Table::new();
|
let mut table = Table::new();
|
||||||
table.set_format(*prettytable::format::consts::FORMAT_CLEAN);
|
table.set_format(*prettytable::format::consts::FORMAT_CLEAN);
|
||||||
|
|
||||||
let list_format = args.options.list_format.split(",");
|
let list_format = settings.list_format.split(",");
|
||||||
|
|
||||||
let mut title_row = row!();
|
let mut title_row = row!();
|
||||||
|
|
||||||
@@ -141,7 +142,7 @@ pub fn mode_list(
|
|||||||
)),
|
)),
|
||||||
ColumnType::Size => match item.size {
|
ColumnType::Size => match item.size {
|
||||||
Some(size) => Cell::new_align(
|
Some(size) => Cell::new_align(
|
||||||
&size_column(size as u64, args.options.human_readable, column_width),
|
&size_column(size as u64, settings.human_readable, column_width),
|
||||||
Alignment::RIGHT,
|
Alignment::RIGHT,
|
||||||
),
|
),
|
||||||
None => match item_path.metadata() {
|
None => match item_path.metadata() {
|
||||||
@@ -158,7 +159,7 @@ pub fn mode_list(
|
|||||||
},
|
},
|
||||||
ColumnType::FileSize => match item_path.metadata() {
|
ColumnType::FileSize => match item_path.metadata() {
|
||||||
Ok(metadata) => Cell::new_align(
|
Ok(metadata) => Cell::new_align(
|
||||||
&size_column(metadata.len(), args.options.human_readable, column_width),
|
&size_column(metadata.len(), settings.human_readable, column_width),
|
||||||
Alignment::RIGHT,
|
Alignment::RIGHT,
|
||||||
),
|
),
|
||||||
Err(_) => Cell::new_align("Missing", Alignment::RIGHT)
|
Err(_) => Cell::new_align("Missing", Alignment::RIGHT)
|
||||||
@@ -195,7 +196,7 @@ fn show_list_structured(
|
|||||||
tags_by_item: std::collections::HashMap<i64, Vec<String>>,
|
tags_by_item: std::collections::HashMap<i64, Vec<String>>,
|
||||||
meta_by_item: std::collections::HashMap<i64, std::collections::HashMap<String, String>>,
|
meta_by_item: std::collections::HashMap<i64, std::collections::HashMap<String, String>>,
|
||||||
data_path: std::path::PathBuf,
|
data_path: std::path::PathBuf,
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
output_format: OutputFormat,
|
output_format: OutputFormat,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut list_items = Vec::new();
|
let mut list_items = Vec::new();
|
||||||
@@ -210,12 +211,12 @@ fn show_list_structured(
|
|||||||
|
|
||||||
let file_size = item_path.metadata().map(|m| m.len()).ok();
|
let file_size = item_path.metadata().map(|m| m.len()).ok();
|
||||||
let file_size_formatted = match file_size {
|
let file_size_formatted = match file_size {
|
||||||
Some(size) => crate::modes::common::format_size(size, args.options.human_readable),
|
Some(size) => crate::modes::common::format_size(size, settings.human_readable),
|
||||||
None => "Missing".to_string(),
|
None => "Missing".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let size_formatted = match item.size {
|
let size_formatted = match item.size {
|
||||||
Some(size) => crate::modes::common::format_size(size as u64, args.options.human_readable),
|
Some(size) => crate::modes::common::format_size(size as u64, settings.human_readable),
|
||||||
None => "Unknown".to_string(),
|
None => "Unknown".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use log::debug;
|
|||||||
use std::io::{Read, Write, IsTerminal};
|
use std::io::{Read, Write, IsTerminal};
|
||||||
|
|
||||||
// Import the missing functions from common module
|
// Import the missing functions from common module
|
||||||
use crate::modes::common::{cmd_args_digest_type, cmd_args_compression_type, cmd_args_meta_plugin_types};
|
use crate::modes::common::{settings_digest_type, settings_compression_type, settings_meta_plugin_types};
|
||||||
|
|
||||||
fn validate_save_args(cmd: &mut Command, ids: &Vec<i64>) {
|
fn validate_save_args(cmd: &mut Command, ids: &Vec<i64>) {
|
||||||
if !ids.is_empty() {
|
if !ids.is_empty() {
|
||||||
@@ -24,18 +24,18 @@ fn initialize_tags(tags: &mut Vec<String>) {
|
|||||||
|
|
||||||
fn setup_compression_and_plugins(
|
fn setup_compression_and_plugins(
|
||||||
cmd: &mut Command,
|
cmd: &mut Command,
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
) -> (crate::compression_engine::CompressionType, Box<dyn crate::compression_engine::CompressionEngine>, Vec<Box<dyn crate::meta_plugin::MetaPlugin>>) {
|
) -> (crate::compression_engine::CompressionType, Box<dyn crate::compression_engine::CompressionEngine>, Vec<Box<dyn crate::meta_plugin::MetaPlugin>>) {
|
||||||
let digest_type = cmd_args_digest_type(cmd, &args);
|
let digest_type = settings_digest_type(cmd, settings);
|
||||||
debug!("MAIN: Digest type: {:?}", digest_type);
|
debug!("MAIN: Digest type: {:?}", digest_type);
|
||||||
|
|
||||||
let compression_type = cmd_args_compression_type(cmd, &args);
|
let compression_type = settings_compression_type(cmd, settings);
|
||||||
debug!("MAIN: Compression type: {:?}", compression_type);
|
debug!("MAIN: Compression type: {:?}", compression_type);
|
||||||
let compression_engine =
|
let compression_engine =
|
||||||
crate::compression_engine::get_compression_engine(compression_type.clone()).expect("Unable to get compression engine");
|
crate::compression_engine::get_compression_engine(compression_type.clone()).expect("Unable to get compression engine");
|
||||||
|
|
||||||
// Start with meta plugin types from command line
|
// Start with meta plugin types from settings
|
||||||
let mut meta_plugin_types: Vec<crate::meta_plugin::MetaPluginType> = cmd_args_meta_plugin_types(cmd, &args);
|
let mut meta_plugin_types: Vec<crate::meta_plugin::MetaPluginType> = settings_meta_plugin_types(cmd, settings);
|
||||||
debug!("MAIN: Meta plugin types: {:?}", meta_plugin_types);
|
debug!("MAIN: Meta plugin types: {:?}", meta_plugin_types);
|
||||||
|
|
||||||
// Convert digest type to meta plugin type and add to the list if needed
|
// Convert digest type to meta plugin type and add to the list if needed
|
||||||
@@ -78,7 +78,7 @@ fn setup_compression_and_plugins(
|
|||||||
|
|
||||||
fn create_and_log_item(
|
fn create_and_log_item(
|
||||||
conn: &mut rusqlite::Connection,
|
conn: &mut rusqlite::Connection,
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
tags: &Vec<String>,
|
tags: &Vec<String>,
|
||||||
compression_type: &crate::compression_engine::CompressionType,
|
compression_type: &crate::compression_engine::CompressionType,
|
||||||
) -> Result<crate::db::Item, anyhow::Error> {
|
) -> Result<crate::db::Item, anyhow::Error> {
|
||||||
@@ -93,7 +93,7 @@ fn create_and_log_item(
|
|||||||
item.id = Some(id);
|
item.id = Some(id);
|
||||||
debug!("MAIN: Added item {:?}", item.clone());
|
debug!("MAIN: Added item {:?}", item.clone());
|
||||||
|
|
||||||
if !args.options.quiet {
|
if !settings.quiet {
|
||||||
if std::io::stderr().is_terminal() {
|
if std::io::stderr().is_terminal() {
|
||||||
let mut t = term::stderr().unwrap();
|
let mut t = term::stderr().unwrap();
|
||||||
t.reset().unwrap_or(());
|
t.reset().unwrap_or(());
|
||||||
@@ -121,7 +121,7 @@ fn create_and_log_item(
|
|||||||
|
|
||||||
fn setup_item_metadata(
|
fn setup_item_metadata(
|
||||||
conn: &mut rusqlite::Connection,
|
conn: &mut rusqlite::Connection,
|
||||||
_args: &crate::Args,
|
_settings: &crate::config::Settings,
|
||||||
item: &crate::db::Item,
|
item: &crate::db::Item,
|
||||||
tags: &Vec<String>,
|
tags: &Vec<String>,
|
||||||
) -> Result<(), anyhow::Error> {
|
) -> Result<(), anyhow::Error> {
|
||||||
@@ -129,7 +129,7 @@ fn setup_item_metadata(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_item_meta(args: &crate::Args) -> std::collections::HashMap<String, String> {
|
fn collect_item_meta(settings: &crate::config::Settings) -> std::collections::HashMap<String, String> {
|
||||||
let mut item_meta: std::collections::HashMap<String, String> = crate::modes::common::get_meta_from_env();
|
let mut item_meta: std::collections::HashMap<String, String> = crate::modes::common::get_meta_from_env();
|
||||||
|
|
||||||
if let Ok(hostname) = gethostname::gethostname().into_string() {
|
if let Ok(hostname) = gethostname::gethostname().into_string() {
|
||||||
@@ -138,7 +138,7 @@ fn collect_item_meta(args: &crate::Args) -> std::collections::HashMap<String, St
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for item in args.item.meta.iter() {
|
for item in settings.meta.iter() {
|
||||||
let item = item.clone();
|
let item = item.clone();
|
||||||
item_meta.insert(item.key, item.value);
|
item_meta.insert(item.key, item.value);
|
||||||
}
|
}
|
||||||
@@ -230,7 +230,8 @@ fn finalize_meta_plugins(
|
|||||||
|
|
||||||
pub fn mode_save(
|
pub fn mode_save(
|
||||||
cmd: &mut Command,
|
cmd: &mut Command,
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
|
_config: &crate::config::Config,
|
||||||
ids: &mut Vec<i64>,
|
ids: &mut Vec<i64>,
|
||||||
tags: &mut Vec<String>,
|
tags: &mut Vec<String>,
|
||||||
conn: &mut rusqlite::Connection,
|
conn: &mut rusqlite::Connection,
|
||||||
@@ -239,14 +240,14 @@ pub fn mode_save(
|
|||||||
validate_save_args(cmd, ids);
|
validate_save_args(cmd, ids);
|
||||||
initialize_tags(tags);
|
initialize_tags(tags);
|
||||||
|
|
||||||
let (compression_type, compression_engine, mut meta_plugins) = setup_compression_and_plugins(cmd, args);
|
let (compression_type, compression_engine, mut meta_plugins) = setup_compression_and_plugins(cmd, settings);
|
||||||
|
|
||||||
let mut item = create_and_log_item(conn, args, tags, &compression_type)?;
|
let mut item = create_and_log_item(conn, settings, tags, &compression_type)?;
|
||||||
setup_item_metadata(conn, args, &item, tags)?; // Pass mutable reference
|
setup_item_metadata(conn, settings, &item, tags)?; // Pass mutable reference
|
||||||
|
|
||||||
// Save as much as possible in case something breaks - don't use transactions
|
// Save as much as possible in case something breaks - don't use transactions
|
||||||
// This allows partial saves to succeed even if some metadata operations fail
|
// This allows partial saves to succeed even if some metadata operations fail
|
||||||
let item_meta = collect_item_meta(args);
|
let item_meta = collect_item_meta(settings);
|
||||||
let item_id = item.id.ok_or_else(|| anyhow!("Item missing ID"))?;
|
let item_id = item.id.ok_or_else(|| anyhow!("Item missing ID"))?;
|
||||||
|
|
||||||
for kv in item_meta.iter() {
|
for kv in item_meta.iter() {
|
||||||
|
|||||||
@@ -20,26 +20,28 @@ pub use common::{ServerConfig, AppState, logging_middleware, create_auth_middlew
|
|||||||
|
|
||||||
pub fn mode_server(
|
pub fn mode_server(
|
||||||
_cmd: &mut Command,
|
_cmd: &mut Command,
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
|
config: &crate::config::Config,
|
||||||
conn: &mut rusqlite::Connection,
|
conn: &mut rusqlite::Connection,
|
||||||
data_path: PathBuf,
|
data_path: PathBuf,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let server_address = args.mode.server.as_ref().unwrap();
|
let server_address = settings.get_server_address(&crate::args::Args::parse(), config)
|
||||||
|
.unwrap_or_else(|| "127.0.0.1:8080".to_string());
|
||||||
|
|
||||||
let config = ServerConfig {
|
let server_config = common::ServerConfig {
|
||||||
address: server_address.clone(),
|
address: server_address,
|
||||||
password: args.options.server_password.clone(),
|
password: settings.server_password.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// We need to move the connection into the async runtime
|
// We need to move the connection into the async runtime
|
||||||
let rt = tokio::runtime::Runtime::new()?;
|
let rt = tokio::runtime::Runtime::new()?;
|
||||||
// Take ownership of the connection and move it into the async runtime
|
// Take ownership of the connection and move it into the async runtime
|
||||||
let owned_conn = std::mem::replace(conn, rusqlite::Connection::open_in_memory()?);
|
let owned_conn = std::mem::replace(conn, rusqlite::Connection::open_in_memory()?);
|
||||||
rt.block_on(run_server(config, owned_conn, data_path))
|
rt.block_on(run_server(server_config, owned_conn, data_path))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_server(
|
async fn run_server(
|
||||||
config: ServerConfig,
|
config: common::ServerConfig,
|
||||||
conn: rusqlite::Connection,
|
conn: rusqlite::Connection,
|
||||||
data_dir: PathBuf,
|
data_dir: PathBuf,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
|||||||
@@ -119,15 +119,16 @@ fn build_meta_plugin_table(meta_plugin_info: &Vec<MetaPluginInfo>) -> Table {
|
|||||||
|
|
||||||
pub fn mode_status(
|
pub fn mode_status(
|
||||||
_cmd: &mut Command,
|
_cmd: &mut Command,
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
|
_config: &crate::config::Config,
|
||||||
data_path: PathBuf,
|
data_path: PathBuf,
|
||||||
db_path: PathBuf,
|
db_path: PathBuf,
|
||||||
) -> Result<(), anyhow::Error> {
|
) -> Result<(), anyhow::Error> {
|
||||||
// Determine which meta plugins would be enabled for a save operation
|
// Determine which meta plugins would be enabled for a save operation
|
||||||
let mut meta_plugin_types: Vec<MetaPluginType> = crate::modes::common::cmd_args_meta_plugin_types(_cmd, &args);
|
let mut meta_plugin_types: Vec<MetaPluginType> = crate::modes::common::settings_meta_plugin_types(_cmd, settings);
|
||||||
|
|
||||||
// Add digest type if specified
|
// Add digest type if specified
|
||||||
let digest_type = crate::modes::common::cmd_args_digest_type(_cmd, &args);
|
let digest_type = crate::modes::common::settings_digest_type(_cmd, settings);
|
||||||
let digest_meta_plugin_type = match digest_type {
|
let digest_meta_plugin_type = match digest_type {
|
||||||
crate::meta_plugin::MetaPluginType::DigestSha256 => Some(MetaPluginType::DigestSha256),
|
crate::meta_plugin::MetaPluginType::DigestSha256 => Some(MetaPluginType::DigestSha256),
|
||||||
crate::meta_plugin::MetaPluginType::DigestMd5 => Some(MetaPluginType::DigestMd5),
|
crate::meta_plugin::MetaPluginType::DigestMd5 => Some(MetaPluginType::DigestMd5),
|
||||||
@@ -140,7 +141,7 @@ pub fn mode_status(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let output_format = get_output_format(args);
|
let output_format = crate::modes::common::settings_output_format(settings);
|
||||||
let status_info = generate_status_info(data_path, db_path, &meta_plugin_types);
|
let status_info = generate_status_info(data_path, db_path, &meta_plugin_types);
|
||||||
|
|
||||||
match output_format {
|
match output_format {
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ use rusqlite::Connection;
|
|||||||
|
|
||||||
pub fn mode_update(
|
pub fn mode_update(
|
||||||
cmd: &mut Command,
|
cmd: &mut Command,
|
||||||
args: &crate::Args,
|
settings: &crate::config::Settings,
|
||||||
|
_config: &crate::config::Config,
|
||||||
ids: &mut Vec<i64>,
|
ids: &mut Vec<i64>,
|
||||||
tags: &mut Vec<String>,
|
tags: &mut Vec<String>,
|
||||||
conn: &mut Connection,
|
conn: &mut Connection,
|
||||||
@@ -71,7 +72,7 @@ pub fn mode_update(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let digest_type = cmd_args_digest_type(cmd, args);
|
let digest_type = crate::modes::common::settings_digest_type(cmd, settings);
|
||||||
let digest_meta = get_digest_type_meta(digest_type.clone());
|
let digest_meta = get_digest_type_meta(digest_type.clone());
|
||||||
let digest_value = db::get_item_meta_value(&tx, &item, digest_meta)?;
|
let digest_value = db::get_item_meta_value(&tx, &item, digest_meta)?;
|
||||||
|
|
||||||
@@ -115,9 +116,9 @@ pub fn mode_update(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !args.item.meta.is_empty() {
|
if !settings.meta.is_empty() {
|
||||||
debug!("MAIN: Updating item meta");
|
debug!("MAIN: Updating item meta");
|
||||||
for kv in args.item.meta.iter() {
|
for kv in settings.meta.iter() {
|
||||||
let meta = db::Meta {
|
let meta = db::Meta {
|
||||||
id: item_id,
|
id: item_id,
|
||||||
name: kv.key.to_string(),
|
name: kv.key.to_string(),
|
||||||
|
|||||||
Reference in New Issue
Block a user