Skip to content

Commit 321da97

Browse files
authored
Merge pull request #12 from ivinjabraham/develop
new and improved status update
2 parents 0408a7f + 6edc0ca commit 321da97

File tree

8 files changed

+346
-96
lines changed

8 files changed

+346
-96
lines changed

Cargo.lock

Lines changed: 4 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7-
anyhow = "1.0.66"
7+
anyhow = "1.0.95"
88
async-trait = "0.1.83"
99
chrono = "0.4.38"
1010
chrono-tz = "0.10.0"
11-
poise = { git = "https://github.com/serenity-rs/poise", branch = "current" }
11+
poise = "0.6.1"
1212
reqwest = { version = "0.12.5", features = ["json"] }
1313
serde = { version = "1.0.203", features = ["derive"] }
1414
serde_json = "1.0.117"

config.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1334963922205147176
2+
1334963925585891419
3+
1334963927678849145
4+
1334963929922670682

src/graphql/models.rs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,24 @@ You should have received a copy of the GNU General Public License
1616
along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
1818
use serde::Deserialize;
19-
use std::borrow::Cow;
2019

21-
#[derive(Deserialize)]
22-
pub struct Member<'a> {
23-
id: Option<i32>,
24-
roll_num: Option<Cow<'a, str>>,
25-
name: Option<Cow<'a, str>>,
26-
hostel: &'a str,
27-
email: &'a str,
28-
sex: &'a str,
29-
year: i32,
30-
mac_addr: &'a str,
31-
discord_id: &'a str,
32-
group_id: i32,
20+
#[derive(Clone, Debug, Deserialize)]
21+
pub struct Streak {
22+
#[serde(rename = "currentStreak")]
23+
pub current_streak: i32,
24+
#[serde(rename = "maxStreak")]
25+
pub max_streak: i32,
3326
}
3427

35-
#[derive(Deserialize)]
36-
struct Data<'a> {
37-
getMember: Vec<Member<'a>>,
38-
}
39-
40-
#[derive(Deserialize)]
41-
struct Root<'a> {
42-
data: Data<'a>,
28+
#[derive(Clone, Debug, Deserialize)]
29+
pub struct Member {
30+
#[serde(rename = "memberId")]
31+
pub member_id: i32,
32+
pub name: String,
33+
#[serde(rename = "discordId")]
34+
pub discord_id: String,
35+
#[serde(rename = "groupId")]
36+
pub group_id: u32,
37+
#[serde(default)]
38+
pub streak: Vec<Streak>,
4339
}

src/graphql/queries.rs

Lines changed: 121 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,139 @@ GNU General Public License for more details.
1515
You should have received a copy of the GNU General Public License
1616
along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
18-
use serde_json::Value;
18+
use crate::graphql::models::{Member, Streak};
19+
use anyhow::Context;
1920

