use anyhow::{anyhow, Result}; use std::io::{Write}; use crate::common::is_binary::is_binary; use crate::config; use crate::core::item_service::ItemService; use clap::Command; use is_terminal::IsTerminal; use std::path::PathBuf; pub fn mode_get( cmd: &mut Command, settings: &config::Settings, ids: &mut Vec, tags: &mut Vec, conn: &mut rusqlite::Connection, data_path: PathBuf, ) -> Result<()> { if !ids.is_empty() && !tags.is_empty() { cmd.error(clap::error::ErrorKind::InvalidValue, "Both ID and tags given, you must supply exactly one ID or at least one tag when using --get").exit(); } else if ids.len() > 1 { cmd.error(clap::error::ErrorKind::InvalidValue, "More than one ID given, you must supply exactly one ID or at least one tag when using --get").exit(); } let mut meta: std::collections::HashMap = std::collections::HashMap::new(); // Collect metadata from environment variables for (key, value) in std::env::vars() { if key.starts_with("KEEP_META_") && key != "KEEP_META_PLUGINS" { let meta_name = key.strip_prefix("KEEP_META_").unwrap(); meta.insert(meta_name.to_string(), value); } } let item_service = ItemService::new(data_path); let item_with_content = item_service.find_item(conn, ids, tags, &meta) .and_then(|item_with_meta| { let item_id = item_with_meta.item.id.unwrap(); item_service.get_item_content(conn, item_id) }) .map_err(|e| anyhow!("Unable to find matching item in database: {}", e))?; let content = &item_with_content.content; // Determine if we should detect binary data let mut detect_binary = !settings.force && std::io::stdout().is_terminal(); if detect_binary { let meta_map = item_with_content.item_with_meta.meta_as_map(); if let Some(binary_val) = meta_map.get("binary") { if binary_val == "false" { detect_binary = false; } else if binary_val == "true" { return Err(anyhow!( "Refusing to output binary data to TTY, use --force to override" )); } } } if detect_binary && is_binary(content) { return Err(anyhow!( "Refusing to output binary data to TTY, use --force to override" )); } std::io::stdout().write_all(content)?; Ok(()) }