feat: combine magic plugins into single magic_file plugin
Co-authored-by: aider (openai/andrew/openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
This commit is contained in:
@@ -12,7 +12,7 @@ pub mod magic;
|
|||||||
use crate::meta_plugin::program::MetaPluginProgram;
|
use crate::meta_plugin::program::MetaPluginProgram;
|
||||||
use crate::meta_plugin::digest::{DigestSha256MetaPlugin, ReadTimeMetaPlugin, ReadRateMetaPlugin};
|
use crate::meta_plugin::digest::{DigestSha256MetaPlugin, ReadTimeMetaPlugin, ReadRateMetaPlugin};
|
||||||
use crate::meta_plugin::system::{CwdMetaPlugin, BinaryMetaPlugin, UidMetaPlugin, UserMetaPlugin, GidMetaPlugin, GroupMetaPlugin, ShellMetaPlugin, ShellPidMetaPlugin, KeepPidMetaPlugin, HostnameMetaPlugin, FullHostnameMetaPlugin};
|
use crate::meta_plugin::system::{CwdMetaPlugin, BinaryMetaPlugin, UidMetaPlugin, UserMetaPlugin, GidMetaPlugin, GroupMetaPlugin, ShellMetaPlugin, ShellPidMetaPlugin, KeepPidMetaPlugin, HostnameMetaPlugin, FullHostnameMetaPlugin};
|
||||||
use crate::meta_plugin::magic::MagicMetaPlugin;
|
use crate::meta_plugin::magic::MagicFileMetaPlugin;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, strum::EnumIter, strum::Display, strum::EnumString)]
|
#[derive(Debug, Eq, PartialEq, Clone, strum::EnumIter, strum::Display, strum::EnumString)]
|
||||||
#[strum(ascii_case_insensitive)]
|
#[strum(ascii_case_insensitive)]
|
||||||
@@ -20,9 +20,7 @@ pub enum MetaPluginType {
|
|||||||
FileMagic,
|
FileMagic,
|
||||||
FileMime,
|
FileMime,
|
||||||
FileEncoding,
|
FileEncoding,
|
||||||
MagicFileType,
|
MagicFile,
|
||||||
MagicMimeType,
|
|
||||||
MagicMimeEncoding,
|
|
||||||
LineCount,
|
LineCount,
|
||||||
WordCount,
|
WordCount,
|
||||||
Cwd,
|
Cwd,
|
||||||
@@ -88,9 +86,7 @@ pub fn get_meta_plugin(meta_plugin_type: MetaPluginType) -> Box<dyn MetaPlugin>
|
|||||||
MetaPluginType::FileMagic => Box::new(MetaPluginProgram::new("file", vec!["-bE", "-"], "file_magic".to_string(), true)),
|
MetaPluginType::FileMagic => Box::new(MetaPluginProgram::new("file", vec!["-bE", "-"], "file_magic".to_string(), true)),
|
||||||
MetaPluginType::FileMime => Box::new(MetaPluginProgram::new("file", vec!["-b", "--mime-type", "-"], "file_mime".to_string(), true)),
|
MetaPluginType::FileMime => Box::new(MetaPluginProgram::new("file", vec!["-b", "--mime-type", "-"], "file_mime".to_string(), true)),
|
||||||
MetaPluginType::FileEncoding => Box::new(MetaPluginProgram::new("file", vec!["-b", "--mime-encoding", "-"], "file_encoding".to_string(), true)),
|
MetaPluginType::FileEncoding => Box::new(MetaPluginProgram::new("file", vec!["-b", "--mime-encoding", "-"], "file_encoding".to_string(), true)),
|
||||||
MetaPluginType::MagicFileType => Box::new(MagicMetaPlugin::new_file_type()),
|
MetaPluginType::MagicFile => Box::new(MagicFileMetaPlugin::new()),
|
||||||
MetaPluginType::MagicMimeType => Box::new(MagicMetaPlugin::new_mime_type()),
|
|
||||||
MetaPluginType::MagicMimeEncoding => Box::new(MagicMetaPlugin::new_mime_encoding()),
|
|
||||||
MetaPluginType::LineCount => Box::new(MetaPluginProgram::new("wc", vec!["-l"], "line_count".to_string(), true)),
|
MetaPluginType::LineCount => Box::new(MetaPluginProgram::new("wc", vec!["-l"], "line_count".to_string(), true)),
|
||||||
MetaPluginType::WordCount => Box::new(MetaPluginProgram::new("wc", vec!["-w"], "word_count".to_string(), true)),
|
MetaPluginType::WordCount => Box::new(MetaPluginProgram::new("wc", vec!["-w"], "word_count".to_string(), true)),
|
||||||
MetaPluginType::Cwd => Box::new(CwdMetaPlugin::new()),
|
MetaPluginType::Cwd => Box::new(CwdMetaPlugin::new()),
|
||||||
|
|||||||
@@ -2,54 +2,30 @@ use anyhow::Result;
|
|||||||
use magic::{Cookie, CookieFlags};
|
use magic::{Cookie, CookieFlags};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use rusqlite::Connection;
|
||||||
|
|
||||||
use crate::meta_plugin::MetaPlugin;
|
use crate::meta_plugin::MetaPlugin;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MagicMetaPlugin {
|
pub struct MagicFileMetaPlugin {
|
||||||
buffer: Vec<u8>,
|
buffer: Vec<u8>,
|
||||||
meta_name: String,
|
is_saved: bool,
|
||||||
cookie_flags: CookieFlags,
|
item_id: Option<i64>,
|
||||||
|
conn: Option<*mut Connection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MagicMetaPlugin {
|
impl MagicFileMetaPlugin {
|
||||||
pub fn new_file_type() -> MagicMetaPlugin {
|
pub fn new() -> MagicFileMetaPlugin {
|
||||||
MagicMetaPlugin {
|
MagicFileMetaPlugin {
|
||||||
buffer: Vec::new(),
|
buffer: Vec::new(),
|
||||||
meta_name: "magic_file_type".to_string(),
|
is_saved: false,
|
||||||
cookie_flags: CookieFlags::empty(),
|
item_id: None,
|
||||||
|
conn: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_mime_type() -> MagicMetaPlugin {
|
fn get_magic_result(&self, flags: CookieFlags) -> io::Result<String> {
|
||||||
MagicMetaPlugin {
|
let cookie = Cookie::open(flags)
|
||||||
buffer: Vec::new(),
|
|
||||||
meta_name: "magic_mime_type".to_string(),
|
|
||||||
cookie_flags: CookieFlags::MIME_TYPE,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_mime_encoding() -> MagicMetaPlugin {
|
|
||||||
MagicMetaPlugin {
|
|
||||||
buffer: Vec::new(),
|
|
||||||
meta_name: "magic_mime_encoding".to_string(),
|
|
||||||
cookie_flags: CookieFlags::MIME_ENCODING,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MetaPlugin for MagicMetaPlugin {
|
|
||||||
fn is_internal(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create(&self) -> Result<Box<dyn Write>> {
|
|
||||||
// For meta plugins, we don't actually create a writer since we're buffering data internally
|
|
||||||
Ok(Box::new(DummyWriter))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn finalize(&mut self) -> io::Result<String> {
|
|
||||||
let cookie = Cookie::open(self.cookie_flags)
|
|
||||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to open magic cookie: {}", e)))?;
|
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to open magic cookie: {}", e)))?;
|
||||||
|
|
||||||
cookie.load(&[] as &[&str])
|
cookie.load(&[] as &[&str])
|
||||||
@@ -64,7 +40,7 @@ impl MetaPlugin for MagicMetaPlugin {
|
|||||||
// For some magic results, we might want just the first part before semicolon or comma
|
// For some magic results, we might want just the first part before semicolon or comma
|
||||||
let cleaned = if trimmed.contains(';') {
|
let cleaned = if trimmed.contains(';') {
|
||||||
trimmed.split(';').next().unwrap_or(trimmed).trim()
|
trimmed.split(';').next().unwrap_or(trimmed).trim()
|
||||||
} else if trimmed.contains(',') && self.meta_name.contains("mime") {
|
} else if trimmed.contains(',') && flags.contains(CookieFlags::MIME_TYPE | CookieFlags::MIME_ENCODING) {
|
||||||
trimmed.split(',').next().unwrap_or(trimmed).trim()
|
trimmed.split(',').next().unwrap_or(trimmed).trim()
|
||||||
} else {
|
} else {
|
||||||
trimmed
|
trimmed
|
||||||
@@ -73,12 +49,79 @@ impl MetaPlugin for MagicMetaPlugin {
|
|||||||
Ok(cleaned.to_string())
|
Ok(cleaned.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn save_all_magic_metadata(&mut self) -> Result<()> {
|
||||||
|
if let (Some(conn), Some(item_id)) = (self.conn, self.item_id) {
|
||||||
|
let conn = unsafe { &*conn };
|
||||||
|
|
||||||
|
// Save file type
|
||||||
|
if let Ok(file_type) = self.get_magic_result(CookieFlags::empty()) {
|
||||||
|
let meta = crate::db::Meta {
|
||||||
|
id: item_id,
|
||||||
|
name: "magic_file_type".to_string(),
|
||||||
|
value: file_type,
|
||||||
|
};
|
||||||
|
crate::db::store_meta(conn, meta)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save MIME type
|
||||||
|
if let Ok(mime_type) = self.get_magic_result(CookieFlags::MIME_TYPE) {
|
||||||
|
let meta = crate::db::Meta {
|
||||||
|
id: item_id,
|
||||||
|
name: "magic_mime_type".to_string(),
|
||||||
|
value: mime_type,
|
||||||
|
};
|
||||||
|
crate::db::store_meta(conn, meta)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save MIME encoding
|
||||||
|
if let Ok(mime_encoding) = self.get_magic_result(CookieFlags::MIME_ENCODING) {
|
||||||
|
let meta = crate::db::Meta {
|
||||||
|
id: item_id,
|
||||||
|
name: "magic_mime_encoding".to_string(),
|
||||||
|
value: mime_encoding,
|
||||||
|
};
|
||||||
|
crate::db::store_meta(conn, meta)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.is_saved = true;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MetaPlugin for MagicFileMetaPlugin {
|
||||||
|
fn is_internal(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create(&self) -> Result<Box<dyn Write>> {
|
||||||
|
// For meta plugins, we don't actually create a writer since we're buffering data internally
|
||||||
|
Ok(Box::new(DummyWriter))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initialize(&mut self, conn: &Connection, item_id: i64) -> Result<()> {
|
||||||
|
self.item_id = Some(item_id);
|
||||||
|
self.conn = Some(conn as *const Connection as *mut Connection);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finalize(&mut self) -> io::Result<String> {
|
||||||
|
// Save all magic metadata if not already saved
|
||||||
|
if !self.is_saved {
|
||||||
|
if let Err(e) = self.save_all_magic_metadata() {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::Other, format!("Failed to save magic metadata: {}", e)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Return empty string since we save during finalize
|
||||||
|
Ok("".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&mut self, data: &[u8]) {
|
fn update(&mut self, data: &[u8]) {
|
||||||
self.buffer.extend_from_slice(data);
|
self.buffer.extend_from_slice(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn meta_name(&mut self) -> String {
|
fn meta_name(&mut self) -> String {
|
||||||
self.meta_name.clone()
|
"magic_file".to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user