Use new structured rust-imap release
This commit is contained in:
parent
58f8c07acf
commit
64bc03163e
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
70
src/main.rs
70
src/main.rs
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue