diff --git a/Cargo.lock b/Cargo.lock index d8c9113..af01bd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2419,6 +2419,7 @@ dependencies = [ "maud", "rand 0.8.5", "serde", + "serde_json", "serenity", "sqlx", "surf", diff --git a/Cargo.toml b/Cargo.toml index a26023a..2128303 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ dotenvy = "0.15.7" # For sqlite sqlx = { version = "0.7.1", features = [ "runtime-tokio", "sqlite", "migrate" ] } +serde_json = { version = "1.0", features = ["raw_value"] } # create random strings rand = "0.8.5" diff --git a/db/migrations/7_committee-mk-ii.sql b/db/migrations/7_committee-mk-ii.sql index 2ddf316..c086f3d 100644 --- a/db/migrations/7_committee-mk-ii.sql +++ b/db/migrations/7_committee-mk-ii.sql @@ -3,8 +3,8 @@ DROP TABLE committee; -- new table pulling from teh api CREATE TABLE IF NOT EXISTS committees ( - id integer PRIMARY KEY, - name text not null, - link text not null, - members text not null + id integer PRIMARY KEY, + name text not null, + link text not null, + committee text not null ); diff --git a/src/common/wolves.rs b/src/common/wolves.rs index c13b163..380d25a 100644 --- a/src/common/wolves.rs +++ b/src/common/wolves.rs @@ -7,13 +7,6 @@ use crate::common::database::Wolves; */ -// #[derive(Debug, Clone, sqlx::FromRow)] -// pub struct Committees { -// pub id: i64, -// pub name: String, -// pub link: String, -// pub members: Vec, -// } #[derive(Deserialize, Serialize, Debug)] struct WolvesResultUserMin { @@ -227,7 +220,119 @@ pub mod cns { /** Get and store the data on C&S committees */ -pub mod committees {} +pub mod committees { + use serde::{Deserialize, Serialize}; + use serenity::client::Context; + use sqlx::{ Pool, Sqlite}; + use crate::common::database::{DataBase}; + use crate::Config; + + // This is what Wolves returns to us + #[derive(Deserialize, Serialize, Debug)] + struct WolvesResult { + success: i8, + result: Vec, + } + + // this is teh actual data we care about + #[derive(Deserialize, Serialize, Debug)] + struct WolvesResultCNS { + id: String, + name: String, + // Link to their page such as https://ulwolves.ie/society/computer + link: String, + // array of Committee members member_id's + committee: Vec + } + + // Database entry for it + #[derive(Debug, Clone, sqlx::FromRow)] + pub struct Committees { + pub id: i64, + pub name: String, + pub link: String, + #[sqlx(json)] + pub committee: Vec, + } + + impl From for Committees { + fn from(value: WolvesResultCNS) -> Self { + Self{ + id: value.id.parse().unwrap_or(0), + name: value.name, + link: value.link, + committee: value.committee.iter().map(|x| x.parse::().unwrap_or(0)).collect(), + } + } + } + + pub async fn get_cns(ctx: &Context){ + let db_lock = { + let data_read = ctx.data.read().await; + data_read.get::().expect("Expected Database in TypeMap.").clone() + }; + let db = db_lock.read().await; + + let config_lock = { + let data_read = ctx.data.read().await; + data_read.get::().expect("Expected Config in TypeMap.").clone() + }; + let config = config_lock.read().await; + + // TODO: proper api key management + let api_key = ""; + // request data from wolves + for committee in get_committees(&config, api_key).await { + let tmp = Committees::from(committee); + add_committee(&db, &tmp).await; + } + } + + async fn get_committees(config: &Config, wolves_api: &str) -> Vec { + if config.wolves_url.is_empty() { + return vec![]; + } + + // TODO: Change teh stored env value to teh base domain + let url = format!("{}/get_cns", &config.wolves_url); + + // get wolves data + if let Ok(mut res) = surf::post(&url).header("X-AM-Identity", wolves_api).await { + if let Ok(WolvesResult { success, result, }) = res.body_json().await { + if success != 1 { + return vec![]; + } + + return result; + } + } + + vec![] + } + + async fn add_committee(db: &Pool, committee: &Committees) { + match sqlx::query_as::<_, Committees>( + " + INSERT INTO committees (id, name, link, committee) + VALUES ($1, $2, $3, $4) + ON CONFLICT(id) DO UPDATE SET committee = $4 + ", + ) + .bind(committee.id) + .bind(&committee.name) + .bind(&committee.link) + .bind(serde_json::to_string(&committee.committee).unwrap_or_default()) + .fetch_optional(db) + .await + { + Ok(_) => {} + Err(e) => { + println!("Failure to insert into Committees {:?}", committee); + println!("{:?}", e); + } + } + } +} /** get the data for an individual user