sync: select mailbox when modifying flags

This commit is contained in:
FliegendeWurst 2021-04-08 22:42:56 +02:00 committed by Arne Keller
parent 480987bf6c
commit 39a63ad966
2 changed files with 17 additions and 4 deletions

View File

@ -1,6 +1,6 @@
#![feature(internal_output_capture)] #![feature(internal_output_capture)]
use std::{cell::RefCell, cmp, collections::{HashMap, HashSet}, env, fmt::Display, io, sync::{Arc, Mutex}}; use std::{cell::RefCell, cmp, collections::{HashMap, HashSet}, env, fmt::Display, io, sync::Arc};
use cursive::{Cursive, CursiveExt, Vec2}; use cursive::{Cursive, CursiveExt, Vec2};
use cursive::align::HAlign; use cursive::align::HAlign;
@ -15,12 +15,13 @@ use imap::types::Flag;
use itertools::Itertools; use itertools::Itertools;
use log::error; use log::error;
use mailparse::{MailHeaderMap, ParsedMail}; use mailparse::{MailHeaderMap, ParsedMail};
use parking_lot::RwLock; use parking_lot::{Mutex, RwLock};
use petgraph::{EdgeDirection, graph::{DiGraph, NodeIndex}, visit::{Dfs, IntoNodeReferences}}; use petgraph::{EdgeDirection, graph::{DiGraph, NodeIndex}, visit::{Dfs, IntoNodeReferences}};
use rusqlite::params;
fn main() -> Result<()> { fn main() -> Result<()> {
load_config(); load_config();
let sink = Arc::new(Mutex::new(Vec::new())); let sink = Arc::new(std::sync::Mutex::new(Vec::new()));
std::io::set_output_capture(Some(sink.clone())); std::io::set_output_capture(Some(sink.clone()));
let result = std::panic::catch_unwind(|| { let result = std::panic::catch_unwind(|| {
let args = env::args().collect_vec(); let args = env::args().collect_vec();
@ -42,6 +43,8 @@ fn main() -> Result<()> {
} }
fn show_listing(mailbox: &str) -> Result<()> { fn show_listing(mailbox: &str) -> Result<()> {
let db = Box::leak(Box::new(get_db()?));
let update_flags = Arc::new(Mutex::new(db.prepare("UPDATE mail SET flags = ? WHERE uid = ?")?));
let maildir = Box::leak(Box::new(get_maildir(mailbox)?)); let maildir = Box::leak(Box::new(get_maildir(mailbox)?));
let maildir = &*maildir; let maildir = &*maildir;
@ -224,6 +227,8 @@ fn show_listing(mailbox: &str) -> Result<()> {
}); });
let mut tree = tree.with_name("tree").scrollable(); let mut tree = tree.with_name("tree").scrollable();
tree.set_scroll_strategy(ScrollStrategy::StickToBottom); tree.set_scroll_strategy(ScrollStrategy::StickToBottom);
let update_flags2 = Arc::clone(&update_flags);
let update_flags3 = Arc::clone(&update_flags);
let tree = OnEventView::new(tree) let tree = OnEventView::new(tree)
.on_event('r', move |siv| { .on_event('r', move |siv| {
siv.call_on_name("tree", |tree: &mut MailTreeView| { siv.call_on_name("tree", |tree: &mut MailTreeView| {
@ -231,7 +236,9 @@ fn show_listing(mailbox: &str) -> Result<()> {
let mail = tree.borrow_item_mut(r).unwrap(); let mail = tree.borrow_item_mut(r).unwrap();
mail.add_flag(Flag::Seen); mail.add_flag(Flag::Seen);
mail.remove_flag2('U'); mail.remove_flag2('U');
// TODO error handling
let _ = mail.save_flags(&maildir); let _ = mail.save_flags(&maildir);
let _ = update_flags2.lock().execute(params![mail.get_flags(), mail.id.to_i64()]);
} }
}); });
}) })
@ -241,7 +248,9 @@ fn show_listing(mailbox: &str) -> Result<()> {
let mail = tree.borrow_item_mut(r).unwrap(); let mail = tree.borrow_item_mut(r).unwrap();
mail.remove_flag(Flag::Seen); mail.remove_flag(Flag::Seen);
mail.add_flag2('U'); mail.add_flag2('U');
// TODO error handling
let _ = mail.save_flags(&maildir); let _ = mail.save_flags(&maildir);
let _ = update_flags3.lock().execute(params![mail.get_flags(), mail.id.to_i64()]);
} }
}); });
}); });

View File

@ -73,7 +73,7 @@ fn sync(
for &name in &names { for &name in &names {
let mailbox = name.name(); let mailbox = name.name();
let remote_mails = remote.get_mut(mailbox).unwrap(); let remote_mails = remote.get_mut(mailbox).unwrap();
let resp = imap_session.examine(mailbox)?; let resp = imap_session.select(mailbox)?;
let uid_validity = resp.uid_validity.unwrap(); let uid_validity = resp.uid_validity.unwrap();
let mut to_fetch = Vec::new(); let mut to_fetch = Vec::new();
@ -90,9 +90,11 @@ fn sync(
let local_u = flags.contains('U'); let local_u = flags.contains('U');
let remote_s = remote_flags.contains(&Flag::Seen); let remote_s = remote_flags.contains(&Flag::Seen);
if local_s && !remote_s { if local_s && !remote_s {
println!("setting Seen flag on {}/{}", mailbox, uid);
imap_session.uid_store(uid.to_string(), "+FLAGS.SILENT (\\Seen)")?; imap_session.uid_store(uid.to_string(), "+FLAGS.SILENT (\\Seen)")?;
remote_flags.push(Flag::Seen); remote_flags.push(Flag::Seen);
} else if local_u && remote_s { } else if local_u && remote_s {
println!("removing Seen flag on {}/{}", mailbox, uid);
imap_session.uid_store(uid.to_string(), "-FLAGS.SILENT (\\Seen)")?; imap_session.uid_store(uid.to_string(), "-FLAGS.SILENT (\\Seen)")?;
remote_flags.remove(remote_flags.iter().position(|x| x == &Flag::Seen).unwrap()); remote_flags.remove(remote_flags.iter().position(|x| x == &Flag::Seen).unwrap());
} }
@ -117,6 +119,8 @@ fn sync(
} }
} }
if !to_fetch.is_empty() { if !to_fetch.is_empty() {
let resp = imap_session.examine(mailbox)?;
let uid_validity = resp.uid_validity.unwrap();
let maildir = &maildirs[mailbox]; let maildir = &maildirs[mailbox];
let fetch_range = to_fetch.into_iter().map(|x| x.to_string()).join(","); let fetch_range = to_fetch.into_iter().map(|x| x.to_string()).join(",");