listing: autogen mbox filename when exporting mail to directories
Tests / Test on ${{ matrix.build }} (linux-amd64, ubuntu-latest, stable, x86_64-unknown-linux-gnu) (pull_request) Successful in 8m9s Details
Tests / Test on ${{ matrix.build }} (linux-amd64, ubuntu-latest, stable, x86_64-unknown-linux-gnu) (push) Successful in 8m7s Details

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/290/head
Manos Pitsidianakis 2023-08-28 18:20:38 +03:00
parent 59513b2670
commit 31aa9ad29e
Signed by: Manos Pitsidianakis
GPG Key ID: 7729C7707F7E09D0
1 changed files with 31 additions and 14 deletions

View File

@ -22,10 +22,15 @@
use std::{
collections::{BTreeSet, HashMap, HashSet},
convert::TryFrom,
fs::File,
future::Future,
io::{BufWriter, Write},
ops::{Deref, DerefMut},
pin::Pin,
};
use melib::{backends::EnvelopeHashBatch, Address};
use futures::future::try_join_all;
use melib::{backends::EnvelopeHashBatch, mbox::MboxMetadata, utils::datetime, Address};
use smallvec::SmallVec;
use super::*;
@ -655,31 +660,44 @@ pub trait MailListingTrait: ListingTrait {
}
}
ListingAction::ExportMbox(format, ref path) => {
use std::{future::Future, io::Write, pin::Pin};
use futures::future::try_join_all;
let futures: Result<Vec<_>> = envs_to_set
.iter()
.map(|&env_hash| {
account.operation(env_hash).and_then(|mut op| op.as_bytes())
})
.collect::<Result<Vec<_>>>();
let path_ = path.to_path_buf();
let mut path_ = path.to_path_buf();
let format = (*format).unwrap_or_default();
let collection = account.collection.clone();
let (sender, mut receiver) = crate::jobs::oneshot::channel();
let fut: Pin<Box<dyn Future<Output = Result<()>> + Send + 'static>> =
Box::pin(async move {
let cl = async move {
use melib::mbox::MboxMetadata;
// fully capture variables.
let _ = (&envs_to_set, &collection);
let bytes: Vec<Vec<u8>> = try_join_all(futures?).await?;
let envs: Vec<_> = envs_to_set
.iter()
.map(|&env_hash| collection.get_env(env_hash))
.collect();
let mut file =
std::io::BufWriter::new(std::fs::File::create(&path_)?);
if path_.is_dir() {
if envs.len() == 1 {
path_.push(format!("{}.mbox", envs[0].message_id_raw()));
} else {
let now = datetime::timestamp_to_string(
datetime::now(),
Some(datetime::formats::RFC3339_DATETIME),
false,
);
path_.push(format!(
"{}-{}-{}_envelopes.mbox",
now,
envs[0].message_id_raw(),
envs.len(),
));
}
}
let mut file = BufWriter::new(File::create(&path_)?);
let mut iter = envs.iter().zip(bytes);
let tags_lck = collection.tag_index.read().unwrap();
if let Some((env, ref bytes)) = iter.next() {
@ -717,17 +735,16 @@ pub trait MailListingTrait: ListingTrait {
)?;
}
file.flush()?;
Ok(())
Ok(path_)
};
let r: Result<()> = cl.await;
let r: Result<PathBuf> = cl.await;
let _ = sender.send(r);
Ok(())
});
let handle = account
.main_loop_handler
.job_executor
.spawn_blocking("export_to_mbox".into(), fut);
let path = path.to_path_buf();
.spawn_blocking("exporting mbox".into(), fut);
account.insert_job(
handle.job_id,
JobRequest::Generic {
@ -745,7 +762,7 @@ pub trait MailListingTrait: ListingTrait {
err.to_string(),
Some(NotificationType::Error(err.kind)),
),
Ok(Some(Ok(()))) => UIEvent::Notification(
Ok(Some(Ok(path))) => UIEvent::Notification(
Some("Succesfully exported mbox".to_string()),
format!("Wrote to file {}", path.display()),
Some(NotificationType::Info),