feat: add central metadata output handler
Co-authored-by: aider (openai/andrew/openrouter/qwen/qwen3-coder) <aider@aider.chat>
This commit is contained in:
@@ -38,6 +38,19 @@ pub enum MetaPluginType {
|
|||||||
FullHostname,
|
FullHostname,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Central function to handle metadata output with name mapping
|
||||||
|
pub fn output_metadata(conn: &Connection, item_id: i64, name: &str, value: String, output_names: &std::collections::HashMap<String, String>) -> Result<()> {
|
||||||
|
let output_name = output_names.get(name).cloned().unwrap_or_else(|| name.to_string());
|
||||||
|
debug!("META: Saving metadata: item_id={}, name={}, value={}", item_id, output_name, value);
|
||||||
|
let meta = crate::db::Meta {
|
||||||
|
id: item_id,
|
||||||
|
name: output_name,
|
||||||
|
value,
|
||||||
|
};
|
||||||
|
crate::db::store_meta(conn, meta)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub trait MetaPlugin {
|
pub trait MetaPlugin {
|
||||||
fn is_supported(&self) -> bool {
|
fn is_supported(&self) -> bool {
|
||||||
true
|
true
|
||||||
@@ -64,17 +77,11 @@ pub trait MetaPlugin {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save metadata to database
|
// Save metadata to database using central output handler
|
||||||
fn save_meta(&mut self, conn: &Connection, item_id: i64, value: String) -> Result<()> {
|
fn save_meta(&mut self, conn: &Connection, item_id: i64, value: String) -> Result<()> {
|
||||||
let meta_name = self.meta_name();
|
let meta_name = self.meta_name();
|
||||||
debug!("META: Saving metadata: item_id={}, name={}, value={}", item_id, meta_name, value);
|
// Default implementation: no output name mapping
|
||||||
let meta = crate::db::Meta {
|
output_metadata(conn, item_id, &meta_name, value, &std::collections::HashMap::new())
|
||||||
id: item_id,
|
|
||||||
name: meta_name,
|
|
||||||
value,
|
|
||||||
};
|
|
||||||
crate::db::store_meta(conn, meta)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure plugin with options
|
// Configure plugin with options
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use sha2::{Digest, Sha256};
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
|
||||||
use crate::meta_plugin::MetaPlugin;
|
use crate::meta_plugin::{MetaPlugin, output_metadata};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct DigestSha256MetaPlugin {
|
pub struct DigestSha256MetaPlugin {
|
||||||
@@ -11,7 +11,7 @@ pub struct DigestSha256MetaPlugin {
|
|||||||
meta_name: String,
|
meta_name: String,
|
||||||
item_id: Option<i64>,
|
item_id: Option<i64>,
|
||||||
conn: Option<*mut Connection>,
|
conn: Option<*mut Connection>,
|
||||||
output_name: Option<String>,
|
output_names: std::collections::HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DigestSha256MetaPlugin {
|
impl DigestSha256MetaPlugin {
|
||||||
@@ -21,7 +21,7 @@ impl DigestSha256MetaPlugin {
|
|||||||
meta_name: "digest_sha256".to_string(),
|
meta_name: "digest_sha256".to_string(),
|
||||||
item_id: None,
|
item_id: None,
|
||||||
conn: None,
|
conn: None,
|
||||||
output_name: None,
|
output_names: std::collections::HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,13 +47,8 @@ impl MetaPlugin for DigestSha256MetaPlugin {
|
|||||||
let hash_result = self.hasher.finalize_reset();
|
let hash_result = self.hasher.finalize_reset();
|
||||||
let hex_string = format!("{:x}", hash_result);
|
let hex_string = format!("{:x}", hash_result);
|
||||||
|
|
||||||
// Save the hash as metadata
|
// Save the hash as metadata using central output handler
|
||||||
let meta = crate::db::Meta {
|
let _ = output_metadata(conn_ref, item_id, &self.meta_name, hex_string, &self.output_names);
|
||||||
id: item_id,
|
|
||||||
name: self.get_output_name(&self.meta_name),
|
|
||||||
value: hex_string,
|
|
||||||
};
|
|
||||||
crate::db::store_meta(conn_ref, meta)?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -71,9 +66,7 @@ impl MetaPlugin for DigestSha256MetaPlugin {
|
|||||||
if let Some(outputs_map) = outputs.as_mapping() {
|
if let Some(outputs_map) = outputs.as_mapping() {
|
||||||
for (key, value) in outputs_map {
|
for (key, value) in outputs_map {
|
||||||
if let (Some(key_str), Some(value_str)) = (key.as_str(), value.as_str()) {
|
if let (Some(key_str), Some(value_str)) = (key.as_str(), value.as_str()) {
|
||||||
if key_str == "digest_sha256" {
|
self.output_names.insert(key_str.to_string(), value_str.to_string());
|
||||||
self.output_name = Some(value_str.to_string());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,7 +75,7 @@ impl MetaPlugin for DigestSha256MetaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_output_name(&self, default_name: &str) -> String {
|
fn get_output_name(&self, default_name: &str) -> String {
|
||||||
self.output_name.clone().unwrap_or_else(|| default_name.to_string())
|
self.output_names.get(default_name).cloned().unwrap_or_else(|| default_name.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use magic::{Cookie, CookieFlags};
|
|||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use crate::meta_plugin::MetaPlugin;
|
use crate::meta_plugin::{MetaPlugin, output_metadata};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MagicFileMetaPlugin {
|
pub struct MagicFileMetaPlugin {
|
||||||
@@ -64,36 +64,21 @@ impl MagicFileMetaPlugin {
|
|||||||
// Save file type
|
// Save file type
|
||||||
if let Ok(file_type) = self.get_magic_result(CookieFlags::empty()) {
|
if let Ok(file_type) = self.get_magic_result(CookieFlags::empty()) {
|
||||||
if !file_type.is_empty() {
|
if !file_type.is_empty() {
|
||||||
let meta = crate::db::Meta {
|
let _ = output_metadata(conn_ref, item_id, "file_type", file_type, &self.output_names);
|
||||||
id: item_id,
|
|
||||||
name: self.get_output_name("file_type"),
|
|
||||||
value: file_type,
|
|
||||||
};
|
|
||||||
let _ = crate::db::store_meta(conn_ref, meta);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save MIME type
|
// Save MIME type
|
||||||
if let Ok(mime_type) = self.get_magic_result(CookieFlags::MIME_TYPE) {
|
if let Ok(mime_type) = self.get_magic_result(CookieFlags::MIME_TYPE) {
|
||||||
if !mime_type.is_empty() {
|
if !mime_type.is_empty() {
|
||||||
let meta = crate::db::Meta {
|
let _ = output_metadata(conn_ref, item_id, "mime_type", mime_type, &self.output_names);
|
||||||
id: item_id,
|
|
||||||
name: self.get_output_name("mime_type"),
|
|
||||||
value: mime_type,
|
|
||||||
};
|
|
||||||
let _ = crate::db::store_meta(conn_ref, meta);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save MIME encoding
|
// Save MIME encoding
|
||||||
if let Ok(mime_encoding) = self.get_magic_result(CookieFlags::MIME_ENCODING) {
|
if let Ok(mime_encoding) = self.get_magic_result(CookieFlags::MIME_ENCODING) {
|
||||||
if !mime_encoding.is_empty() {
|
if !mime_encoding.is_empty() {
|
||||||
let meta = crate::db::Meta {
|
let _ = output_metadata(conn_ref, item_id, "mime_encoding", mime_encoding, &self.output_names);
|
||||||
id: item_id,
|
|
||||||
name: self.get_output_name("mime_encoding"),
|
|
||||||
value: mime_encoding,
|
|
||||||
};
|
|
||||||
let _ = crate::db::store_meta(conn_ref, meta);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,13 @@ use uzers::{get_current_uid, get_current_gid, get_current_username, get_current_
|
|||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
|
||||||
use crate::common::is_binary::is_binary;
|
use crate::common::is_binary::is_binary;
|
||||||
use crate::meta_plugin::MetaPlugin;
|
use crate::meta_plugin::{MetaPlugin, output_metadata};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct CwdMetaPlugin {
|
pub struct CwdMetaPlugin {
|
||||||
meta_name: String,
|
meta_name: String,
|
||||||
is_saved: bool,
|
is_saved: bool,
|
||||||
|
output_names: std::collections::HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
@@ -24,7 +25,7 @@ pub struct BinaryMetaPlugin {
|
|||||||
is_saved: bool,
|
is_saved: bool,
|
||||||
item_id: Option<i64>,
|
item_id: Option<i64>,
|
||||||
conn: Option<*mut Connection>,
|
conn: Option<*mut Connection>,
|
||||||
output_name: Option<String>,
|
output_names: std::collections::HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BinaryMetaPlugin {
|
impl BinaryMetaPlugin {
|
||||||
@@ -36,7 +37,7 @@ impl BinaryMetaPlugin {
|
|||||||
is_saved: false,
|
is_saved: false,
|
||||||
item_id: None,
|
item_id: None,
|
||||||
conn: None,
|
conn: None,
|
||||||
output_name: None,
|
output_names: std::collections::HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,13 +68,8 @@ impl MetaPlugin for BinaryMetaPlugin {
|
|||||||
let is_binary = is_binary(&self.buffer);
|
let is_binary = is_binary(&self.buffer);
|
||||||
let value = if is_binary { "true".to_string() } else { "false".to_string() };
|
let value = if is_binary { "true".to_string() } else { "false".to_string() };
|
||||||
|
|
||||||
// Save to database immediately
|
// Save to database immediately using central output handler
|
||||||
let meta = crate::db::Meta {
|
let _ = output_metadata(conn_ref, item_id, &self.meta_name, value, &self.output_names);
|
||||||
id: item_id,
|
|
||||||
name: self.get_output_name(&self.meta_name),
|
|
||||||
value,
|
|
||||||
};
|
|
||||||
let _ = crate::db::store_meta(conn_ref, meta);
|
|
||||||
|
|
||||||
self.is_saved = true;
|
self.is_saved = true;
|
||||||
}
|
}
|
||||||
@@ -98,11 +94,21 @@ impl MetaPlugin for BinaryMetaPlugin {
|
|||||||
self.max_buffer_size = size as usize;
|
self.max_buffer_size = size as usize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(outputs) = options.get("outputs") {
|
||||||
|
if let Some(outputs_map) = outputs.as_mapping() {
|
||||||
|
for (key, value) in outputs_map {
|
||||||
|
if let (Some(key_str), Some(value_str)) = (key.as_str(), value.as_str()) {
|
||||||
|
self.output_names.insert(key_str.to_string(), value_str.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_output_name(&self, default_name: &str) -> String {
|
fn get_output_name(&self, default_name: &str) -> String {
|
||||||
self.output_name.clone().unwrap_or_else(|| default_name.to_string())
|
self.output_names.get(default_name).cloned().unwrap_or_else(|| default_name.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,6 +117,7 @@ impl CwdMetaPlugin {
|
|||||||
CwdMetaPlugin {
|
CwdMetaPlugin {
|
||||||
meta_name: "cwd".to_string(),
|
meta_name: "cwd".to_string(),
|
||||||
is_saved: false,
|
is_saved: false,
|
||||||
|
output_names: std::collections::HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,10 +145,28 @@ impl MetaPlugin for CwdMetaPlugin {
|
|||||||
Ok(path) => path.to_string_lossy().to_string(),
|
Ok(path) => path.to_string_lossy().to_string(),
|
||||||
Err(_) => "unknown".to_string(),
|
Err(_) => "unknown".to_string(),
|
||||||
};
|
};
|
||||||
self.save_meta(conn, item_id, cwd)?;
|
// Use central output handler
|
||||||
|
output_metadata(conn, item_id, &self.meta_name, cwd, &self.output_names)?;
|
||||||
self.is_saved = true;
|
self.is_saved = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn configure(&mut self, options: &std::collections::HashMap<String, serde_yaml::Value>) -> Result<()> {
|
||||||
|
if let Some(outputs) = options.get("outputs") {
|
||||||
|
if let Some(outputs_map) = outputs.as_mapping() {
|
||||||
|
for (key, value) in outputs_map {
|
||||||
|
if let (Some(key_str), Some(value_str)) = (key.as_str(), value.as_str()) {
|
||||||
|
self.output_names.insert(key_str.to_string(), value_str.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_output_name(&self, default_name: &str) -> String {
|
||||||
|
self.output_names.get(default_name).cloned().unwrap_or_else(|| default_name.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
|
|||||||
Reference in New Issue
Block a user