feat: initial proof of concept

this sucks so hard but both notify_rust and octocrab libs kinda suck and
don't allow me to do the right things easily. There sure is an
alternative solution but I'm not sinking (yet) more than ~1h and ~50
lines in this crap
This commit is contained in:
əlemi 2023-07-22 17:10:08 +02:00
parent e5177a9573
commit 1f3d640e41
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 78 additions and 0 deletions

14
Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "ghnotify"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
notify-rust = "4.8.0"
octocrab = "0.28.0"
open = "5.0.0"
reqwest = { version = "0.11.18", features = ["json"]}
serde_json = "1.0.103"
tokio = { version = "1.29.1", features = ["full"] } # TODO slim down features

64
src/main.rs Normal file
View file

@ -0,0 +1,64 @@
use octocrab::Octocrab;
use notify_rust::{Notification, Hint, CloseReason};
use tokio::sync::mpsc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let token = std::env::var("GITHUB_TOKEN").expect("GITHUB_TOKEN env variable is required");
let octocrab = Octocrab::builder().personal_token(token).build()?;
let notifications = octocrab
.activity()
.notifications()
.list()
.send()
.await?;
let mut tasks = Vec::new();
for notification in notifications {
// TODO on_close which doesn't block so I don't need to spawn all these workers!!!
tasks.push(tokio::spawn(async move {
// TODO on_close which can be FnOnce so I can move stuff into it and avoid channels!!!
let (tx, mut rx) = mpsc::unbounded_channel();
Notification::new()
.summary(&format!("{} (GitHub)", notification.repository.name))
.body(&format!("[{}] {}", notification.subject.r#type, notification.subject.title))
.appname("github")
.icon("github")
.action("clicked", "click here")
.hint(Hint::Resident(true))
.show_async().await.unwrap()
.on_close(|reason| match reason {
CloseReason::Dismissed => tx.send(true).unwrap(),
_ => tx.send(false).unwrap(),
});
if rx.recv().await.unwrap() {
if let Some(url) = notification.subject.url {
// TODO this is awful! Is there no proper way to get html_url using octocrab?????
let client = reqwest::Client::builder()
.user_agent("holy-shit-fuck-you-github-why-are-you-401-me-if-i-dont-give-an-user-agent")
.build().unwrap();
let response_raw = client.get(url)
.send()
.await.unwrap()
.text().await.unwrap();
let response : serde_json::Value = serde_json::from_str(&response_raw).unwrap();
let html_url = response
.get("html_url").unwrap();
open::that(html_url.as_str().unwrap()).unwrap();
} else if let Some(url) = notification.repository.html_url {
open::that(url.to_string()).unwrap();
} else {
open::that(notification.url.to_string()).unwrap();
};
}
}));
}
for t in tasks {
t.await?;
}
Ok(())
}