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