added github calls

This commit is contained in:
Kasper Juul Hermansen 2022-10-13 20:10:18 +02:00
commit fd3f197364
Signed by: kjuulh
GPG Key ID: 57B6E1465221F912
6 changed files with 55664 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

1377
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

14
Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "github-status"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chrono = "0.4.22"
clap = { version = "4.0.14", features = ["derive", "env"] }
eyre = "0.6.8"
graphql_client = { version = "0.11.0", features = ["reqwest", "reqwest-blocking"] }
reqwest = { version = "0.11.12", features = ["blocking"] }
serde = { version = "1.0.145", features = ["derive"] }

View File

@ -0,0 +1,10 @@
mutation SetStatus($status: ChangeUserStatusInput!) {
changeUserStatus(input: $status) {
status {
emoji
expiresAt
limitedAvailability: indicatesLimitedAvailability
message
}
}
}

54123
commands/schema/github.graphql Normal file

File diff suppressed because it is too large Load Diff

139
src/main.rs Normal file
View File

@ -0,0 +1,139 @@
use clap::Parser;
use eyre::{Context, ContextCompat};
use graphql_client::{reqwest::post_graphql_blocking as post_graphql, GraphQLQuery};
use reqwest::blocking::Client;
#[derive(clap::ValueEnum, Clone, Debug)]
enum Availability {
Busy,
Free,
}
#[derive(Parser, Debug, Clone)]
#[command(author, version, about, long_about = None)]
struct Args {
/// Emoji to set ':smile:'
#[arg(short, long)]
emoji: Option<String>,
/// Message to display
#[arg(short, long)]
message: Option<String>,
#[arg(value_enum)]
availability: Option<Availability>,
#[arg(long)]
expires_in_minutes: Option<i64>,
#[arg(short, long)]
organization_id: Option<String>,
#[clap(env, long)]
github_token: Option<String>,
#[clap(env, long)]
github_url: Option<String>,
}
struct Status {
emoji: Option<String>,
message: Option<String>,
availability: Availability,
expires: Option<chrono::DateTime<chrono::Utc>>,
organization_id: Option<String>,
}
fn main() -> eyre::Result<()> {
let args = Args::parse();
let status = get_status_input(args.clone())?;
let github_token = get_github_token(args.clone())?;
set_github_status(args.github_url, github_token, status)?;
Ok(())
}
fn get_status_input(args: Args) -> eyre::Result<Status> {
Ok(Status {
emoji: args.emoji,
message: args.message,
availability: match args.availability {
Some(av) => av,
None => Availability::Free,
},
expires: match args.expires_in_minutes {
Some(0) => None,
Some(min) => Some(chrono::offset::Utc::now() + chrono::Duration::minutes(min)),
None => None,
},
organization_id: args.organization_id,
})
}
fn get_github_token(args: Args) -> eyre::Result<String> {
match args.github_token {
Some(token) => Ok(token),
None => {
// Temporary maybe moved because this should support different providers
Err(eyre::anyhow!("could not find github_token variable"))
}
}
}
type DateTime = String;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "commands/schema/github.graphql",
query_path = "commands/mutations/setGithubStatus.graphql",
response_derives = "Debug"
)]
pub struct SetStatus;
fn set_github_status(
github_url: Option<String>,
github_token: String,
status: Status,
) -> eyre::Result<()> {
let client = Client::builder()
.user_agent("graphql-rust/0.10.0")
.default_headers(
std::iter::once((
reqwest::header::AUTHORIZATION,
reqwest::header::HeaderValue::from_str(&format!("Bearer {}", github_token))
.context("could not format bearer token")?,
))
.collect(),
)
.build()?;
let variables = set_status::Variables {
status: set_status::ChangeUserStatusInput {
client_mutation_id: None,
emoji: status.emoji,
expires_at: status
.expires
.map(|expires| expires.to_rfc3339_opts(chrono::SecondsFormat::Millis, true)),
limited_availability: Some(match status.availability {
Availability::Busy => true,
Availability::Free => false,
}),
message: status.message,
organization_id: status.organization_id,
},
};
let response_body = post_graphql::<SetStatus, _>(
&client,
match github_url {
Some(url) => url,
None => "https://api.github.com/graphql".into(),
},
variables,
)
.unwrap();
let _: set_status::ResponseData = response_body.data.context("missing response data")?;
Ok(())
}