mirror of
https://git.meli.delivery/meli/meli
synced 2024-11-19 03:25:38 +00:00
melib/imap: detect tag (\* flag) support
This commit is contained in:
parent
fdb42cfc0c
commit
dab9b39f4d
@ -41,7 +41,7 @@ use crate::conf::AccountSettings;
|
||||
use crate::email::*;
|
||||
use crate::error::{MeliError, Result};
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::{hash_map::DefaultHasher, BTreeMap};
|
||||
use std::hash::Hasher;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
@ -128,6 +128,8 @@ pub struct ImapType {
|
||||
connection: Arc<Mutex<ImapConnection>>,
|
||||
server_conf: ImapServerConf,
|
||||
uid_store: Arc<UIDStore>,
|
||||
can_create_flags: Arc<Mutex<bool>>,
|
||||
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
|
||||
|
||||
folders: Arc<RwLock<FnvHashMap<FolderHash, ImapFolder>>>,
|
||||
}
|
||||
@ -151,6 +153,7 @@ impl MailBackend for ImapType {
|
||||
let handle = {
|
||||
let tx = w.tx();
|
||||
let uid_store = self.uid_store.clone();
|
||||
let can_create_flags = self.can_create_flags.clone();
|
||||
let folder_path = folder.path().to_string();
|
||||
let folder_hash = folder.hash();
|
||||
let (permissions, folder_exists) = {
|
||||
@ -176,6 +179,7 @@ impl MailBackend for ImapType {
|
||||
let examine_response = protocol_parser::select_response(&response);
|
||||
exit_on_error!(&tx, examine_response);
|
||||
let examine_response = examine_response.unwrap();
|
||||
*can_create_flags.lock().unwrap() = examine_response.can_create_flags;
|
||||
debug!(
|
||||
"folder: {} examine_response: {:?}",
|
||||
folder_path, examine_response
|
||||
@ -445,6 +449,14 @@ impl MailBackend for ImapType {
|
||||
fn as_any(&self) -> &dyn::std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {
|
||||
if *self.can_create_flags.lock().unwrap() {
|
||||
Some(self.tag_index.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ImapType {
|
||||
@ -481,6 +493,8 @@ impl ImapType {
|
||||
server_conf,
|
||||
is_subscribed: Arc::new(IsSubscribedFn(is_subscribed)),
|
||||
|
||||
can_create_flags: Arc::new(Mutex::new(false)),
|
||||
tag_index: Arc::new(RwLock::new(Default::default())),
|
||||
folders: Arc::new(RwLock::new(Default::default())),
|
||||
connection: Arc::new(Mutex::new(connection)),
|
||||
uid_store: Arc::new(UIDStore {
|
||||
|
@ -302,6 +302,8 @@ pub struct SelectResponse {
|
||||
pub uidvalidity: usize,
|
||||
pub uidnext: usize,
|
||||
pub permanentflags: Flag,
|
||||
/// if SELECT returns \* we can set arbritary flags permanently.
|
||||
pub can_create_flags: bool,
|
||||
pub read_only: bool,
|
||||
}
|
||||
|
||||
@ -332,27 +334,23 @@ pub fn select_response(input: &str) -> Result<SelectResponse> {
|
||||
let mut ret = SelectResponse::default();
|
||||
for l in input.split("\r\n") {
|
||||
if l.starts_with("* ") && l.ends_with(" EXISTS") {
|
||||
ret.exists = usize::from_str(&l["* ".len()..l.len() - " EXISTS".len()]).unwrap();
|
||||
ret.exists = usize::from_str(&l["* ".len()..l.len() - " EXISTS".len()])?;
|
||||
} else if l.starts_with("* ") && l.ends_with(" RECENT") {
|
||||
ret.recent = usize::from_str(&l["* ".len()..l.len() - " RECENT".len()]).unwrap();
|
||||
ret.recent = usize::from_str(&l["* ".len()..l.len() - " RECENT".len()])?;
|
||||
} else if l.starts_with("* FLAGS (") {
|
||||
ret.flags = flags(&l["* FLAGS (".len()..l.len() - ")".len()])
|
||||
.to_full_result()
|
||||
.unwrap();
|
||||
ret.flags = flags(&l["* FLAGS (".len()..l.len() - ")".len()]).to_full_result()?;
|
||||
} else if l.starts_with("* OK [UNSEEN ") {
|
||||
ret.unseen =
|
||||
usize::from_str(&l["* OK [UNSEEN ".len()..l.find(']').unwrap()]).unwrap();
|
||||
ret.unseen = usize::from_str(&l["* OK [UNSEEN ".len()..l.find(']').unwrap()])?;
|
||||
} else if l.starts_with("* OK [UIDVALIDITY ") {
|
||||
ret.uidvalidity =
|
||||
usize::from_str(&l["* OK [UIDVALIDITY ".len()..l.find(']').unwrap()]).unwrap();
|
||||
usize::from_str(&l["* OK [UIDVALIDITY ".len()..l.find(']').unwrap()])?;
|
||||
} else if l.starts_with("* OK [UIDNEXT ") {
|
||||
ret.uidnext =
|
||||
usize::from_str(&l["* OK [UIDNEXT ".len()..l.find(']').unwrap()]).unwrap();
|
||||
ret.uidnext = usize::from_str(&l["* OK [UIDNEXT ".len()..l.find(']').unwrap()])?;
|
||||
} else if l.starts_with("* OK [PERMANENTFLAGS (") {
|
||||
ret.permanentflags =
|
||||
flags(&l["* OK [PERMANENTFLAGS (".len()..l.find(')').unwrap()])
|
||||
.to_full_result()
|
||||
.unwrap();
|
||||
.to_full_result()?;
|
||||
ret.can_create_flags = l.contains("\\*");
|
||||
} else if l.contains("OK [READ-WRITE]") {
|
||||
ret.read_only = false;
|
||||
} else if l.contains("OK [READ-ONLY]") {
|
||||
|
@ -144,6 +144,13 @@ impl From<native_tls::Error> for MeliError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::num::ParseIntError> for MeliError {
|
||||
#[inline]
|
||||
fn from(kind: std::num::ParseIntError) -> MeliError {
|
||||
MeliError::new(format!("{}", kind))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for MeliError {
|
||||
#[inline]
|
||||
fn from(kind: &str) -> MeliError {
|
||||
|
Loading…
Reference in New Issue
Block a user