melib/imap: small cleanups
parent
f02dde46da
commit
e9a80b32ac
|
@ -466,6 +466,10 @@ impl MailBackend for ImapType {
|
||||||
let uid_store = self.uid_store.clone();
|
let uid_store = self.uid_store.clone();
|
||||||
let connection = self.connection.clone();
|
let connection = self.connection.clone();
|
||||||
Ok(Box::pin(async move {
|
Ok(Box::pin(async move {
|
||||||
|
let mut response = String::with_capacity(8 * 1024);
|
||||||
|
let mut conn = connection.lock().await;
|
||||||
|
conn.select_mailbox(mailbox_hash, &mut response, true)
|
||||||
|
.await?;
|
||||||
let path = {
|
let path = {
|
||||||
let mailboxes = uid_store.mailboxes.lock().await;
|
let mailboxes = uid_store.mailboxes.lock().await;
|
||||||
|
|
||||||
|
@ -481,8 +485,6 @@ impl MailBackend for ImapType {
|
||||||
|
|
||||||
mailbox.imap_path().to_string()
|
mailbox.imap_path().to_string()
|
||||||
};
|
};
|
||||||
let mut response = String::with_capacity(8 * 1024);
|
|
||||||
let mut conn = connection.lock().await;
|
|
||||||
let flags = flags.unwrap_or_else(Flag::empty);
|
let flags = flags.unwrap_or_else(Flag::empty);
|
||||||
let has_literal_plus: bool = uid_store
|
let has_literal_plus: bool = uid_store
|
||||||
.capabilities
|
.capabilities
|
||||||
|
@ -556,7 +558,7 @@ impl MailBackend for ImapType {
|
||||||
.ok_or_else(|| MeliError::new("Destination mailbox not found"))?;
|
.ok_or_else(|| MeliError::new("Destination mailbox not found"))?;
|
||||||
if !mailbox.permissions.lock().unwrap().create_messages {
|
if !mailbox.permissions.lock().unwrap().create_messages {
|
||||||
return Err(MeliError::new(format!(
|
return Err(MeliError::new(format!(
|
||||||
"You are not allowed to delete messages from mailbox {}",
|
"You are not allowed to create messages in mailbox {}",
|
||||||
mailbox.path()
|
mailbox.path()
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
@ -804,6 +806,7 @@ impl MailBackend for ImapType {
|
||||||
let mut response = String::with_capacity(8 * 1024);
|
let mut response = String::with_capacity(8 * 1024);
|
||||||
{
|
{
|
||||||
let mut conn_lck = connection.lock().await;
|
let mut conn_lck = connection.lock().await;
|
||||||
|
conn_lck.unselect().await?;
|
||||||
|
|
||||||
conn_lck
|
conn_lck
|
||||||
.send_command(format!("CREATE \"{}\"", path,).as_bytes())
|
.send_command(format!("CREATE \"{}\"", path,).as_bytes())
|
||||||
|
@ -835,11 +838,9 @@ impl MailBackend for ImapType {
|
||||||
let new_mailbox_fut = self.mailboxes();
|
let new_mailbox_fut = self.mailboxes();
|
||||||
Ok(Box::pin(async move {
|
Ok(Box::pin(async move {
|
||||||
let imap_path: String;
|
let imap_path: String;
|
||||||
let no_select: bool;
|
|
||||||
let is_subscribed: bool;
|
let is_subscribed: bool;
|
||||||
{
|
{
|
||||||
let mailboxes = uid_store.mailboxes.lock().await;
|
let mailboxes = uid_store.mailboxes.lock().await;
|
||||||
no_select = mailboxes[&mailbox_hash].no_select;
|
|
||||||
is_subscribed = mailboxes[&mailbox_hash].is_subscribed();
|
is_subscribed = mailboxes[&mailbox_hash].is_subscribed();
|
||||||
imap_path = mailboxes[&mailbox_hash].imap_path().to_string();
|
imap_path = mailboxes[&mailbox_hash].imap_path().to_string();
|
||||||
let permissions = mailboxes[&mailbox_hash].permissions();
|
let permissions = mailboxes[&mailbox_hash].permissions();
|
||||||
|
@ -850,15 +851,9 @@ impl MailBackend for ImapType {
|
||||||
let mut response = String::with_capacity(8 * 1024);
|
let mut response = String::with_capacity(8 * 1024);
|
||||||
{
|
{
|
||||||
let mut conn_lck = connection.lock().await;
|
let mut conn_lck = connection.lock().await;
|
||||||
let current_mailbox = conn_lck.stream.as_ref()?.current_mailbox;
|
/* make sure mailbox is not selected before it gets deleted, otherwise
|
||||||
if !no_select
|
* connection gets dropped by server */
|
||||||
&& (current_mailbox == MailboxSelection::Examine(mailbox_hash)
|
conn_lck.unselect().await?;
|
||||||
|| current_mailbox == MailboxSelection::Select(mailbox_hash))
|
|
||||||
{
|
|
||||||
/* make sure mailbox is not selected before it gets deleted, otherwise
|
|
||||||
* connection gets dropped by server */
|
|
||||||
conn_lck.unselect().await?;
|
|
||||||
}
|
|
||||||
if is_subscribed {
|
if is_subscribed {
|
||||||
conn_lck
|
conn_lck
|
||||||
.send_command(format!("UNSUBSCRIBE \"{}\"", &imap_path).as_bytes())
|
.send_command(format!("UNSUBSCRIBE \"{}\"", &imap_path).as_bytes())
|
||||||
|
|
|
@ -33,11 +33,10 @@ pub async fn poll_with_examine(kit: ImapWatchKit) -> Result<()> {
|
||||||
debug!("poll with examine");
|
debug!("poll with examine");
|
||||||
let ImapWatchKit {
|
let ImapWatchKit {
|
||||||
mut conn,
|
mut conn,
|
||||||
main_conn,
|
main_conn: _,
|
||||||
uid_store,
|
uid_store,
|
||||||
} = kit;
|
} = kit;
|
||||||
conn.connect().await?;
|
conn.connect().await?;
|
||||||
let mut response = String::with_capacity(8 * 1024);
|
|
||||||
loop {
|
loop {
|
||||||
let mailboxes: HashMap<MailboxHash, ImapMailbox> = {
|
let mailboxes: HashMap<MailboxHash, ImapMailbox> = {
|
||||||
let mailboxes_lck = timeout(Duration::from_secs(3), uid_store.mailboxes.lock()).await?;
|
let mailboxes_lck = timeout(Duration::from_secs(3), uid_store.mailboxes.lock()).await?;
|
||||||
|
@ -46,11 +45,6 @@ pub async fn poll_with_examine(kit: ImapWatchKit) -> Result<()> {
|
||||||
for (_, mailbox) in mailboxes {
|
for (_, mailbox) in mailboxes {
|
||||||
examine_updates(mailbox, &mut conn, &uid_store).await?;
|
examine_updates(mailbox, &mut conn, &uid_store).await?;
|
||||||
}
|
}
|
||||||
let mut main_conn = timeout(Duration::from_secs(3), main_conn.lock()).await?;
|
|
||||||
main_conn.send_command(b"NOOP").await?;
|
|
||||||
main_conn
|
|
||||||
.read_response(&mut response, RequiredResponses::empty())
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,52 +73,36 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
|
||||||
};
|
};
|
||||||
let mailbox_hash = mailbox.hash();
|
let mailbox_hash = mailbox.hash();
|
||||||
let mut response = String::with_capacity(8 * 1024);
|
let mut response = String::with_capacity(8 * 1024);
|
||||||
conn.send_command(format!("SELECT \"{}\"", mailbox.imap_path()).as_bytes())
|
let select_response = conn
|
||||||
.await?;
|
.select_mailbox(mailbox_hash, &mut response, true)
|
||||||
conn.read_response(&mut response, RequiredResponses::SELECT_REQUIRED)
|
.await?
|
||||||
.await?;
|
.unwrap();
|
||||||
debug!("select response {}", &response);
|
debug!("select response {}", &response);
|
||||||
{
|
{
|
||||||
let mut prev_exists = mailbox.exists.lock().unwrap();
|
let mut uidvalidities = uid_store.uidvalidity.lock().unwrap();
|
||||||
match protocol_parser::select_response(&response) {
|
|
||||||
Ok(ok) => {
|
|
||||||
{
|
|
||||||
let uidvalidities = uid_store.uidvalidity.lock().unwrap();
|
|
||||||
|
|
||||||
if let Some(v) = uidvalidities.get(&mailbox_hash) {
|
if let Some(v) = uidvalidities.get(&mailbox_hash) {
|
||||||
if *v != ok.uidvalidity {
|
if *v != select_response.uidvalidity {
|
||||||
conn.add_refresh_event(RefreshEvent {
|
let cache_handle = cache::CacheHandle::get(uid_store.clone())?;
|
||||||
account_hash: uid_store.account_hash,
|
cache_handle.clear(
|
||||||
mailbox_hash,
|
mailbox_hash,
|
||||||
kind: RefreshEventKind::Rescan,
|
select_response.uidvalidity,
|
||||||
});
|
select_response.highestmodseq.and_then(|i| i.ok()),
|
||||||
prev_exists.clear();
|
)?;
|
||||||
/*
|
conn.add_refresh_event(RefreshEvent {
|
||||||
uid_store.uid_index.lock().unwrap().clear();
|
account_hash: uid_store.account_hash,
|
||||||
uid_store.hash_index.lock().unwrap().clear();
|
mailbox_hash,
|
||||||
uid_store.byte_cache.lock().unwrap().clear();
|
kind: RefreshEventKind::Rescan,
|
||||||
*/
|
});
|
||||||
}
|
/*
|
||||||
} else {
|
uid_store.uid_index.lock().unwrap().clear();
|
||||||
conn.add_refresh_event(RefreshEvent {
|
uid_store.hash_index.lock().unwrap().clear();
|
||||||
account_hash: uid_store.account_hash,
|
uid_store.byte_cache.lock().unwrap().clear();
|
||||||
mailbox_hash,
|
*/
|
||||||
kind: RefreshEventKind::Rescan,
|
|
||||||
});
|
|
||||||
return Err(MeliError::new(format!(
|
|
||||||
"Unknown mailbox: {} {}",
|
|
||||||
mailbox.path(),
|
|
||||||
mailbox_hash
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug!(&ok);
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
} else {
|
||||||
debug!("{:?}", e);
|
uidvalidities.insert(mailbox_hash, select_response.uidvalidity);
|
||||||
return Err(e).chain_err_summary(|| "could not select mailbox");
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
conn.send_command(b"IDLE").await?;
|
conn.send_command(b"IDLE").await?;
|
||||||
let mut blockn = ImapBlockingConnection::from(conn);
|
let mut blockn = ImapBlockingConnection::from(conn);
|
||||||
|
@ -134,7 +112,7 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
|
||||||
const _26_MINS: std::time::Duration = std::time::Duration::from_secs(26 * 60);
|
const _26_MINS: std::time::Duration = std::time::Duration::from_secs(26 * 60);
|
||||||
/* duration interval to check other mailboxes for changes */
|
/* duration interval to check other mailboxes for changes */
|
||||||
const _5_MINS: std::time::Duration = std::time::Duration::from_secs(5 * 60);
|
const _5_MINS: std::time::Duration = std::time::Duration::from_secs(5 * 60);
|
||||||
while let Some(line) = blockn.as_stream().await {
|
while let Some(line) = timeout(Duration::from_secs(35 * 60), blockn.as_stream()).await? {
|
||||||
let now = std::time::Instant::now();
|
let now = std::time::Instant::now();
|
||||||
if now.duration_since(beat) >= _26_MINS {
|
if now.duration_since(beat) >= _26_MINS {
|
||||||
let mut main_conn_lck = timeout(Duration::from_secs(3), main_conn.lock()).await?;
|
let mut main_conn_lck = timeout(Duration::from_secs(3), main_conn.lock()).await?;
|
||||||
|
@ -158,13 +136,18 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
|
||||||
timeout(Duration::from_secs(3), uid_store.mailboxes.lock()).await?;
|
timeout(Duration::from_secs(3), uid_store.mailboxes.lock()).await?;
|
||||||
mailboxes_lck.clone()
|
mailboxes_lck.clone()
|
||||||
};
|
};
|
||||||
for (_, mailbox) in mailboxes {
|
for (h, mailbox) in mailboxes {
|
||||||
|
if mailbox_hash == h {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
examine_updates(mailbox, &mut conn, &uid_store).await?;
|
examine_updates(mailbox, &mut conn, &uid_store).await?;
|
||||||
}
|
}
|
||||||
watch = now;
|
watch = now;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let mut conn = timeout(Duration::from_secs(3), main_conn.lock()).await?;
|
let mut conn = timeout(Duration::from_secs(10), main_conn.lock()).await?;
|
||||||
|
conn.examine_mailbox(mailbox_hash, &mut response, false)
|
||||||
|
.await?;
|
||||||
conn.process_untagged(to_str!(&line)).await?;
|
conn.process_untagged(to_str!(&line)).await?;
|
||||||
}
|
}
|
||||||
*uid_store.is_online.lock().unwrap() = (Instant::now(), Ok(()));
|
*uid_store.is_online.lock().unwrap() = (Instant::now(), Ok(()));
|
||||||
|
@ -201,14 +184,14 @@ pub async fn examine_updates(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut response = String::with_capacity(8 * 1024);
|
let mut response = String::with_capacity(8 * 1024);
|
||||||
conn.examine_mailbox(mailbox_hash, &mut response, true)
|
let select_response = conn
|
||||||
.await?;
|
.examine_mailbox(mailbox_hash, &mut response, true)
|
||||||
|
.await?
|
||||||
|
.unwrap();
|
||||||
*uid_store.is_online.lock().unwrap() = (Instant::now(), Ok(()));
|
*uid_store.is_online.lock().unwrap() = (Instant::now(), Ok(()));
|
||||||
let select_response = protocol_parser::select_response(&response)
|
|
||||||
.chain_err_summary(|| "could not select mailbox")?;
|
|
||||||
debug!(&select_response);
|
debug!(&select_response);
|
||||||
{
|
{
|
||||||
let uidvalidities = uid_store.uidvalidity.lock().unwrap();
|
let mut uidvalidities = uid_store.uidvalidity.lock().unwrap();
|
||||||
|
|
||||||
if let Some(v) = uidvalidities.get(&mailbox_hash) {
|
if let Some(v) = uidvalidities.get(&mailbox_hash) {
|
||||||
if *v != select_response.uidvalidity {
|
if *v != select_response.uidvalidity {
|
||||||
|
@ -231,16 +214,7 @@ pub async fn examine_updates(
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
conn.add_refresh_event(RefreshEvent {
|
uidvalidities.insert(mailbox_hash, select_response.uidvalidity);
|
||||||
account_hash: uid_store.account_hash,
|
|
||||||
mailbox_hash,
|
|
||||||
kind: RefreshEventKind::Rescan,
|
|
||||||
});
|
|
||||||
return Err(MeliError::new(format!(
|
|
||||||
"Unknown mailbox: {} {}",
|
|
||||||
mailbox.path(),
|
|
||||||
mailbox_hash
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut cache_handle = cache::CacheHandle::get(uid_store.clone())?;
|
let mut cache_handle = cache::CacheHandle::get(uid_store.clone())?;
|
||||||
|
|
Loading…
Reference in New Issue