Browse Source

melib/imap: detect tag (\* flag) support

tags/alpha-0.4.1
Manos Pitsidianakis 2 months ago
parent
commit
dab9b39f4d
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS. GPG Key ID: 73627C2F690DF710
3 changed files with 32 additions and 13 deletions
  1. +15
    -1
      melib/src/backends/imap.rs
  2. +10
    -12
      melib/src/backends/imap/protocol_parser.rs
  3. +7
    -0
      melib/src/error.rs

+ 15
- 1
melib/src/backends/imap.rs View File

@@ -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 {


+ 10
- 12
melib/src/backends/imap/protocol_parser.rs View File

@@ -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]") {


+ 7
- 0
melib/src/error.rs View File

@@ -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…
Cancel
Save