Add human-readable identifiers in temp draft files
Draft files that are created in temp directories to be opened and edited by the user's editor get UUID filenames with the `.eml` extension. Give them filenames with the draft subject, recipient and date to make it easier to discern a file's identity on the filesystem. Closes #466 Resolves: <https://git.meli-email.org/meli/meli/issues/466> Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
This commit is contained in:
parent
e9b87b2e40
commit
8f0e1d6640
3 changed files with 53 additions and 6 deletions
|
@ -41,6 +41,7 @@ use crate::{
|
|||
accounts::JobRequest,
|
||||
jobs::{IsAsync, JoinHandle},
|
||||
terminal::embedded::Terminal,
|
||||
types::{sanitize_filename, File},
|
||||
};
|
||||
|
||||
#[cfg(feature = "gpgme")]
|
||||
|
@ -1867,10 +1868,25 @@ impl Component for Composer {
|
|||
account_settings!(context[self.account_hash].composing.wrap_header_preamble)
|
||||
.clone(),
|
||||
);
|
||||
let filename = format!(
|
||||
"{date}_{subject}_{to}_{in_reply_to}",
|
||||
date = self.draft.headers.get(HeaderName::DATE).unwrap_or_default(),
|
||||
subject = self
|
||||
.draft
|
||||
.headers
|
||||
.get(HeaderName::SUBJECT)
|
||||
.unwrap_or_default(),
|
||||
to = self.draft.headers.get(HeaderName::TO).unwrap_or_default(),
|
||||
in_reply_to = self
|
||||
.draft
|
||||
.headers
|
||||
.get(HeaderName::IN_REPLY_TO)
|
||||
.unwrap_or_default()
|
||||
);
|
||||
|
||||
let f = match File::create_temp_file(
|
||||
self.draft.to_edit_string().as_bytes(),
|
||||
None,
|
||||
sanitize_filename(filename).as_deref(),
|
||||
None,
|
||||
Some("eml"),
|
||||
true,
|
||||
|
|
|
@ -33,12 +33,8 @@
|
|||
//! [`UIEvent`] is the type passed around
|
||||
//! [`Component`]'s when something happens.
|
||||
|
||||
#[macro_use]
|
||||
mod helpers;
|
||||
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
|
||||
pub use helpers::*;
|
||||
use indexmap::IndexMap;
|
||||
use melib::{
|
||||
backends::{AccountHash, BackendEvent, MailboxHash},
|
||||
|
@ -54,6 +50,10 @@ use super::{
|
|||
};
|
||||
use crate::components::{Component, ComponentId, ScrollUpdate};
|
||||
|
||||
#[macro_use]
|
||||
mod helpers;
|
||||
pub use helpers::*;
|
||||
|
||||
pub type UIMessage = Box<dyn 'static + std::any::Any + Send + Sync>;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -91,7 +91,11 @@ impl File {
|
|||
dir.push("meli");
|
||||
std::fs::DirBuilder::new().recursive(true).create(&dir)?;
|
||||
if let Some(filename) = filename {
|
||||
dir.push(filename)
|
||||
dir.push(filename);
|
||||
while dir.try_exists().unwrap_or_default() {
|
||||
dir.pop();
|
||||
dir.push(format!("{filename}_{}", Uuid::new_v4().as_simple()));
|
||||
}
|
||||
} else {
|
||||
let u = Uuid::new_v4();
|
||||
dir.push(u.as_simple().to_string());
|
||||
|
@ -136,6 +140,25 @@ pub fn pipe() -> Result<(OwnedFd, OwnedFd)> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Create a shell-friendly filename by removing control characters and
|
||||
/// replacing characters that need escaping.
|
||||
pub fn sanitize_filename(og: String) -> Option<String> {
|
||||
use regex::Regex;
|
||||
|
||||
let regex = Regex::new(r"(?m)[[:space:]]+").ok()?; // _
|
||||
let mut ret = regex.replace_all(&og, "_").to_string();
|
||||
let regex = Regex::new(r"(?m)[[:punct:]]").ok()?; // -
|
||||
ret = regex.replace_all(&ret, "-").to_string();
|
||||
let regex = Regex::new(r"(?m)[[:cntrl:]]*").ok()?; //
|
||||
ret = regex.replace_all(&ret, "").to_string();
|
||||
let regex = Regex::new(r"(?m)[[:blank:]]*").ok()?; //
|
||||
ret = regex.replace_all(&ret, "").to_string();
|
||||
let regex = Regex::new(r"^[[:punct:]]*").ok()?; //
|
||||
ret = regex.replace_all(&ret, "").to_string();
|
||||
let regex = Regex::new(r"[[:punct:]]*$").ok()?; //
|
||||
Some(regex.replace_all(&ret, "").to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -180,4 +203,12 @@ mod tests {
|
|||
|
||||
_ = tempdir.close();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file_sanitize_filename() {
|
||||
assert_eq!(
|
||||
sanitize_filename("Re: Some long subject - \"User Dot. Name\" <user1@example.com> Sent from my bPad 2024-09-07, on a sunny Saturday".to_string()),
|
||||
Some("Re--Some-long-subject----User-Dot--Name---user1-example-com--Sent-from-my-bPad-2024-09-07--on-a-sunny-Saturday".to_string())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue