From 9feba1a136199f947b09c84e27ab3d7551654696 Mon Sep 17 00:00:00 2001 From: Kiana Sheibani Date: Sat, 30 Sep 2023 04:37:10 -0400 Subject: [PATCH] Various fixes --- src/datasets.rs | 18 ++--- src/main.rs | 11 ++- src/queries.rs | 3 + src/queries/tournament_sets.rs | 126 +++++++++++++++------------------ 4 files changed, 74 insertions(+), 84 deletions(-) diff --git a/src/datasets.rs b/src/datasets.rs index ae2447c..5b80c62 100644 --- a/src/datasets.rs +++ b/src/datasets.rs @@ -12,7 +12,7 @@ fn datasets_path(config_dir: &Path) -> io::Result { // Create datasets path if it doesn't exist fs::create_dir_all(&path)?; - path.push("main.db"); + path.push("datasets.sqlite"); // Create datasets file if it doesn't exist OpenOptions::new().write(true).create(true).open(&path)?; @@ -26,7 +26,7 @@ pub fn open_datasets(config_dir: &Path) -> sqlite::Result { let query = " CREATE TABLE IF NOT EXISTS datasets ( name TEXT UNIQUE NOT NULL, - last_sync INTEGER NOT NULL DEFAULT 1 + last_sync INTEGER DEFAULT 1 ) STRICT;"; let connection = sqlite::open(path)?; @@ -58,7 +58,7 @@ pub fn delete_dataset(connection: &Connection, dataset: &str) -> sqlite::Result< pub fn new_dataset(connection: &Connection, dataset: &str) -> sqlite::Result<()> { let query = format!( - r#"INSERT INTO datasets VALUES ('{0}'); + r#"INSERT INTO datasets (name) VALUES ('{0}'); CREATE TABLE IF NOT EXISTS "dataset_{0}" ( id INTEGER PRIMARY KEY, @@ -201,7 +201,7 @@ fn update_from_set(connection: &Connection, dataset: &str, results: SetData) -> update_ratings(connection, dataset, elos) } -fn update_from_tournament( +pub fn update_from_tournament( connection: &Connection, dataset: &str, results: TournamentData, @@ -211,13 +211,3 @@ fn update_from_tournament( .into_iter() .try_for_each(|set| update_from_set(connection, dataset, set)) } - -pub fn update_from_tournaments( - connection: &Connection, - dataset: &str, - results: Vec, -) -> sqlite::Result<()> { - results - .into_iter() - .try_for_each(|tour| update_from_tournament(connection, dataset, tour)) -} diff --git a/src/main.rs b/src/main.rs index 1d60a9f..2145667 100644 --- a/src/main.rs +++ b/src/main.rs @@ -119,6 +119,9 @@ fn sync(names: Vec, all: bool, auth_token: Option) { let names = if all { list_datasets(&connection).unwrap() + } else if names.len() == 0 { + new_dataset(&connection, "default").unwrap(); + vec![String::from("default")] } else { names }; @@ -130,14 +133,16 @@ fn sync(names: Vec, all: bool, auth_token: Option) { TournamentSetsVars { last_query: Timestamp(last_sync), game_id: VideogameId(1), - country: None, - state: None, + tournament: 1, + set_page: 1, + set_pagesize: 50, + event_limit: 9999999, }, &auth, ) .unwrap(); - update_from_tournaments(&connection, &name, results).unwrap(); + update_from_tournament(&connection, &name, results).unwrap(); let current_time = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) diff --git a/src/queries.rs b/src/queries.rs index 6e00393..9d593cc 100644 --- a/src/queries.rs +++ b/src/queries.rs @@ -1,5 +1,6 @@ use cynic::{GraphQlResponse, QueryBuilder}; use serde::{Deserialize, Serialize}; +use std::fmt::Debug; use std::path::Path; pub mod search_games; @@ -22,6 +23,7 @@ pub fn get_auth_token(config_dir: &Path) -> Option { Err(VarError::NotUnicode(_)) => panic!("Invalid authorization key"), Err(VarError::NotPresent) => { let mut auth_file = config_dir.to_owned(); + auth_file.push("ggelo"); auth_file.push("auth.txt"); read_to_string(auth_file).ok().and_then(|s| { let trimmed = s.trim(); @@ -67,6 +69,7 @@ pub trait QueryUnwrap: 'static + QueryBuilder { // Generic function for running start.gg queries pub fn run_query(vars: Vars, auth_token: &str) -> Option where + Builder: Debug, Builder: QueryUnwrap, Vars: Serialize, for<'de> Builder: Deserialize<'de>, diff --git a/src/queries/tournament_sets.rs b/src/queries/tournament_sets.rs index 9f81e76..5be5904 100644 --- a/src/queries/tournament_sets.rs +++ b/src/queries/tournament_sets.rs @@ -7,15 +7,17 @@ pub type Teams = Vec>; // Variables #[derive(cynic::QueryVariables, Debug)] -pub struct TournamentSetsVars<'a> { +pub struct TournamentSetsVars { // HACK: This should really be an optional variable, but there seems to be a // server-side bug that completely breaks everything when this isn't passed. // We can use a dummy value of 1 when we don't want to filter by time. pub last_query: Timestamp, - pub game_id: VideogameId, - pub country: Option<&'a str>, - pub state: Option<&'a str>, + + pub tournament: i32, + pub event_limit: i32, + pub set_page: i32, + pub set_pagesize: i32, } // Query @@ -24,15 +26,13 @@ pub struct TournamentSetsVars<'a> { #[cynic(graphql_type = "Query", variables = "TournamentSetsVars")] pub struct TournamentSets { #[arguments(query: { - page: 1, + page: $tournament, perPage: 1, - sortBy: "endAt desc", + sortBy: "endAt asc", filter: { past: true, afterDate: $last_query, videogameIds: [$game_id], - countryCode: $country, - addrState: $state }})] tournaments: Option, } @@ -48,14 +48,15 @@ struct TournamentConnection { #[cynic(variables = "TournamentSetsVars")] struct Tournament { name: Option, - #[arguments(limit: 99999, filter: { videogameId: [$game_id] })] + #[arguments(limit: $event_limit, filter: { videogameId: [$game_id] })] #[cynic(flatten)] events: Vec, } #[derive(cynic::QueryFragment, Debug)] +#[cynic(variables = "TournamentSetsVars")] struct Event { - #[arguments(page: 1, perPage: 999)] + #[arguments(page: $set_page, perPage: $set_pagesize)] sets: Option, } @@ -111,67 +112,58 @@ pub struct SetData { pub winner: usize, } -impl<'a> QueryUnwrap> for TournamentSets { - type Unwrapped = Vec; +impl QueryUnwrap for TournamentSets { + type Unwrapped = TournamentData; // This might be the most spaghetti code I've ever written - fn unwrap_response(response: GraphQlResponse) -> Option> { - Some( - response - .data? - .tournaments? - .nodes - .into_iter() - .filter_map(|tour| { - let sets = tour - .events + fn unwrap_response(response: GraphQlResponse) -> Option { + let tour = response.data?.tournaments?.nodes.into_iter().next()?; + let sets = tour + .events + .into_iter() + .filter_map(|event| { + Some( + event + .sets? + .nodes .into_iter() - .filter_map(|event| { - Some( - event - .sets? - .nodes - .into_iter() - .filter_map(|set| { - let winner_id = set.winner_id?; - let winner = set.slots.iter().position(|slot| { - slot.entrant - .as_ref() - .and_then(|x| x.id) - .map(|id| id.0 == winner_id as u64) - .unwrap_or(false) - })?; - let teams = set - .slots - .into_iter() - .map(|slot| { - slot.entrant? - .participants - .into_iter() - .map(|p| { - let p_ = p.player?; - Some(PlayerData { - id: p_.id?, - name: p_.gamer_tag, - prefix: p_.prefix, - }) - }) - .try_collect() + .filter_map(|set| { + let winner_id = set.winner_id?; + let winner = set.slots.iter().position(|slot| { + slot.entrant + .as_ref() + .and_then(|x| x.id) + .map(|id| id.0 == winner_id as u64) + .unwrap_or(false) + })?; + let teams = set + .slots + .into_iter() + .map(|slot| { + slot.entrant? + .participants + .into_iter() + .map(|p| { + let p_ = p.player?; + Some(PlayerData { + id: p_.id?, + name: p_.gamer_tag, + prefix: p_.prefix, }) - .try_collect()?; - Some(SetData { teams, winner }) - }) - .collect::>(), - ) + }) + .try_collect() + }) + .try_collect()?; + Some(SetData { teams, winner }) }) - .flatten() - .collect(); - Some(TournamentData { - name: tour.name?, - sets, - }) - }) - .collect(), - ) + .collect::>(), + ) + }) + .flatten() + .collect(); + Some(TournamentData { + name: tour.name?, + sets, + }) } }