From 215f9220201700fc6eb008c047bcf9495dd64a88 Mon Sep 17 00:00:00 2001 From: nyyu Date: Sat, 13 Mar 2021 23:02:26 +0100 Subject: [PATCH] Initilization new impl CGG --- src/cgg_data_source.rs | 162 +++++++++++++++++++---------------------- src/data_source.rs | 16 ++-- src/kb_data_source.rs | 8 +- src/main.rs | 34 ++++++--- src/pb_data_source.rs | 3 +- 5 files changed, 114 insertions(+), 109 deletions(-) diff --git a/src/cgg_data_source.rs b/src/cgg_data_source.rs index b0af9f9..c27b943 100644 --- a/src/cgg_data_source.rs +++ b/src/cgg_data_source.rs @@ -1,31 +1,54 @@ use indexmap::IndexMap; use lazy_static::lazy_static; use regex::Regex; -use select::document::Document; -use select::predicate::{Class, Name}; +use serde_derive::Deserialize; use serde_json::{json, Value}; use crate::data_source::DataSource; +use crate::ChampInfo; -const CONSUMABLES: [u32; 9] = [2003, 2004, 2055, 2031, 2032, 2033, 2138, 2140, 2139]; -const TRINKETS: [u32; 3] = [3340, 3364, 3363]; -const ITEM_TYPES: & [(&str, [&str; 2]); 4] = &[ - ("Most Frequent Starters", ["firstItems", "mostGames"]), - ( - "Highest Win % Starters", - ["firstItems", "highestWinPercent"], - ), - ("Most Frequent Core Build", ["items", "mostGames"]), - ("Highest Win % Core Build", ["items", "highestWinPercent"]), -]; + +#[derive(Deserialize, Debug)] +struct BuildResponse { + lol: Lol +} + +#[derive(Deserialize, Debug)] +struct Lol { + #[serde(rename = "championsReport")] + champions_report: Vec +} + +#[derive(Deserialize, Debug)] +struct ChampionReport { + champion_id: u32, + role: String, + patch: String, + stats: Stats +} + +#[derive(Deserialize, Debug)] +struct Stats { + starting_items: Build, + core_builds: Build +} + +#[derive(Deserialize, Debug)] +struct Build { + build: Vec, + win_rate: f64, + games: u32 +} + +static mut CHAMPIONS_REPORT: Vec = Vec::new(); pub struct CGGDataSource; impl CGGDataSource { - fn make_item_set(&self, data: &Value, label: &str) -> Value { + fn make_item_set(&self, build: &Build, label: &str) -> Value { json!({ - "items": data["items"].as_array().unwrap().iter().map(|x| json!({"id": x["id"].as_str(), "count": 1})).collect::>(), - "type": format!("{} ({:.2}% - {} games)", label, data["winPercent"].as_f64().unwrap() * 100., data["games"].as_u64().unwrap()) + "items": build.build.iter().map(|x| json!({"id": x, "count": 1})).collect::>(), + "type": format!("{} ({:.2}% - {} games)", label, build.win_rate * 100., build.games) }) } @@ -67,96 +90,59 @@ impl DataSource for CGGDataSource { &self, client: &ureq::Agent, ) -> (IndexMap>, String) { - let page = client + let req = client .get("https://champion.gg") .call() - .unwrap() - .into_string() .unwrap(); - let document = Document::from(&*page); - let patch = document - .find(Class("analysis-holder")) - .next() - .unwrap() - .find(Name("strong")) - .next() - .unwrap() - .text(); + lazy_static! { + static ref RE: Regex = + Regex::new(r"(?m)^\s+window.__PRELOADED_STATE__ = (.*);$").unwrap(); + } + + let datas: BuildResponse = + serde_json::from_str(&RE.captures(&req.into_string().unwrap()).unwrap()[1].replace("undefined", "null")).unwrap(); + + let patch = String::from(datas.lol.champions_report[0].patch.as_str()); let mut champions = IndexMap::new(); - for node in document.find(Class("champ-height")) { - let id = node - .find(Class("home-champion")) - .next() - .unwrap() - .attr("class") - .unwrap() - .split(' ') - .last() - .unwrap() - .to_string(); - let positions = node - .find(Name("a")) - .skip(1) - .map(|x| { - x.attr("href") - .unwrap() - .split('/') - .last() - .unwrap() - .to_string() - }) - .collect(); + for champ in &datas.lol.champions_report { + let id = champ.champion_id.to_string(); + let positions = [String::from(&champ.role)].to_vec(); champions.insert(id, positions); } + unsafe { + CHAMPIONS_REPORT = datas.lol.champions_report; + } + (champions, patch) } fn get_champ_data_with_win_pourcentage( &self, - id: &str, + champ: &ChampInfo, position: &str, - client: &ureq::Agent, + _client: &ureq::Agent, ) -> Option<(Vec, f64)> { - let req = client - .get(&format!( - "https://champion.gg/champion/{}/{}?league=", - id, position - )) - .call() - .unwrap(); - let response_status = req.status(); - if (200..300).contains(&response_status) { - lazy_static! { - static ref RE: Regex = - Regex::new(r"(?m)^\s+matchupData\.championData = (.*)$").unwrap(); - } - let data: Value = - serde_json::from_str(&RE.captures(&req.into_string().unwrap())?[1]).unwrap(); - let mut blocks = vec![]; - for (label, path) in ITEM_TYPES.iter() { - if data[&path[0]].get(&path[1]).is_some() { - blocks.push(self.make_item_set(&data[&path[0]][&path[1]], label)); + + let mut some_champ: Option<&ChampionReport> = None; + unsafe { + for champion in &CHAMPIONS_REPORT { + if champion.champion_id.to_string() == champ.key && champion.role == position { + some_champ = Some(champion); } } - - blocks.push(self.make_item_set_from_list( - &CONSUMABLES.to_vec(), - "Consumables | Frequent:", - "mostGames", - &data, - )); - blocks.push(self.make_item_set_from_list( - &TRINKETS.to_vec(), - "Trinkets | Wins:", - "highestWinPercent", - &data, - )); - Some((blocks, data["stats"]["winRate"].as_f64().unwrap() * 100.)) - } else { - None } + if let Some(champ) = some_champ { + let mut blocks = vec![]; + + blocks.push(self.make_item_set(&champ.stats.starting_items, "Highest % Win Starting Items")); + blocks.push(self.make_item_set(&champ.stats.core_builds, "Highest % Win Core Build Path:")); + + return Some((blocks, 42.0)); + } + + None } } diff --git a/src/data_source.rs b/src/data_source.rs index 6ae1f2f..4a0fcff 100644 --- a/src/data_source.rs +++ b/src/data_source.rs @@ -4,6 +4,7 @@ use serde_derive::{Deserialize, Serialize}; use serde_json::Value; use std::fs; use std::path::PathBuf; +use crate::ChampInfo; #[derive(Serialize, Deserialize)] struct ItemSet { @@ -40,22 +41,21 @@ pub trait DataSource { fn get_champ_data_with_win_pourcentage( &self, - id: &str, + champ: &ChampInfo, position: &str, client: &ureq::Agent, ) -> Option<(Vec, f64)>; fn write_item_set( &self, - id: &str, - name: &str, + champ: &ChampInfo, pos: &str, ver: &str, path: &PathBuf, client: &ureq::Agent, ) { - info!("Retrieving data for {} at {}", name, pos); - let data = self.get_champ_data_with_win_pourcentage(id, pos, client); + info!("Retrieving data for {} at {}", champ.name, pos); + let data = self.get_champ_data_with_win_pourcentage(champ, pos, client); match data { Some(data) => { @@ -69,15 +69,15 @@ pub trait DataSource { blocks: data.0, }; - info!("Writing item set for {} at {}", name, pos); + info!("Writing item set for {} at {}", champ.name, pos); fs::write( - path.join(format!("{}_{}_{}.json", self.get_alias(), id, pos)), + path.join(format!("{}_{}_{}.json", self.get_alias(), champ.id, pos)), serde_json::to_string_pretty(&item_set).unwrap(), ) .unwrap(); } None => { - error!("Can't get data for {} at {}", id, pos); + error!("Can't get data for {} at {}", champ.id, pos); } } } diff --git a/src/kb_data_source.rs b/src/kb_data_source.rs index 6acad79..6bc2c20 100644 --- a/src/kb_data_source.rs +++ b/src/kb_data_source.rs @@ -5,6 +5,7 @@ use indexmap::IndexMap; use regex::Regex; use serde_derive::Deserialize; use serde_json::{json, Value}; +use crate::ChampInfo; pub struct KBDataSource { token: Option, @@ -203,7 +204,7 @@ impl DataSource for KBDataSource { fn get_champ_data_with_win_pourcentage( &self, - id: &str, + champ: &ChampInfo, position: &str, client: &ureq::Agent, ) -> Option<(Vec, f64)> { @@ -211,7 +212,7 @@ impl DataSource for KBDataSource { Some(t) => t, None => return None, }; - let map_id = match self.internal_classname_mapping.get(id) { + let map_id = match self.internal_classname_mapping.get(&champ.id) { Some(m_id) => m_id, None => return None, }; @@ -375,7 +376,8 @@ mod tests { .timeout(Duration::from_secs(10)) .build(); let datasource = KBDataSource::new(&client); - let result = datasource.get_champ_data_with_win_pourcentage("Aatrox", "TOP", &client); + let champ = ChampInfo{id: String::from("Aatrox"), name: String::from("Aatrox"), key: String::from("1")}; + let result = datasource.get_champ_data_with_win_pourcentage(&champ, "TOP", &client); assert!(result.is_some()); match result { Some(value) => { diff --git a/src/main.rs b/src/main.rs index 92f6610..d3f559e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ mod data_source; mod kb_data_source; mod pb_data_source; -// use cgg_data_source::CGGDataSource; +use cgg_data_source::CGGDataSource; use data_source::DataSource; use kb_data_source::KBDataSource; use pb_data_source::PBDataSource; @@ -32,13 +32,15 @@ struct Champion { } #[derive(Deserialize)] -struct ChampInfo { +pub struct ChampInfo { + id: String, name: String, + key: String } const USER_AGENT_KEY: &str = "User-Agent"; const USER_AGENT_VALUE: &str = - "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0"; + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0"; const LOL_CHAMPS_DIR: &str = ".\\champs"; fn main() { @@ -81,9 +83,9 @@ fn main() { .unwrap(); info!("LoL numbers of champs: {}", champion.data.len()); - let data_sources: [Box; 2] = [ + let data_sources: [Box; 3] = [ Box::new(PBDataSource), - // Box::new(CGGDataSource), + Box::new(CGGDataSource), Box::new(KBDataSource::new(&client)), ]; @@ -98,13 +100,18 @@ fn main() { ); for (id, positions) in &champs { - if champion.data.contains_key(id) { - let path = lol_champs_dir.join(&id).join("Recommended"); + let mut champ_id: String = String::from(id); + + if !champion.data.contains_key(&champ_id) { + champ_id = get_champ_from_key(&champion, &champ_id); + } + + if champion.data.contains_key(&champ_id) { + let path = lol_champs_dir.join(&champ_id).join("Recommended"); fs::create_dir_all(&path).unwrap(); for pos in positions { data_source.write_item_set( - &id, - &champion.data.get(id).unwrap().name, + &champion.data.get(&champ_id).unwrap(), &pos, &patch, &path, @@ -119,6 +126,15 @@ fn main() { } } +fn get_champ_from_key(champs: &Champion, key: &String) -> String { + for champ in champs.data.values() { + if key == &champ.key { + return champ.id.clone(); + } + } + String::new() +} + #[cfg(target_os = "windows")] fn lol_champ_dir() -> Result { let hklm = RegKey::predef(winreg::enums::HKEY_LOCAL_MACHINE); diff --git a/src/pb_data_source.rs b/src/pb_data_source.rs index 83400c0..d24632e 100644 --- a/src/pb_data_source.rs +++ b/src/pb_data_source.rs @@ -2,6 +2,7 @@ use indexmap::IndexMap; use serde_json::Value; use crate::data_source::DataSource; +use crate::ChampInfo; pub struct PBDataSource; impl DataSource for PBDataSource { @@ -18,7 +19,7 @@ impl DataSource for PBDataSource { fn get_champ_data_with_win_pourcentage( &self, - _id: &str, + _champ: &ChampInfo, _position: &str, _client: &ureq::Agent, ) -> Option<(Vec, f64)> {