mirror of
https://github.com/soywod/himalaya.git
synced 2024-11-22 11:00:19 +00:00
improve notmuch backend logs and error msg
This commit is contained in:
parent
328da34f8d
commit
f631f63799
2 changed files with 154 additions and 56 deletions
|
@ -141,10 +141,10 @@ impl<'a> Backend<'a> for MaildirBackend<'a> {
|
|||
let page_begin = page * page_size;
|
||||
debug!("page begin: {:?}", page_begin);
|
||||
if page_begin > envelopes.len() {
|
||||
return Err(anyhow!(format!(
|
||||
return Err(anyhow!(
|
||||
"cannot get maildir envelopes at page {:?} (out of bounds)",
|
||||
page_begin + 1,
|
||||
)));
|
||||
));
|
||||
}
|
||||
let page_end = envelopes.len().min(page_begin + page_size);
|
||||
debug!("page end: {:?}", page_end);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::{convert::TryInto, fs};
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use log::{debug, info, trace};
|
||||
|
||||
use crate::{
|
||||
backends::{Backend, IdMapper, NotmuchEnvelopes, NotmuchMbox, NotmuchMboxes},
|
||||
|
@ -9,6 +10,8 @@ use crate::{
|
|||
msg::{Envelopes, Msg},
|
||||
};
|
||||
|
||||
/// Represents the Notmuch backend.
|
||||
#[derive(Debug)]
|
||||
pub struct NotmuchBackend<'a> {
|
||||
account_config: &'a AccountConfig,
|
||||
notmuch_config: &'a NotmuchBackendConfig,
|
||||
|
@ -20,24 +23,31 @@ impl<'a> NotmuchBackend<'a> {
|
|||
account_config: &'a AccountConfig,
|
||||
notmuch_config: &'a NotmuchBackendConfig,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
info!(">> create new notmuch backend");
|
||||
|
||||
let backend = Self {
|
||||
account_config,
|
||||
notmuch_config,
|
||||
db: notmuch::Database::open(
|
||||
notmuch_config.notmuch_database_dir.clone(),
|
||||
notmuch::DatabaseMode::ReadWrite,
|
||||
)
|
||||
.context(format!(
|
||||
"cannot open notmuch database at {:?}",
|
||||
notmuch_config.notmuch_database_dir
|
||||
))?,
|
||||
})
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"cannot open notmuch database at {:?}",
|
||||
notmuch_config.notmuch_database_dir
|
||||
)
|
||||
})?,
|
||||
};
|
||||
trace!("backend: {:?}", backend);
|
||||
|
||||
info!("<< create new notmuch backend");
|
||||
Ok(backend)
|
||||
}
|
||||
|
||||
fn _search_envelopes(
|
||||
&mut self,
|
||||
query: &str,
|
||||
virt_mbox: &str,
|
||||
page_size: usize,
|
||||
page: usize,
|
||||
) -> Result<Box<dyn Envelopes>> {
|
||||
|
@ -45,28 +55,26 @@ impl<'a> NotmuchBackend<'a> {
|
|||
let query_builder = self
|
||||
.db
|
||||
.create_query(query)
|
||||
.context(format!("cannot create notmuch query from {:?}", query))?;
|
||||
.with_context(|| format!("cannot create notmuch query from {:?}", query))?;
|
||||
let mut envelopes: NotmuchEnvelopes = query_builder
|
||||
.search_messages()
|
||||
.context(format!(
|
||||
"cannot find notmuch envelopes from query {:?}",
|
||||
query
|
||||
))?
|
||||
.with_context(|| format!("cannot find notmuch envelopes from query {:?}", query))?
|
||||
.try_into()
|
||||
.context(format!(
|
||||
"cannot parse notmuch envelopes from query {:?}",
|
||||
query
|
||||
))?;
|
||||
.with_context(|| format!("cannot parse notmuch envelopes from query {:?}", query))?;
|
||||
debug!("envelopes len: {:?}", envelopes.len());
|
||||
trace!("envelopes: {:?}", envelopes);
|
||||
|
||||
// Calculates pagination boundaries.
|
||||
let page_begin = page * page_size;
|
||||
debug!("page begin: {:?}", page_begin);
|
||||
if page_begin > envelopes.len() {
|
||||
return Err(anyhow!(format!(
|
||||
"cannot find notmuch envelopes at page {:?} (out of bounds)",
|
||||
"cannot get notmuch envelopes at page {:?} (out of bounds)",
|
||||
page_begin + 1,
|
||||
)));
|
||||
}
|
||||
let page_end = envelopes.len().min(page_begin + page_size);
|
||||
debug!("page end: {:?}", page_end);
|
||||
|
||||
// Sorts envelopes by most recent date.
|
||||
envelopes.sort_by(|a, b| b.date.partial_cmp(&a.date).unwrap());
|
||||
|
@ -74,7 +82,10 @@ impl<'a> NotmuchBackend<'a> {
|
|||
// Applies pagination boundaries.
|
||||
envelopes.0 = envelopes[page_begin..page_end].to_owned();
|
||||
|
||||
// Appends id <=> hash entries to the id mapper cache file.
|
||||
// Appends envelopes hash to the id mapper cache file and
|
||||
// calculates the new short hash length. The short hash length
|
||||
// represents the minimum hash length possible to avoid
|
||||
// conflicts.
|
||||
let short_hash_len = {
|
||||
let mut mapper = IdMapper::new(&self.notmuch_config.notmuch_database_dir)?;
|
||||
let entries = envelopes
|
||||
|
@ -83,6 +94,7 @@ impl<'a> NotmuchBackend<'a> {
|
|||
.collect();
|
||||
mapper.append(entries)?
|
||||
};
|
||||
debug!("short hash length: {:?}", short_hash_len);
|
||||
|
||||
// Shorten envelopes hash.
|
||||
envelopes
|
||||
|
@ -95,22 +107,35 @@ impl<'a> NotmuchBackend<'a> {
|
|||
|
||||
impl<'a> Backend<'a> for NotmuchBackend<'a> {
|
||||
fn add_mbox(&mut self, _mbox: &str) -> Result<()> {
|
||||
unimplemented!();
|
||||
info!(">> add notmuch mailbox");
|
||||
info!("<< add notmuch mailbox");
|
||||
Err(anyhow!(
|
||||
"cannot add notmuch mailbox: feature not implemented"
|
||||
))
|
||||
}
|
||||
|
||||
fn get_mboxes(&mut self) -> Result<Box<dyn Mboxes>> {
|
||||
let mut mboxes: Vec<_> = self
|
||||
info!(">> get notmuch virtual mailboxes");
|
||||
|
||||
let mut virt_mboxes: Vec<_> = self
|
||||
.account_config
|
||||
.mailboxes
|
||||
.iter()
|
||||
.map(|(k, v)| NotmuchMbox::new(k, v))
|
||||
.collect();
|
||||
mboxes.sort_by(|a, b| b.name.partial_cmp(&a.name).unwrap());
|
||||
Ok(Box::new(NotmuchMboxes(mboxes)))
|
||||
trace!("virtual mailboxes: {:?}", virt_mboxes);
|
||||
virt_mboxes.sort_by(|a, b| b.name.partial_cmp(&a.name).unwrap());
|
||||
|
||||
info!("<< get notmuch virtual mailboxes");
|
||||
Ok(Box::new(NotmuchMboxes(virt_mboxes)))
|
||||
}
|
||||
|
||||
fn del_mbox(&mut self, _mbox: &str) -> Result<()> {
|
||||
unimplemented!();
|
||||
info!(">> delete notmuch mailbox");
|
||||
info!("<< delete notmuch mailbox");
|
||||
Err(anyhow!(
|
||||
"cannot delete notmuch mailbox: feature not implemented"
|
||||
))
|
||||
}
|
||||
|
||||
fn get_envelopes(
|
||||
|
@ -119,13 +144,22 @@ impl<'a> Backend<'a> for NotmuchBackend<'a> {
|
|||
page_size: usize,
|
||||
page: usize,
|
||||
) -> Result<Box<dyn Envelopes>> {
|
||||
info!(">> get notmuch envelopes");
|
||||
debug!("virtual mailbox: {:?}", virt_mbox);
|
||||
debug!("page size: {:?}", page_size);
|
||||
debug!("page: {:?}", page);
|
||||
|
||||
let query = self
|
||||
.account_config
|
||||
.mailboxes
|
||||
.get(virt_mbox)
|
||||
.map(|s| s.as_str())
|
||||
.unwrap_or("all");
|
||||
self._search_envelopes(query, virt_mbox, page_size, page)
|
||||
debug!("query: {:?}", query);
|
||||
let envelopes = self._search_envelopes(query, page_size, page)?;
|
||||
|
||||
info!("<< get notmuch envelopes");
|
||||
Ok(envelopes)
|
||||
}
|
||||
|
||||
fn search_envelopes(
|
||||
|
@ -136,69 +170,133 @@ impl<'a> Backend<'a> for NotmuchBackend<'a> {
|
|||
page_size: usize,
|
||||
page: usize,
|
||||
) -> Result<Box<dyn Envelopes>> {
|
||||
self._search_envelopes(query, virt_mbox, page_size, page)
|
||||
info!(">> search notmuch envelopes");
|
||||
debug!("virtual mailbox: {:?}", virt_mbox);
|
||||
debug!("query: {:?}", query);
|
||||
debug!("page size: {:?}", page_size);
|
||||
debug!("page: {:?}", page);
|
||||
|
||||
let query = if query.is_empty() {
|
||||
self.account_config
|
||||
.mailboxes
|
||||
.get(virt_mbox)
|
||||
.map(|s| s.as_str())
|
||||
.unwrap_or("all")
|
||||
} else {
|
||||
query
|
||||
};
|
||||
debug!("final query: {:?}", query);
|
||||
let envelopes = self._search_envelopes(query, page_size, page)?;
|
||||
|
||||
info!("<< search notmuch envelopes");
|
||||
Ok(envelopes)
|
||||
}
|
||||
|
||||
fn add_msg(&mut self, _mbox: &str, _msg: &[u8], _flags: &str) -> Result<Box<dyn ToString>> {
|
||||
unimplemented!();
|
||||
fn add_msg(
|
||||
&mut self,
|
||||
_virt_mbox: &str,
|
||||
_msg: &[u8],
|
||||
_flags: &str,
|
||||
) -> Result<Box<dyn ToString>> {
|
||||
info!(">> add notmuch envelopes");
|
||||
info!("<< add notmuch envelopes");
|
||||
Err(anyhow!(
|
||||
"cannot add notmuch envelopes: feature not implemented"
|
||||
))
|
||||
}
|
||||
|
||||
fn get_msg(&mut self, _mbox: &str, short_hash: &str) -> Result<Msg> {
|
||||
let id = IdMapper::new(&self.notmuch_config.notmuch_database_dir)?
|
||||
fn get_msg(&mut self, _virt_mbox: &str, short_hash: &str) -> Result<Msg> {
|
||||
info!(">> add notmuch envelopes");
|
||||
debug!("short hash: {:?}", short_hash);
|
||||
|
||||
let dir = &self.notmuch_config.notmuch_database_dir;
|
||||
let id = IdMapper::new(dir)
|
||||
.with_context(|| format!("cannot create id mapper instance for {:?}", dir))?
|
||||
.find(short_hash)
|
||||
.context(format!(
|
||||
"cannot get notmuch message from short hash {:?}",
|
||||
short_hash
|
||||
))?;
|
||||
let msg_filepath = self
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"cannot find notmuch message from short hash {:?}",
|
||||
short_hash
|
||||
)
|
||||
})?;
|
||||
debug!("id: {:?}", id);
|
||||
let msg_file_path = self
|
||||
.db
|
||||
.find_message(&id)
|
||||
.context(format!("cannot find notmuch message {:?}", id))?
|
||||
.with_context(|| format!("cannot find notmuch message {:?}", id))?
|
||||
.ok_or_else(|| anyhow!("cannot find notmuch message {:?}", id))?
|
||||
.filename()
|
||||
.to_owned();
|
||||
let raw_msg = fs::read(&msg_filepath)
|
||||
.context(format!("cannot read message from file {:?}", msg_filepath))?;
|
||||
let msg = Msg::from_parsed_mail(mailparse::parse_mail(&raw_msg)?, &self.account_config)?;
|
||||
debug!("message file path: {:?}", msg_file_path);
|
||||
let raw_msg = fs::read(&msg_file_path).with_context(|| {
|
||||
format!("cannot read notmuch message from file {:?}", msg_file_path)
|
||||
})?;
|
||||
let msg = mailparse::parse_mail(&raw_msg)
|
||||
.with_context(|| format!("cannot parse raw notmuch message {:?}", id))?;
|
||||
let msg = Msg::from_parsed_mail(msg, &self.account_config)
|
||||
.with_context(|| format!("cannot parse notmuch message {:?}", id))?;
|
||||
trace!("message: {:?}", msg);
|
||||
|
||||
info!("<< get notmuch message");
|
||||
Ok(msg)
|
||||
}
|
||||
|
||||
fn copy_msg(&mut self, _mbox_src: &str, _mbox_dst: &str, _id: &str) -> Result<()> {
|
||||
unimplemented!();
|
||||
info!(">> copy notmuch message");
|
||||
info!("<< copy notmuch message");
|
||||
Err(anyhow!(
|
||||
"cannot copy notmuch message: feature not implemented"
|
||||
))
|
||||
}
|
||||
|
||||
fn move_msg(&mut self, _mbox_src: &str, _mbox_dst: &str, _id: &str) -> Result<()> {
|
||||
unimplemented!();
|
||||
fn move_msg(&mut self, _src: &str, _dst: &str, _id: &str) -> Result<()> {
|
||||
info!(">> move notmuch message");
|
||||
info!("<< move notmuch message");
|
||||
Err(anyhow!(
|
||||
"cannot move notmuch message: feature not implemented"
|
||||
))
|
||||
}
|
||||
|
||||
fn del_msg(&mut self, _mbox: &str, short_hash: &str) -> Result<()> {
|
||||
let id = IdMapper::new(&self.notmuch_config.notmuch_database_dir)?
|
||||
fn del_msg(&mut self, _virt_mbox: &str, short_hash: &str) -> Result<()> {
|
||||
info!(">> delete notmuch message");
|
||||
debug!("short hash: {:?}", short_hash);
|
||||
|
||||
let dir = &self.notmuch_config.notmuch_database_dir;
|
||||
let id = IdMapper::new(dir)
|
||||
.with_context(|| format!("cannot create id mapper instance for {:?}", dir))?
|
||||
.find(short_hash)
|
||||
.context(format!(
|
||||
"cannot get notmuch message from short hash {:?}",
|
||||
short_hash
|
||||
))?;
|
||||
let msg_filepath = self
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"cannot find notmuch message from short hash {:?}",
|
||||
short_hash
|
||||
)
|
||||
})?;
|
||||
debug!("id: {:?}", id);
|
||||
let msg_file_path = self
|
||||
.db
|
||||
.find_message(&id)
|
||||
.context(format!("cannot find notmuch message {:?}", id))?
|
||||
.with_context(|| format!("cannot find notmuch message {:?}", id))?
|
||||
.ok_or_else(|| anyhow!("cannot find notmuch message {:?}", id))?
|
||||
.filename()
|
||||
.to_owned();
|
||||
debug!("message file path: {:?}", msg_file_path);
|
||||
self.db
|
||||
.remove_message(msg_filepath)
|
||||
.context(format!("cannot delete notmuch message {:?}", id))
|
||||
.remove_message(msg_file_path)
|
||||
.with_context(|| format!("cannot delete notmuch message {:?}", id))?;
|
||||
|
||||
info!("<< delete notmuch message");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_flags(&mut self, _mbox: &str, _id: &str, _flags_str: &str) -> Result<()> {
|
||||
fn add_flags(&mut self, _virt_mbox: &str, _id: &str, _flags: &str) -> Result<()> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_flags(&mut self, _mbox: &str, _id: &str, _flags_str: &str) -> Result<()> {
|
||||
fn set_flags(&mut self, _virt_mbox: &str, _id: &str, _flags: &str) -> Result<()> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn del_flags(&mut self, _mbox: &str, _id: &str, _flags_str: &str) -> Result<()> {
|
||||
fn del_flags(&mut self, _virt_mbox: &str, _id: &str, _flags: &str) -> Result<()> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue