140 lines
3.7 KiB
Rust
140 lines
3.7 KiB
Rust
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(())
|
|
}
|