|
1 | 1 | extern crate xdg; |
2 | 2 | extern crate toml; |
3 | 3 | extern crate imap; |
| 4 | +extern crate rayon; |
4 | 5 | extern crate openssl; |
5 | 6 | extern crate systray; |
6 | 7 | extern crate mailparse; |
7 | 8 | extern crate notify_rust; |
8 | 9 |
|
9 | 10 | use openssl::ssl::{SslContext, SslMethod}; |
10 | 11 | use imap::client::Client; |
| 12 | +use rayon::prelude::*; |
11 | 13 |
|
12 | 14 | use std::collections::HashSet; |
13 | 15 | use std::process::Command; |
14 | 16 | use std::io::prelude::*; |
| 17 | +use std::time::Duration; |
15 | 18 | use std::sync::mpsc; |
16 | 19 | use std::fs::File; |
17 | 20 | use std::thread; |
@@ -122,23 +125,49 @@ fn main() { |
122 | 125 | // TODO: w.set_tooltip(&"Whatever".to_string()); |
123 | 126 | // TODO: app.wait_for_message(); |
124 | 127 |
|
125 | | - let accounts: Vec<_> = accounts.into_iter() |
| 128 | + let accounts: Vec<_> = accounts.par_iter() |
126 | 129 | .filter_map(|a| { |
127 | | - let name = a.name; |
128 | | - Client::secure_connect(a.server, SslContext::new(SslMethod::Sslv23).unwrap()) |
129 | | - .map(move |mut c| { |
130 | | - c.login(a.username, &a.password).unwrap(); |
131 | | - assert!(c.capability().unwrap().iter().any(|c| c == "IDLE")); |
132 | | - c.select("INBOX").unwrap(); |
133 | | - (String::from(name), c) |
134 | | - }) |
135 | | - .map_err(move |e| { |
136 | | - println!("Failed to connect account {}: {}", name, e); |
137 | | - }) |
138 | | - .ok() |
| 130 | + let mut wait = 1; |
| 131 | + for _ in 0..5 { |
| 132 | + let c = Client::secure_connect(a.server, |
| 133 | + SslContext::new(SslMethod::Sslv23).unwrap()) |
| 134 | + .and_then(|mut c| { |
| 135 | + try!(c.login(a.username, &a.password)); |
| 136 | + let cap = try!(c.capability()); |
| 137 | + if !cap.iter().any(|c| c == "IDLE") { |
| 138 | + return Err(imap::error::Error::BadResponse(cap)); |
| 139 | + } |
| 140 | + try!(c.select("INBOX")); |
| 141 | + Ok((String::from(a.name), c)) |
| 142 | + }); |
| 143 | + |
| 144 | + match c { |
| 145 | + Ok(c) => return Some(c), |
| 146 | + Err(imap::error::Error::Io(e)) => { |
| 147 | + println!("Failed to connect account {}: {}; retrying in {}s", |
| 148 | + a.name, |
| 149 | + e, |
| 150 | + wait); |
| 151 | + thread::sleep(Duration::from_secs(wait)); |
| 152 | + } |
| 153 | + Err(e) => { |
| 154 | + println!("{} host produced bad IMAP tunnel: {}", a.name, e); |
| 155 | + break; |
| 156 | + } |
| 157 | + } |
| 158 | + |
| 159 | + wait *= 2; |
| 160 | + } |
| 161 | + |
| 162 | + None |
139 | 163 | }) |
140 | 164 | .collect(); |
141 | 165 |
|
| 166 | + if accounts.is_empty() { |
| 167 | + println!("No accounts in config worked; exiting..."); |
| 168 | + return; |
| 169 | + } |
| 170 | + |
142 | 171 | // We have now connected |
143 | 172 | app.set_icon_from_file(&"/usr/share/icons/Faenza/stock/24/stock_connect.png".to_string()).ok(); |
144 | 173 |
|
|
0 commit comments