From 8549f5ec9139f63bfac5f86ec883d269a608bd00 Mon Sep 17 00:00:00 2001 From: Dan Chiarlone Date: Wed, 27 Dec 2023 15:22:43 -0800 Subject: [PATCH] fixing bug in pidgtm compile (#54) * fixing bug in pidgtm compile Signed-off-by: danbugs * improve Signed-off-by: danbugs --------- Signed-off-by: danbugs fixing bug in pidgtm compile (#55) * fixing bug in pidgtm compile Signed-off-by: danbugs * fix && fmt Signed-off-by: danbugs --------- Signed-off-by: danbugs fix pidgtm compile bug Signed-off-by: danbugs fix && fmt Signed-off-by: danbugs fix pidgtm compile bug Signed-off-by: danbugs fix && fmt Signed-off-by: danbugs fix pidgtm compile bug Signed-off-by: danbugs fix && fmt Signed-off-by: danbugs fix pidgtm compile bug Signed-off-by: danbugs fix && fmt Signed-off-by: danbugs fix pidgtm compile bug Signed-off-by: danbugs --- Cargo.lock | 25 +------- .../2023-12-27-224952_migration4/down.sql | 14 +++++ .../2023-12-27-224952_migration4/up.sql | 14 +++++ database/src/db_models/game.rs | 4 ++ database/src/db_models/player.rs | 6 +- database/src/db_models/set.rs | 6 -- database/src/schema.rs | 22 ++++--- lib/Cargo.toml | 2 +- lib/src/common.rs | 32 ++++++++-- lib/src/game.rs | 2 + lib/src/player.rs | 62 +++++++++++++------ lib/src/tournament.rs | 15 +++-- src/bin/pidgtm.rs | 9 +-- src/bin/smithe.rs | 8 +-- startgg_api/src/lib.rs | 4 +- 15 files changed, 136 insertions(+), 89 deletions(-) create mode 100644 database/migrations/2023-12-27-224952_migration4/down.sql create mode 100644 database/migrations/2023-12-27-224952_migration4/up.sql diff --git a/Cargo.lock b/Cargo.lock index 81f100f..7f915ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1740,7 +1740,7 @@ dependencies = [ "startgg", "tokio", "tracing", - "tracing-test", + "tracing-subscriber", ] [[package]] @@ -2088,29 +2088,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "tracing-test" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a2c0ff408fe918a94c428a3f2ad04e4afd5c95bbc08fcf868eff750c15728a4" -dependencies = [ - "lazy_static", - "tracing-core", - "tracing-subscriber", - "tracing-test-macro", -] - -[[package]] -name = "tracing-test-macro" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bc1c4f8e2e73a977812ab339d503e6feeb92700f6d07a6de4d321522d5c08" -dependencies = [ - "lazy_static", - "quote", - "syn 1.0.99", -] - [[package]] name = "try-lock" version = "0.2.3" diff --git a/database/migrations/2023-12-27-224952_migration4/down.sql b/database/migrations/2023-12-27-224952_migration4/down.sql new file mode 100644 index 0000000..740f2d1 --- /dev/null +++ b/database/migrations/2023-12-27-224952_migration4/down.sql @@ -0,0 +1,14 @@ +-- Revert primary key change in player_games +ALTER TABLE player_games +DROP CONSTRAINT player_games_pkey; + +ALTER TABLE player_games +ADD PRIMARY KEY (game_id, requester_id); + +-- Remove the set_id column from player_games +ALTER TABLE player_games +DROP COLUMN set_id; + +-- Add the game_ids column back to player_sets +ALTER TABLE player_sets +ADD COLUMN game_ids INTEGER ARRAY; diff --git a/database/migrations/2023-12-27-224952_migration4/up.sql b/database/migrations/2023-12-27-224952_migration4/up.sql new file mode 100644 index 0000000..4114368 --- /dev/null +++ b/database/migrations/2023-12-27-224952_migration4/up.sql @@ -0,0 +1,14 @@ +-- Drop the game_ids column from player_sets +ALTER TABLE player_sets +DROP COLUMN game_ids; + +-- Add the set_id column to player_games +ALTER TABLE player_games +ADD COLUMN set_id INTEGER; + +-- Update the primary key of player_games +ALTER TABLE player_games +DROP CONSTRAINT player_games_pkey; + +ALTER TABLE player_games +ADD PRIMARY KEY (game_id, requester_id, set_id); diff --git a/database/src/db_models/game.rs b/database/src/db_models/game.rs index 7e73f26..e19dcde 100644 --- a/database/src/db_models/game.rs +++ b/database/src/db_models/game.rs @@ -14,9 +14,11 @@ pub struct Game { requester_char_played: Option, opponent_char_played: Option, stage: Option, + set_id: i32, } impl Game { + #[allow(clippy::too_many_arguments)] pub fn new( gid: i32, rid: i32, @@ -25,6 +27,7 @@ impl Game { rcp_num_o: Option, ocp_num_o: Option, s: Option, + sid: i32, ) -> Self { Self { game_id: gid, @@ -34,6 +37,7 @@ impl Game { requester_char_played: rcp_num_o.map(get_character_from_id), opponent_char_played: ocp_num_o.map(get_character_from_id), stage: s, + set_id: sid, } } } diff --git a/database/src/db_models/player.rs b/database/src/db_models/player.rs index 2cded89..2f9029b 100644 --- a/database/src/db_models/player.rs +++ b/database/src/db_models/player.rs @@ -21,7 +21,7 @@ pub struct Player { pub gender_pronouns: Option, pub birthday: Option, pub bio: Option, - pub rankings: Option>, + pub rankings: Option>>, } impl From for Player { @@ -70,8 +70,8 @@ impl From for Player { bio: u.bio, rankings: p.rankings.map(|r| { r.iter() - .map(|pr| format!("#{} @ {}", pr.rank, pr.title)) - .collect::>() + .map(|pr| Some(format!("#{} @ {}", pr.rank, pr.title))) + .collect::>>() }), } } diff --git a/database/src/db_models/set.rs b/database/src/db_models/set.rs index a67f542..1a009fb 100644 --- a/database/src/db_models/set.rs +++ b/database/src/db_models/set.rs @@ -5,8 +5,6 @@ use serde::Serialize; // — an auto fix for this exists only in Diesel v2. use crate::schema::player_sets; -use crate::db_models::game::Game; - #[derive(Debug, Serialize, Insertable, Queryable, QueryableByName)] #[table_name = "player_sets"] pub struct Set { @@ -20,7 +18,6 @@ pub struct Set { opponent_score: i32, opponent_seed: i32, result_type: i32, - game_ids: Option>, event_id: i32, tournament_id: i32, is_event_online: bool, @@ -35,7 +32,6 @@ impl Set { is_on: bool, e_id: i32, t_id: i32, - maybe_games: Option>, rtag: &str, rscore: i32, rseed: i32, @@ -59,8 +55,6 @@ impl Set { is_event_online: is_on, event_id: e_id, tournament_id: t_id, - game_ids: maybe_games - .map(|games| games.iter().map(|g| g.game_id).collect::>()), } } } diff --git a/database/src/schema.rs b/database/src/schema.rs index 670c1bf..c64c1a3 100644 --- a/database/src/schema.rs +++ b/database/src/schema.rs @@ -1,17 +1,19 @@ -table! { +// @generated automatically by Diesel CLI. + +diesel::table! { empty_player_ids (player_id) { player_id -> Int4, } } -table! { +diesel::table! { last_checked_player_id (player_id) { player_id -> Int4, } } -table! { - player_games (game_id, requester_id) { +diesel::table! { + player_games (game_id, requester_id, set_id) { game_id -> Int4, requester_id -> Int4, requester_win -> Nullable, @@ -19,10 +21,11 @@ table! { requester_char_played -> Nullable, opponent_char_played -> Nullable, stage -> Nullable, + set_id -> Int4, } } -table! { +diesel::table! { player_sets (id, requester_id) { id -> Int4, completed_at -> Int8, @@ -34,14 +37,13 @@ table! { opponent_score -> Int4, opponent_seed -> Int4, result_type -> Int4, - game_ids -> Nullable>, event_id -> Int4, tournament_id -> Int4, is_event_online -> Bool, } } -table! { +diesel::table! { player_tournaments (tournament_id, event_id, requester_id) { tournament_id -> Int4, event_id -> Int4, @@ -56,7 +58,7 @@ table! { } } -table! { +diesel::table! { players (player_id) { player_id -> Int4, user_slug -> Varchar, @@ -71,11 +73,11 @@ table! { gender_pronouns -> Nullable, birthday -> Nullable, bio -> Nullable, - rankings -> Nullable>, + rankings -> Nullable>>, } } -allow_tables_to_appear_in_same_query!( +diesel::allow_tables_to_appear_in_same_query!( empty_player_ids, last_checked_player_id, player_games, diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 318ac30..8b82a03 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,11 +11,11 @@ test = false [dependencies] anyhow = "1" tracing = "0.1" +tracing-subscriber = "0.3" diesel = { version = "1.4", features = ["postgres"] } smithe_database = { path = "../database" } startgg = { path = "../startgg_api" } ctrlc = "3.2" as-any = "0.3" tokio = { version = "1.1", features = [ "rt", "macros" ] } -tracing-test = "0.2" chrono = "0.4" diff --git a/lib/src/common.rs b/lib/src/common.rs index a205264..accfb43 100644 --- a/lib/src/common.rs +++ b/lib/src/common.rs @@ -1,6 +1,8 @@ #![allow(unused)] use anyhow::Result; +use tracing::Level; +use tracing_subscriber::FmtSubscriber; use std::{ future::Future, @@ -13,6 +15,16 @@ use std::{ time::{Duration, Instant}, }; +pub fn init_logger() -> Result<()> { + let subscriber = FmtSubscriber::builder() + .with_max_level(Level::INFO) + .finish(); + + tracing::subscriber::set_global_default(subscriber)?; + + Ok(()) +} + use startgg::{GQLData, GQLVars}; #[allow(clippy::too_many_arguments)] @@ -47,15 +59,15 @@ where let mut curr_page = start; let mut now = Instant::now(); - loop { + 'outer: loop { let result; - loop { + 'inner: loop { tracing::info!("🍥 querying StartGG API..."); match get_pages(curr_page, gql_vars.clone()).await { Ok(data) => { tracing::info!("🍥 got data for page {}", &curr_page); result = data; - break; + break 'inner; } Err(e) => { if e.to_string().contains("429") @@ -83,10 +95,20 @@ where now = Instant::now(); } } else { - tracing::info!( + tracing::error!( "🙃 an oddity happened, skipping for now ({:#?})...", e.to_string() ); + + // weird error, skip this iteration + if e.to_string() + .contains("Look at json field for more details") + { + curr_page = increment(curr_page)?; + continue 'outer; + } + + // else, if set getter, we prob. want to panic let mut gql_vars_lock = gql_vars.lock().unwrap(); *gql_vars_lock = gql_vars_lock.update(); } @@ -95,7 +117,7 @@ where } if execute(curr_page, result)? { - break; + break 'outer; } else { curr_page = increment(curr_page)?; } diff --git a/lib/src/game.rs b/lib/src/game.rs index 169f69f..b2247d2 100644 --- a/lib/src/game.rs +++ b/lib/src/game.rs @@ -5,6 +5,7 @@ pub fn maybe_get_games_from_set( player_id: i32, requester_entrant_id: i32, s: &SGGSet, + sid: i32, ) -> Option> { s.clone().games.map(|gs| { gs.iter() @@ -33,6 +34,7 @@ pub fn maybe_get_games_from_set( rcp_num, ocp_num, g.stage.as_ref().map(|se| se.name.clone()), + sid, ) }) .collect::>() diff --git a/lib/src/player.rs b/lib/src/player.rs index 1a67975..ff75be6 100644 --- a/lib/src/player.rs +++ b/lib/src/player.rs @@ -236,22 +236,26 @@ where tracing::info!("🏁 finished compiling results for this player!"); Ok(true) } else { - tracing::info!("✅ got some results..."); for s in ss { - tracing::info!( - "🍥 processing set from tourney \"{}\"", - s.event.tournament.clone().unwrap().name - ); - // we only want to compile results for: double elimination single ssbu brackets - if is_ssbu_singles_double_elimination_tournament(&s) && s.completedAt.is_some() { + if is_ssbu_singles_double_elimination_tournament(&s) + && s.completedAt.is_some() + && s.event.standings.is_some() + && s.event.standings.as_ref().unwrap().nodes.len() > 1 + { + tracing::info!( + "🍥 processing set from tourney \"{}\"", + s.event.tournament.clone().unwrap().name + ); + let requester_entrant_id = if is_tournament_finished(&s) { get_requester_id_from_standings(&s, player.id) } else { continue; }; - let maybe_games = maybe_get_games_from_set(player.id, requester_entrant_id, &s); + let maybe_games = + maybe_get_games_from_set(player.id, requester_entrant_id, &s, s.id); // if there are games, we want to add to the vec to insert in the DB at the end if let Some(mut games) = maybe_games.clone() { @@ -292,7 +296,6 @@ where s.event.isOnline.unwrap(), s.event.id.unwrap(), s.event.tournament.as_ref().unwrap().id, - maybe_games.clone(), r.entrant.as_ref().unwrap().name.as_ref().unwrap(), r.standing .as_ref() @@ -323,7 +326,7 @@ where s.event.id.unwrap(), s.event.name.as_ref().unwrap(), &s.event.tournament.as_ref().unwrap().name, - s.event.tournament.as_ref().unwrap().endAt, + s.event.tournament.as_ref().unwrap().endAt.unwrap(), player.id, get_placement(&s, player.id), s.event.numEntrants.unwrap(), @@ -341,19 +344,40 @@ where } // ^^^ unwrapping in these instances is fine due to the query context that we are in, if an error occurs, // we want to panic regardless + else { + tracing::info!( + "🚫 skipping set from tourney \"{}\"", + s.event.tournament.as_ref().unwrap().name + ); + continue; + } + } + + for g in curated_games { + let res = insert_into(player_games).values(g).execute(&db_connection); + + if let Err(e) = res { + tracing::error!("🚨 error inserting game into db: {}", e); + } } - insert_into(player_games) - .values(curated_games) - .execute(&db_connection)?; + for s in curated_sets { + let res = insert_into(player_sets).values(s).execute(&db_connection); + + if let Err(e) = res { + tracing::error!("🚨 error inserting set into db: {}", e); + } + } - insert_into(player_sets) - .values(curated_sets) - .execute(&db_connection)?; + for t in curated_tournaments { + let res = insert_into(player_tournaments) + .values(t) + .execute(&db_connection); - insert_into(player_tournaments) - .values(curated_tournaments) - .execute(&db_connection)?; + if let Err(e) = res { + tracing::error!("🚨 error inserting tournament into db: {}", e); + } + } Ok(false) } diff --git a/lib/src/tournament.rs b/lib/src/tournament.rs index f826840..20307cc 100644 --- a/lib/src/tournament.rs +++ b/lib/src/tournament.rs @@ -16,7 +16,8 @@ use crate::{ }; pub fn is_tournament_finished(s: &SGGSet) -> bool { - s.event.tournament.as_ref().unwrap().endAt <= chrono::Utc::now().timestamp() + let e_at = s.event.tournament.as_ref().unwrap().endAt; + e_at.is_some() && (e_at.unwrap() <= chrono::Utc::now().timestamp()) } fn get_standing_of_player_from_sggset(s: &SGGSet, player_id: i32) -> Standing { @@ -80,7 +81,8 @@ pub async fn get_tournaments_from_requester_id(rid: i32) -> Result bool { s.event.videogame.as_ref().unwrap().name == "Super Smash Bros. Ultimate" - && s.phaseGroup.bracketType == "DOUBLE_ELIMINATION" + && s.phaseGroup.is_some() + && s.phaseGroup.clone().unwrap().bracketType == "DOUBLE_ELIMINATION" && s.event.teamRosterSize.is_none() } @@ -128,14 +130,15 @@ pub fn is_tournament_cached(player_id: i32, s: &SGGSet) -> Result { #[cfg(test)] mod tests { use anyhow::Result; - use tracing_test::traced_test; - const DANTOTTO_PLAYER_ID: i32 = 1178271; + use crate::common::init_logger; + + const HUNGRYBOX_PLAYER_ID: i32 = 1004; - #[traced_test] #[tokio::test] async fn get_tournaments_from_requester_id_test() -> Result<()> { - let _ = super::get_tournaments_from_requester_id(DANTOTTO_PLAYER_ID).await?; + init_logger()?; + let _ = super::get_tournaments_from_requester_id(HUNGRYBOX_PLAYER_ID).await?; Ok(()) } } diff --git a/src/bin/pidgtm.rs b/src/bin/pidgtm.rs index 9fdd4a6..7f6563a 100644 --- a/src/bin/pidgtm.rs +++ b/src/bin/pidgtm.rs @@ -2,11 +2,10 @@ use std::env; use anyhow::Result; use clap::{Parser, Subcommand}; +use smithe_lib::common::init_logger; use smithereens::pidgtm::{ compile::handle_compile, inspect::handle_inspect, map::handle_map, update::handle_update, }; -use tracing::Level; -use tracing_subscriber::FmtSubscriber; /// pidgtm stands for "player id to gamer tag mapper". This is a CLI that allows /// direct user access to the engine that powers searching players by name. @@ -43,11 +42,7 @@ enum Commands { #[tokio::main] async fn main() -> Result<()> { - let subscriber = FmtSubscriber::builder() - .with_max_level(Level::INFO) - .finish(); - - tracing::subscriber::set_global_default(subscriber)?; + init_logger()?; let cli = Cli::parse(); diff --git a/src/bin/smithe.rs b/src/bin/smithe.rs index 4c3dc4e..47add82 100644 --- a/src/bin/smithe.rs +++ b/src/bin/smithe.rs @@ -1,7 +1,6 @@ use anyhow::Result; +use smithe_lib::common::init_logger; use std::str::FromStr; -use tracing::Level; -use tracing_subscriber::FmtSubscriber; use clap::{Parser, Subcommand}; use smithereens::smithe::{event::handle_event, player::handle_player}; @@ -32,11 +31,8 @@ enum Commands { #[tokio::main] async fn main() -> Result<()> { - let subscriber = FmtSubscriber::builder() - .with_max_level(Level::INFO) - .finish(); + init_logger()?; - tracing::subscriber::set_global_default(subscriber)?; let cli = Cli::parse(); match &cli.command { diff --git a/startgg_api/src/lib.rs b/startgg_api/src/lib.rs index cff1a35..1217c9d 100644 --- a/startgg_api/src/lib.rs +++ b/startgg_api/src/lib.rs @@ -100,7 +100,7 @@ pub struct SetConnection { pub struct Tournament { pub id: i32, pub name: String, - pub endAt: i64, + pub endAt: Option, } #[derive(Debug, Clone, Deserialize)] @@ -109,7 +109,7 @@ pub struct Set { pub games: Option>, pub slots: Vec, pub completedAt: Option, - pub phaseGroup: PhaseGroup, + pub phaseGroup: Option, pub event: Event, }