melib/notmuch: avoid parsing entire email in Envelope creation
parent
806254436b
commit
db69349251
|
@ -22,7 +22,7 @@
|
||||||
use crate::backends::*;
|
use crate::backends::*;
|
||||||
use crate::conf::AccountSettings;
|
use crate::conf::AccountSettings;
|
||||||
use crate::email::{Envelope, EnvelopeHash, Flag};
|
use crate::email::{Envelope, EnvelopeHash, Flag};
|
||||||
use crate::error::{MeliError, Result, ResultIntoMeliError};
|
use crate::error::{MeliError, Result};
|
||||||
use crate::shellexpand::ShellExpandTrait;
|
use crate::shellexpand::ShellExpandTrait;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::collections::{
|
use std::collections::{
|
||||||
|
@ -130,31 +130,25 @@ impl DbConnection {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let message_id = message.msg_id_cstr().to_string_lossy().to_string();
|
let message_id = message.msg_id_cstr().to_string_lossy().to_string();
|
||||||
match message.into_envelope(index.clone(), tag_index.clone()) {
|
let env = message.into_envelope(&index, &tag_index);
|
||||||
Ok(env) => {
|
for (&mailbox_hash, m) in mailboxes_lck.iter() {
|
||||||
for (&mailbox_hash, m) in mailboxes_lck.iter() {
|
let query_str = format!("{} id:{}", m.query_str.as_str(), &message_id);
|
||||||
let query_str = format!("{} id:{}", m.query_str.as_str(), &message_id);
|
let query: Query = Query::new(self, &query_str)?;
|
||||||
let query: Query = Query::new(self, &query_str)?;
|
if query.count().unwrap_or(0) > 0 {
|
||||||
if query.count().unwrap_or(0) > 0 {
|
let mut total_lck = m.total.lock().unwrap();
|
||||||
let mut total_lck = m.total.lock().unwrap();
|
let mut unseen_lck = m.unseen.lock().unwrap();
|
||||||
let mut unseen_lck = m.unseen.lock().unwrap();
|
*total_lck += 1;
|
||||||
*total_lck += 1;
|
if !env.is_seen() {
|
||||||
if !env.is_seen() {
|
*unseen_lck += 1;
|
||||||
*unseen_lck += 1;
|
|
||||||
}
|
|
||||||
(event_consumer)(
|
|
||||||
account_hash,
|
|
||||||
BackendEvent::Refresh(RefreshEvent {
|
|
||||||
account_hash,
|
|
||||||
mailbox_hash,
|
|
||||||
kind: Create(Box::new(env.clone())),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
(event_consumer)(
|
||||||
Err(err) => {
|
account_hash,
|
||||||
debug!("could not parse message {:?}", err);
|
BackendEvent::Refresh(RefreshEvent {
|
||||||
|
account_hash,
|
||||||
|
mailbox_hash,
|
||||||
|
kind: Create(Box::new(env.clone())),
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,21 +475,15 @@ impl MailBackend for NotmuchDb {
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
match message.into_envelope(self.index.clone(), self.tag_index.clone()) {
|
let env = message.into_envelope(&self.index, &self.tag_index);
|
||||||
Ok(env) => {
|
mailbox_index_lck
|
||||||
mailbox_index_lck
|
.entry(env.hash())
|
||||||
.entry(env.hash())
|
.or_default()
|
||||||
.or_default()
|
.push(self.mailbox_hash);
|
||||||
.push(self.mailbox_hash);
|
if !env.is_seen() {
|
||||||
if !env.is_seen() {
|
unseen_count += 1;
|
||||||
unseen_count += 1;
|
|
||||||
}
|
|
||||||
ret.push(env);
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
debug!("could not parse message {:?}", err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ret.push(env);
|
||||||
} else {
|
} else {
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -65,6 +65,16 @@ impl<'m> Message<'m> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn header(&self, header: &CStr) -> Option<&[u8]> {
|
||||||
|
let header_val =
|
||||||
|
unsafe { call!(self.lib, notmuch_message_get_header)(self.message, header.as_ptr()) };
|
||||||
|
if header_val.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(unsafe { CStr::from_ptr(header_val).to_bytes() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn msg_id(&self) -> &[u8] {
|
pub fn msg_id(&self) -> &[u8] {
|
||||||
let c_str = self.msg_id_cstr();
|
let c_str = self.msg_id_cstr();
|
||||||
c_str.to_bytes()
|
c_str.to_bytes()
|
||||||
|
@ -81,19 +91,11 @@ impl<'m> Message<'m> {
|
||||||
|
|
||||||
pub fn into_envelope(
|
pub fn into_envelope(
|
||||||
self,
|
self,
|
||||||
index: Arc<RwLock<HashMap<EnvelopeHash, CString>>>,
|
index: &RwLock<HashMap<EnvelopeHash, CString>>,
|
||||||
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
tag_index: &RwLock<BTreeMap<u64, String>>,
|
||||||
) -> Result<Envelope> {
|
) -> Envelope {
|
||||||
let mut contents = Vec::new();
|
|
||||||
let path = self.get_filename().to_os_string();
|
|
||||||
let mut f = std::fs::File::open(&path)?;
|
|
||||||
f.read_to_end(&mut contents)?;
|
|
||||||
let env_hash = self.env_hash();
|
let env_hash = self.env_hash();
|
||||||
let mut env = Envelope::from_bytes(&contents, None).chain_err_summary(|| {
|
let mut env = Envelope::new(env_hash);
|
||||||
index.write().unwrap().remove(&env_hash);
|
|
||||||
format!("could not parse path {:?}", path)
|
|
||||||
})?;
|
|
||||||
env.set_hash(env_hash);
|
|
||||||
index
|
index
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -109,8 +111,63 @@ impl<'m> Message<'m> {
|
||||||
}
|
}
|
||||||
env.labels_mut().push(num);
|
env.labels_mut().push(num);
|
||||||
}
|
}
|
||||||
env.set_flags(flags);
|
unsafe {
|
||||||
Ok(env)
|
use crate::email::parser::address::rfc2822address_list;
|
||||||
|
env.set_message_id(self.msg_id())
|
||||||
|
.set_date(
|
||||||
|
self.header(CStr::from_bytes_with_nul_unchecked(b"Date\0"))
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.set_from(
|
||||||
|
rfc2822address_list(
|
||||||
|
self.header(CStr::from_bytes_with_nul_unchecked(b"From\0"))
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.map(|(_, v)| v)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.set_to(
|
||||||
|
rfc2822address_list(
|
||||||
|
self.header(CStr::from_bytes_with_nul_unchecked(b"To\0"))
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.map(|(_, v)| v)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.set_cc(
|
||||||
|
rfc2822address_list(
|
||||||
|
self.header(CStr::from_bytes_with_nul_unchecked(b"Cc\0"))
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.map(|(_, v)| v)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.set_bcc(
|
||||||
|
rfc2822address_list(
|
||||||
|
self.header(CStr::from_bytes_with_nul_unchecked(b"Bcc\0"))
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.map(|(_, v)| v)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_vec(),
|
||||||
|
)
|
||||||
|
.set_subject(
|
||||||
|
self.header(CStr::from_bytes_with_nul_unchecked(b"Subject\0"))
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_vec(),
|
||||||
|
)
|
||||||
|
.set_references(
|
||||||
|
self.header(CStr::from_bytes_with_nul_unchecked(b"References\0"))
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.set_in_reply_to(
|
||||||
|
self.header(CStr::from_bytes_with_nul_unchecked(b"In-Reply-To\0"))
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.set_datetime(self.date())
|
||||||
|
.set_flags(flags);
|
||||||
|
}
|
||||||
|
env
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replies_iter(&self) -> Option<MessageIterator> {
|
pub fn replies_iter(&self) -> Option<MessageIterator> {
|
||||||
|
|
Loading…
Reference in New Issue