remove unused crust, arguments enabled

This commit is contained in:
Teldra 2019-08-26 10:54:46 +02:00 committed by teldra
commit 37e9cd65f0
3 changed files with 28 additions and 82 deletions

View File

@ -1,16 +1,16 @@
[package]
name = "buzz"
version = "1.1.10"
name = "buzz-ed"
version = "1.1.11"
description = "A simple system tray application for notifying about unseen e-mail"
description = "A simple application for notifying about unseen e-mail"
readme = "README.md"
authors = ["Jon Gjengset <jon@thesquareplanet.com>"]
homepage = "https://github.com/jonhoo/buzz"
repository = "https://github.com/jonhoo/buzz.git"
homepage = "https://github.com/teldra/buzz-ed"
repository = "https://github.com/teldra/buzz-ed.git"
keywords = ["email","cli","systray","notification"]
keywords = ["email","cli"]
categories = ["command-line-utilities", "email"]
license = "MIT/Apache-2.0"

View File

@ -1,28 +1,21 @@
# Introduction
Using mutt (or pine), but annoyed that it doesn't give you any
notifications when you've received new emails? buzz is a simple tray
notifications when you've received new emails? buzz-ed is a simple
application that detects new emails on IMAP servers using IDLE (push
rather than pull). When it detects unseen messages, it shows a OSD style
notification and changes the tray icon to indicate that you have new
mail.
rather than pull). When it detects unseen messages, it shows writes
the amount of new messages to a defined file and runs a defined command.
This project is a Rust fork of
[hasmail](https://github.com/jonhoo/hasmail), which provides basically
the same features, and is written in Go.
## What does it look like:
![no new e-mail](assets/no-email.png?raw=true)
![new e-mail](assets/new-email.png?raw=true)
![new e-mail notification](assets/notification.png?raw=true)
# Configuration
buzz looks for a
buzz-ed looks for a
[TOML](https://github.com/toml-lang/toml#user-content-example)
configuration file in `~/.config/buzz.toml` on startup. The
configuration file in `~/.config/buzz/buzz.toml` on startup. The
configuration file consists of a number of sections, each corresponding
to one account:
@ -34,11 +27,20 @@ username = "jon@gmail.com"
pwcmd = "gnome-keyring-query get gmail_pw"
```
## Running buzz-ed
```
buzz /tmp/mails "pkill -RTMIN+2 i3blocks"
```
The first argument is the file, where it stores the amount of unread messages.
The second argument is the script or programm it starts after the amount has changed.
## Account fields
The value in `[]` can be anything (though avoid `.` as it will be parsed
as a new TOML section), and is shown in the tooltip when new e-mails
arrive for an account. The options for an account are as follows:
as a new TOML section). The options for an account are as follows:
- `server`: The address to connect to. MUST currently be SSL/TLS
enabled.
@ -46,8 +48,4 @@ arrive for an account. The options for an account are as follows:
- `username`: Username for authentication.
- `pwcmd`: Command to execute to get password for authentication.
# TODOs
- [ ] `click` command
- [ ] hover tooltip
- [ ] customizeable folder

View File

@ -9,8 +9,6 @@ extern crate xdg;
use native_tls::{TlsConnector, TlsStream};
use rayon::prelude::*;
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::fs::File;
use std::io::prelude::*;
use std::net::TcpStream;
@ -105,56 +103,6 @@ impl<T: Read + Write + imap::extensions::idle::SetReadTimeout> Connection<T> {
}
last_notified = std::cmp::max(last_notified, uids.iter().cloned().max().unwrap_or(0));
let mut subjects = BTreeMap::new();
if !uids.is_empty() {
let uids: Vec<_> = uids.into_iter().map(|v: u32| format!("{}", v)).collect();
for msg in self.socket
.uid_fetch(&uids.join(","), "RFC822.HEADER")?
.iter()
{
let msg = msg.header();
if msg.is_none() {
continue;
}
match mailparse::parse_headers(msg.unwrap()) {
Ok((headers, _)) => {
use mailparse::MailHeaderMap;
let subject = match headers.get_first_value("Subject") {
Ok(Some(subject)) => Cow::from(subject),
Ok(None) => Cow::from("<no subject>"),
Err(e) => {
println!("failed to get message subject: {:?}", e);
continue;
}
};
let date = match headers.get_first_value("Date") {
Ok(Some(date)) => {
match chrono::DateTime::parse_from_rfc2822(&date) {
Ok(date) => date.with_timezone(&chrono::Local),
Err(e) => {
println!("failed to parse message date: {:?}", e);
chrono::Local::now()
}
}
}
Ok(None) => chrono::Local::now(),
Err(e) => {
println!("failed to get message date: {:?}", e);
continue;
}
};
subjects.insert(date, subject);
}
Err(e) => println!("failed to parse headers of message: {:?}", e),
}
}
}
tx.send((account, num_unseen)).unwrap();
// IDLE until we see changes
@ -296,14 +244,14 @@ fn main() {
for (i, num_unseen) in rx {
unseen[i] = num_unseen;
let mut file = std::fs::File::create("/tmp/mails").expect("create failed");
let output_path = ::std::env::args().nth(1).unwrap();
let commands = ::std::env::args().nth(2).unwrap();
let mut file = std::fs::File::create(&output_path).expect("create failed");
file.write_all(num_unseen.to_string().as_bytes()).expect(
"write failed",
);
Command::new("pkill")
.arg("-RTMIN+2")
.arg("i3blocks")
.spawn()
.expect("pkill command failed to start");
Command::new("sh").arg("-c").arg(&commands).spawn().expect(
"command failed to start",
);
}
}