aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2021-05-22 18:26:24 +0200
committerTeddy Wing2021-05-22 18:29:16 +0200
commit8da3502b3f065a10e5faf4cd24bc988d843d798e (patch)
tree8a2a603ac6267c1bf22896804ff3fc65f601fcd4
parente40ea0fc324b1a0b47a7b3433ee3abe2b5171b40 (diff)
downloadgoogle-calendar-rsvp-8da3502b3f065a10e5faf4cd24bc988d843d798e.tar.bz2
Get event eid from email on standard input
If the `--email` flag is supplied, parse a Google Calendar email from standard input and extract the event's eid from there.
-rw-r--r--Cargo.lock85
-rw-r--r--Cargo.toml2
-rw-r--r--src/main.rs36
3 files changed, 120 insertions, 3 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d090f28..1b7791e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,6 +1,15 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
+name = "aho-corasick"
+version = "0.7.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -8,6 +17,15 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base64"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
@@ -25,6 +43,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
name = "bytes"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -43,6 +67,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
+name = "charset"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f426e64df1c3de26cbf44593c6ffff5dbfd43bbf9de0d075058558126b3fc73"
+dependencies = [
+ "base64 0.10.1",
+ "encoding_rs",
+]
+
+[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -88,6 +122,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
+name = "encoding_rs"
+version = "0.8.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
name = "exitcode"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -207,12 +250,14 @@ dependencies = [
name = "google-calendar-rsvp"
version = "0.0.1"
dependencies = [
- "base64",
+ "base64 0.13.0",
"exitcode",
"google-calendar3",
"home",
"hyper",
"hyper-rustls",
+ "mailparse",
+ "regex",
"serde_json",
"tokio",
"yup-oauth2",
@@ -440,6 +485,17 @@ dependencies = [
]
[[package]]
+name = "mailparse"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62db73ff1a42b0e3a8858cf0d5c183bdfc23491f7294ae4a8200c83577457386"
+dependencies = [
+ "base64 0.13.0",
+ "charset",
+ "quoted_printable",
+]
+
+[[package]]
name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -607,6 +663,29 @@ dependencies = [
]
[[package]]
+name = "quoted_printable"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1238256b09923649ec89b08104c4dfe9f6cb2fea734a5db5384e44916d59e9c5"
+
+[[package]]
+name = "regex"
+version = "1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
+
+[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -627,7 +706,7 @@ version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
dependencies = [
- "base64",
+ "base64 0.13.0",
"log 0.4.14",
"ring",
"sct",
@@ -1046,7 +1125,7 @@ version = "5.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2573621fa28865489bdf556cdb8703604f4e8498612e3041a212ac20e59c4aeb"
dependencies = [
- "base64",
+ "base64 0.13.0",
"chrono",
"futures",
"http",
diff --git a/Cargo.toml b/Cargo.toml
index 9c4fc75..6c6d536 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,6 +10,8 @@ google-calendar3 = "2.0.4+20210327"
home = "0.5.3"
hyper = "0.14.7"
hyper-rustls = "0.22.1"
+mailparse = "0.13.4"
+regex = "1.5.4"
serde_json = "1.0.64"
tokio = { version = "1.6.0", features = ["rt-multi-thread"] }
yup-oauth2 = "5.1.0"
diff --git a/src/main.rs b/src/main.rs
index a5e7a05..1d3595a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,12 +4,15 @@ use google_calendar3::CalendarHub;
use home;
use hyper;
use hyper_rustls;
+use mailparse;
+use regex::Regex;
use tokio;
use yup_oauth2 as oauth2;
use std::env;
use std::fmt;
use std::fs;
+use std::io::{self, Read};
use std::process;
use std::str;
@@ -38,6 +41,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut action_opt: Option<EventResponseStatus> = None;
let mut email = false;
+ let mut email_eid = String::new();
let mut event_ids = Vec::new();
for arg in &args[1..] {
@@ -66,6 +70,16 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
},
};
+ if email {
+ let mut stdin = io::stdin();
+ let mut email_input: Vec<u8> = Vec::new();
+ stdin.read_to_end(&mut email_input)?;
+
+ email_eid = eid_from_email(&email_input);
+
+ event_ids.push(&email_eid);
+ }
+
if event_ids.is_empty() {
eprintln!("error: missing event ID argument");
@@ -163,6 +177,28 @@ fn event_id_from_base64(event_id: &str) -> String {
id
}
+fn eid_from_email(email: &[u8]) -> String {
+ let email = mailparse::parse_mail(&email).unwrap();
+ let re = Regex::new("eid=([^&]+)&").unwrap();
+
+ // Assume email is multipart/alternative.
+ for part in &email.subparts {
+ if part.ctype.mimetype == "multipart/alternative" {
+ for part in &part.subparts {
+ if part.ctype.mimetype == "text/plain" {
+ let body = part.get_body().unwrap();
+ let captures = re.captures(&body).unwrap();
+ let eid = captures.get(1).unwrap();
+
+ return eid.as_str().to_owned();
+ }
+ }
+ }
+ }
+
+ todo!();
+}
+
#[cfg(test)]
mod tests {