mirror of
https://github.com/NotAShelf/stash.git
synced 2026-04-13 06:23:47 +00:00
db: add MIME sniffing for binary clipboard previews
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I70416269dd40496758b6e5431e77a9456a6a6964
This commit is contained in:
parent
ebf46de99d
commit
181edcefb1
3 changed files with 307 additions and 20 deletions
|
|
@ -10,7 +10,8 @@ use std::{
|
|||
};
|
||||
|
||||
use base64::prelude::*;
|
||||
use log::{debug, error, warn};
|
||||
use log::{debug, error, info, warn};
|
||||
use mime_sniffer::MimeTypeSniffer;
|
||||
use regex::Regex;
|
||||
use rusqlite::{Connection, OptionalExtension, params};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -1065,26 +1066,14 @@ pub fn preview_entry(data: &[u8], mime: Option<&str>, width: u32) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
// For non-text data, use lossy conversion
|
||||
let s = String::from_utf8_lossy(data);
|
||||
truncate(s.trim(), width as usize, "…")
|
||||
}
|
||||
|
||||
pub fn truncate(s: &str, max: usize, ellip: &str) -> String {
|
||||
let char_count = s.chars().count();
|
||||
if char_count > max {
|
||||
let mut result = String::with_capacity(max * 4 + ellip.len()); // UTF-8 worst case
|
||||
let mut char_iter = s.chars();
|
||||
for _ in 0..max {
|
||||
if let Some(c) = char_iter.next() {
|
||||
result.push(c);
|
||||
}
|
||||
}
|
||||
result.push_str(ellip);
|
||||
result
|
||||
} else {
|
||||
s.to_string()
|
||||
// For non-text/non-image data, try to sniff the MIME type
|
||||
if let Some(sniffed) = data.sniff_mime_type() {
|
||||
return format!("[[ binary data {} {} ]]", size_str(data.len()), sniffed);
|
||||
}
|
||||
|
||||
// Shouldn't reach here if MIME is properly set, but just in case
|
||||
info!("Mimetype sniffing failed, omitting");
|
||||
format!("[[ binary data {} ]]", size_str(data.len()))
|
||||
}
|
||||
|
||||
pub fn size_str(size: usize) -> String {
|
||||
|
|
@ -1963,6 +1952,15 @@ mod tests {
|
|||
assert_eq!(size_str(1024 * 1024), "1 MiB");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_preview_entry_binary_sniffed() {
|
||||
// PDF magic bytes
|
||||
let data = b"%PDF-1.4 fake pdf content here for testing";
|
||||
let preview = preview_entry(data, None, 100);
|
||||
assert!(preview.contains("binary data"));
|
||||
assert!(preview.contains("application/pdf"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_copy_entry_returns_data() {
|
||||
let db = test_db();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue