Use new structured rust-imap release

This commit is contained in:
Jon Gjengset 2018-05-06 15:34:32 -04:00
parent 58f8c07acf
commit 64bc03163e
No known key found for this signature in database
GPG Key ID: D64AC9D67176DC71
3 changed files with 44 additions and 45 deletions

17
Cargo.lock generated
View File

@ -131,7 +131,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "buzz"
version = "1.0.7"
dependencies = [
"imap 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"imap 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"mailparse 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"notify-rust 3.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -568,14 +568,24 @@ dependencies = [
[[package]]
name = "imap"
version = "0.6.0"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"imap-proto 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "imap-proto"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
version = "0.3.4"
@ -1349,7 +1359,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum gobject-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70409d6405db8b1591602fcd0cbe8af52cd9976dd39194442b4c149ba343f86d"
"checksum gtk 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "414f3522f550a0b4f65e089f00ffcd3987dab8b0be284cb979aa7f6a03d60516"
"checksum gtk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d9554cf5b3a85a13fb39258c65b04b262989c1d7a758f8f555b77a478621a91"
"checksum imap 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01150a9ea6b0ff4c7135c04090bfe2e5e073b90263208b08a7d4bfff0b5f47e2"
"checksum imap 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3072853e727ec65d846008463e37265d8fe4917ed68765ae7dda2d1f5e65860b"
"checksum imap-proto 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8733e1ad1058e09532090e95b1debda73cc25ea4d1ba53bf4a60870c19865952"
"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"

View File

@ -19,7 +19,7 @@ license = "MIT/Apache-2.0"
debug=true
[dependencies]
imap = "0.6.0"
imap = "0.8.1"
native-tls = "0.1"
systray = "0.3.0"
mailparse = "0.6.0"

View File

@ -7,17 +7,17 @@ extern crate systray;
extern crate toml;
extern crate xdg;
use native_tls::{TlsConnector, TlsStream};
use imap::client::Client;
use native_tls::{TlsConnector, TlsStream};
use rayon::prelude::*;
use std::process::Command;
use std::fs::File;
use std::io::prelude::*;
use std::net::TcpStream;
use std::time::Duration;
use std::process::Command;
use std::sync::mpsc;
use std::fs::File;
use std::thread;
use std::time::Duration;
#[derive(Clone)]
struct Account {
@ -30,12 +30,14 @@ struct Account {
impl Account {
pub fn connect(&self) -> Result<Connection<TlsStream<TcpStream>>, imap::error::Error> {
let tls = TlsConnector::builder()?.build()?;
Client::secure_connect((&*self.server.0, self.server.1), &self.server.0, tls).and_then(
Client::secure_connect((&*self.server.0, self.server.1), &self.server.0, &tls).and_then(
|mut c| {
try!(c.login(&self.username, &self.password));
let cap = try!(c.capability());
if !cap.iter().any(|c| c == "IDLE") {
return Err(imap::error::Error::BadResponse(cap));
try!(c.login(self.username.trim(), self.password.trim()));
let cap = try!(c.capabilities());
if !cap.iter().any(|&c| c == "IDLE") {
return Err(imap::error::Error::BadResponse(
cap.iter().cloned().collect(),
));
}
try!(c.select("INBOX"));
Ok(Connection {
@ -103,7 +105,7 @@ impl<T: Read + Write + imap::client::SetReadTimeout> Connection<T> {
let mut num_unseen = 0;
let mut uids = Vec::new();
let unseen = unseen.join(" ");
let unseen = ::std::str::from_utf8(&unseen[..]).unwrap();
let unseen = unseen.split_whitespace().skip(2);
for uid in unseen.take_while(|&e| e != "" && e != "Completed") {
if let Ok(uid) = usize::from_str_radix(uid, 10) {
@ -117,18 +119,24 @@ impl<T: Read + Write + imap::client::SetReadTimeout> Connection<T> {
let mut subjects = Vec::new();
if !uids.is_empty() {
let mut finish = |message: &[u8]| -> bool {
match mailparse::parse_headers(message) {
for msg in self.socket
.uid_fetch(&uids.join(","), "RFC822.HEADER")?
.iter()
{
let msg = msg.rfc822_header();
if msg.is_none() {
continue;
}
match mailparse::parse_headers(msg.unwrap()) {
Ok((headers, _)) => {
use mailparse::MailHeaderMap;
match headers.get_first_value("Subject") {
Ok(Some(subject)) => {
subjects.push(subject);
return true;
}
Ok(None) => {
subjects.push(String::from("<no subject>"));
return true;
}
Err(e) => {
println!("failed to get message subject: {:?}", e);
@ -137,30 +145,14 @@ impl<T: Read + Write + imap::client::SetReadTimeout> Connection<T> {
}
Err(e) => println!("failed to parse headers of message: {:?}", e),
}
false
};
let lines = self.socket.uid_fetch(&uids.join(","), "RFC822.HEADER")?;
let mut message = Vec::new();
for line in &lines {
if line.starts_with("* ") {
if !message.is_empty() {
finish(&message[..]);
message.clear();
}
continue;
}
message.extend(line.as_bytes());
}
finish(&message[..]);
}
if !subjects.is_empty() {
use notify_rust::{Notification, NotificationHint};
let title = format!(
"@{} has new mail ({} unseen)",
self.account.name,
num_unseen
self.account.name, num_unseen
);
let notification = format!("> {}", subjects.join("\n> "));
println!("! {}", title);
@ -274,8 +266,8 @@ fn main() {
return;
}
};
if let Err(e) = app.set_icon_from_file(&"/usr/share/icons/Faenza/stock/24/stock_disconnect.png"
.to_string())
if let Err(e) =
app.set_icon_from_file(&"/usr/share/icons/Faenza/stock/24/stock_disconnect.png".to_string())
{
println!("Could not set application icon: {}", e);
}
@ -298,14 +290,12 @@ fn main() {
Err(imap::error::Error::Io(e)) => {
println!(
"Failed to connect account {}: {}; retrying in {}s",
account.name,
e,
wait
account.name, e, wait
);
thread::sleep(Duration::from_secs(wait));
}
Err(e) => {
println!("{} host produced bad IMAP tunnel: {}", account.name, e);
println!("{} host produced bad IMAP tunnel: {:?}", account.name, e);
break;
}
}
@ -323,8 +313,7 @@ fn main() {
}
// We have now connected
app.set_icon_from_file(&"/usr/share/icons/Faenza/stock/24/stock_connect.png"
.to_string())
app.set_icon_from_file(&"/usr/share/icons/Faenza/stock/24/stock_connect.png".to_string())
.ok();
let (tx, rx) = mpsc::channel();
@ -339,8 +328,7 @@ fn main() {
for (i, num_unseen) in rx {
unseen[i] = num_unseen;
if unseen.iter().sum::<usize>() == 0 {
app.set_icon_from_file(&"/usr/share/icons/oxygen/base/32x32/status/mail-unread.png"
.to_string())
app.set_icon_from_file(&"/usr/share/icons/oxygen/base/32x32/status/mail-unread.png".to_string())
.unwrap();
} else {
app.set_icon_from_file(