20-
use super::models::Member;
21+
pub async fn fetch_members() -> Result<Vec<Member>, anyhow::Error> {
22+
let request_url = std::env::var("ROOT_URL").expect("ROOT_URL not found");
2123

22-
const REQUEST_URL: &str = "https://root.shuttleapp.rs/";
23-
24-
pub async fn fetch_members() -> Result<Vec<String>, reqwest::Error> {
2524
let client = reqwest::Client::new();
2625
let query = r#"
27-
query {
28-
getMember {
29-
name,
30-
groupId,
26+
{
27+
members {
28+
memberId
29+
name
3130
discordId
31+
groupId
32+
streak {
33+
currentStreak
34+
maxStreak
35+
}
3236
}
3337
}"#;
3438

3539
let response = client
36-
.post(REQUEST_URL)
40+
.post(request_url)
3741
.json(&serde_json::json!({"query": query}))
3842
.send()
39-
.await?;
43+
.await
44+
.context("Failed to successfully post request")?;
45+
46+
let response_json: serde_json::Value = response
47+
.json()
48+
.await
49+
.context("Failed to serialize response")?;
50+
51+
let members = response_json
52+
.get("data")
53+
.and_then(|data| data.get("members"))
54+
.and_then(|members| members.as_array())
55+
.ok_or_else(|| anyhow::anyhow!("Malformed response: 'members' field missing or invalid"))?;
56+
57+
let members: Vec<Member> = serde_json::from_value(serde_json::Value::Array(members.clone()))
58+
.context("Failed to parse 'members' into Vec<Member>")?;
59+
60+
Ok(members)
61+
}
62+
63+
pub async fn increment_streak(member: &mut Member) -> anyhow::Result<()> {
64+
let request_url = std::env::var("ROOT_URL").context("ROOT_URL was not found")?;
65+
66+
let client = reqwest::Client::new();
67+
let mutation = format!(
68+
r#"
69+
mutation {{
70+
incrementStreak(input: {{ memberId: {} }}) {{
71+
currentStreak
72+
}}
73+
}}"#,
74+
member.member_id
75+
);
76+
let response = client
77+
.post(request_url)
78+
.json(&serde_json::json!({"query": mutation}))
79+
.send()
80+
.await
81+
.context("Root Request failed")?;
4082

41-
let json: Value = response.json().await?;
83+
// Handle the streak vector
84+
if member.streak.is_empty() {
85+
// If the streak vector is empty, add a new Streak object with both values set to 1
86+
member.streak.push(Streak {
87+
current_streak: 1,
88+
max_streak: 1,
89+
});
90+
} else {
91+
// Otherwise, increment the current_streak for each Streak and update max_streak if necessary
92+
for streak in &mut member.streak {
93+
streak.current_streak += 1;
94+
if streak.current_streak > streak.max_streak {
95+
streak.max_streak = streak.current_streak;
96+
}
97+
}
98+
}
99+
100+
Ok(())
101+
}
42102

43-
let member_names: Vec<String> = json["data"]["getMember"]
44-
.as_array()
45-
.unwrap()
46-
.iter()
47-
.map(Member)
48-
.collect();
103+
pub async fn reset_streak(member: &mut Member) -> anyhow::Result<()> {
104+
let request_url = std::env::var("ROOT_URL").context("ROOT_URL was not found")?;
49105

50-
Ok(member_names)
106+
let client = reqwest::Client::new();
107+
let mutation = format!(
108+
r#"
109+
mutation {{
110+
resetStreak(input: {{ memberId: {} }}) {{
111+
currentStreak
112+
maxStreak
113+
}}
114+
}}"#,
115+
member.member_id
116+
);
117+
118+
let response = client
119+
.post(&request_url)
120+
.json(&serde_json::json!({ "query": mutation }))
121+
.send()
122+
.await
123+
.context("Root Request failed")?;
124+
125+
let response_json: serde_json::Value = response
126+
.json()
127+
.await
128+
.context("Failed to parse response JSON")?;
129+
if let Some(data) = response_json
130+
.get("data")
131+
.and_then(|data| data.get("resetStreak"))
132+
{
133+
let current_streak = data.get("currentStreak").and_then(|v| v.as_i64()).unwrap();
134+
135+
let max_streak = data.get("maxStreak").and_then(|v| v.as_i64()).unwrap();
136+
137+
// Update the member's streak vector
138+
if member.streak.is_empty() {
139+
// If the streak vector is empty, initialize it with the returned values
140+
member.streak.push(Streak {
141+
current_streak: current_streak as i32,
142+
max_streak: max_streak as i32,
143+
});
144+
} else {
145+
// Otherwise, update the first streak entry
146+
for streak in &mut member.streak {
147+
streak.current_streak = current_streak as i32;
148+
streak.max_streak = max_streak as i32;
149+
}
150+
}
151+
}
152+
Ok(())
51153
}

src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ pub fn initialize_data() -> Data {
9898

9999
data
100100
}
101+
101102
#[tokio::main]
102-
async fn main(
103-
) -> Result<(), Error> {
103+
async fn main() -> Result<(), Error> {
104104
dotenv::dotenv().ok();
105105
let discord_token = std::env::var("DISCORD_TOKEN").context("'DISCORD_TOKEN' was not found")?;
106106

src/tasks/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl Task for StatusUpdateCheck {
5050
}
5151

5252
fn run_in(&self) -> Duration {
53-
time_until(9, 0)
53+
time_until(00, 40)
5454
}
5555

5656
async fn run(&self, ctx: Context) {

0 commit comments

Comments
 (0)