mirror of
https://github.com/FliegendeWurst/inboxid.git
synced 2024-11-22 00:45:01 +00:00
sync: handle empty Message-Id again
This commit is contained in:
parent
451fac9edc
commit
00e5ddf5c6
@ -63,10 +63,12 @@ fn sync(
|
||||
continue;
|
||||
}
|
||||
let header = m.header().unwrap();
|
||||
let message_id = parse_header(header).map(|x| x.0.get_value())
|
||||
.unwrap_or_else(|_| fallback_mid(mailbox, id));
|
||||
let mut message_id = parse_header(header).map(|x| x.0.get_value()).unwrap_or_default();
|
||||
if message_id.is_empty() {
|
||||
message_id = fallback_mid(mailbox, id);
|
||||
}
|
||||
let flags = flags.iter().map(|x| remove_cow(x)).collect_vec();
|
||||
mails.insert(message_id, (id.uid_validity, id.uid, id.to_u64(), flags));
|
||||
mails.insert(message_id, (id.uid_validity, id.uid, id, flags));
|
||||
}
|
||||
remote.insert(mailbox, mails);
|
||||
}
|
||||
@ -139,24 +141,19 @@ fn sync(
|
||||
let mut to_fetch = Vec::new();
|
||||
for (message_id, entry) in remote_mails.iter_mut() {
|
||||
let (uid1, uid2, full_uid, remote_flags) = entry;
|
||||
let local = have_mail.query_map(params![message_id], |row| Ok((
|
||||
row.get::<_, String>(0)?,
|
||||
load_i64(row.get::<_, i64>(1)?),
|
||||
row.get::<_, String>(2)?
|
||||
)))?.map(|x| x.unwrap()).collect_vec();
|
||||
let local = have_mail.query_map(params![message_id], map3rows::<String, MaildirID, String>)?.map(|x| x.unwrap()).collect_vec();
|
||||
macro_rules! update_flags {
|
||||
($full_uid:expr, $flags:expr) => {
|
||||
let uid = ($full_uid << 32) >> 32;
|
||||
($id:expr, $flags:expr) => {
|
||||
let local_s = $flags.contains('S');
|
||||
let local_u = $flags.contains(UNREAD);
|
||||
let remote_s = remote_flags.contains(&Flag::Seen);
|
||||
if local_s && !remote_s {
|
||||
println!("setting Seen flag on {}/{}", mailbox, uid);
|
||||
imap_session.uid_store(uid.to_string(), "+FLAGS.SILENT (\\Seen)")?;
|
||||
println!("setting Seen flag on {}/{}", mailbox, $id.uid);
|
||||
imap_session.uid_store($id.to_imap(), "+FLAGS.SILENT (\\Seen)")?;
|
||||
remote_flags.push(Flag::Seen);
|
||||
} else if local_u && remote_s {
|
||||
println!("removing Seen flag on {}/{}", mailbox, uid);
|
||||
imap_session.uid_store(uid.to_string(), "-FLAGS.SILENT (\\Seen)")?;
|
||||
println!("removing Seen flag on {}/{}", mailbox, $id.uid);
|
||||
imap_session.uid_store($id.to_imap(), "-FLAGS.SILENT (\\Seen)")?;
|
||||
remote_flags.remove(remote_flags.iter().position(|x| x == &Flag::Seen).unwrap());
|
||||
}
|
||||
}
|
||||
@ -167,9 +164,7 @@ fn sync(
|
||||
}
|
||||
if !local.is_empty() {
|
||||
let (inbox, full_uid, flags) = &local[0];
|
||||
let local_uid1 = (full_uid >> 32) as u32;
|
||||
let local_uid2 = ((full_uid << 32) >> 32) as u32;
|
||||
let local_id = gen_id(local_uid1, local_uid2);
|
||||
let local_id = full_uid.to_string();
|
||||
let new_uid = MaildirID::new(*uid1, *uid2);
|
||||
let new_id = new_uid.to_string();
|
||||
// hardlink mail
|
||||
@ -178,8 +173,9 @@ fn sync(
|
||||
println!("hardlinking: {}/{} -> {}/{}", inbox, local_id, mailbox, new_id);
|
||||
maildir_cp(maildir1, maildir2, &local_id, &new_id, flags, false)?;
|
||||
save_mail.execute(params![mailbox, new_uid.to_i64(), message_id, flags])?;
|
||||
update_flags!(new_uid.to_u64(), flags);
|
||||
update_flags!(new_uid, flags);
|
||||
} else if !is_trash { // do not fetch trashed mail
|
||||
println!("fetching {:?} {:?} as it is not in {:?}", uid2, message_id, local);
|
||||
to_fetch.push(uid2);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use mailparse::{MailHeaderMap, ParsedMail, SingleInfo, addrparse, dateparse};
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::RwLock;
|
||||
use petgraph::{Graph, graph::NodeIndex};
|
||||
use rusqlite::{Connection, ToSql, params, types::ToSqlOutput};
|
||||
use rusqlite::{Connection, ToSql, params, types::{FromSql, ToSqlOutput}};
|
||||
use rustls_connector::{RustlsConnector, rustls::{ClientSession, StreamOwned}};
|
||||
use serde::{Deserializer, Serializer};
|
||||
use serde::de::Visitor;
|
||||
@ -118,6 +118,13 @@ impl ToSql for MaildirID {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSql for MaildirID {
|
||||
fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
|
||||
let x = i64::column_result(value)?;
|
||||
Ok(MaildirID::from(x))
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for MaildirID {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}_{}", self.uid_validity, self.uid)
|
||||
|
Loading…
Reference in New Issue
Block a user