CGGItemSets/src/cgg_data_source.rs

163 lines
5 KiB
Rust
Raw Normal View History

2018-06-16 10:48:46 +02:00
use indexmap::IndexMap;
use lazy_static::lazy_static;
2018-06-16 10:48:46 +02:00
use regex::Regex;
use select::document::Document;
use select::predicate::{Class, Name};
use serde_json::{json, Value};
2018-06-16 10:48:46 +02:00
2019-09-26 22:39:25 +02:00
use crate::data_source::DataSource;
2018-06-16 10:48:46 +02:00
const CONSUMABLES: [u32; 9] = [2003, 2004, 2055, 2031, 2032, 2033, 2138, 2140, 2139];
const TRINKETS: [u32; 3] = [3340, 3364, 3363];
const ITEM_TYPES: &'static [(&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"]),
];
2018-06-16 10:48:46 +02:00
pub struct CGGDataSource;
impl CGGDataSource {
fn make_item_set(&self, data: &Value, label: &str) -> Value {
json!({
"items": data["items"].as_array().unwrap().iter().map(|x| json!({"id": x["id"].as_str(), "count": 1})).collect::<Vec<Value>>(),
"type": format!("{} ({:.2}% - {} games)", label, data["winPercent"].as_f64().unwrap() * 100., data["games"].as_u64().unwrap())
})
}
fn make_item_set_from_list(
&self,
list: &Vec<u32>,
label: &str,
key: &str,
data: &Value,
) -> Value {
let mut key_order = String::new();
if !data["skills"].get("skillInfo").is_none() {
key_order = data["skills"][key]["order"]
.as_array()
.unwrap()
.iter()
.map(|x| {
data["skills"]["skillInfo"].as_array().unwrap()
[x.as_str().unwrap().parse::<usize>().unwrap() - 1]["key"]
.as_str()
.unwrap()
})
.collect::<Vec<&str>>()
.join(".");
}
json!({
"items": list.iter().map(|x| json!({"id": x.to_string(), "count": 1})).collect::<Vec<Value>>(),
"type": format!("{} {}", label, key_order)
})
}
}
2018-06-16 10:48:46 +02:00
impl DataSource for CGGDataSource {
fn get_alias(&self) -> &str {
"CGG"
}
2018-06-16 10:48:46 +02:00
fn get_champs_with_positions_and_patch(
2018-06-16 12:48:14 +02:00
&self,
2021-03-10 12:22:00 +01:00
client: &ureq::Agent,
2018-06-16 10:48:46 +02:00
) -> (IndexMap<String, Vec<String>>, String) {
let page = client
.get("https://champion.gg")
2021-03-10 12:22:00 +01:00
.call()
2018-06-16 10:48:46 +02:00
.unwrap()
2021-03-10 12:22:00 +01:00
.into_string()
2018-06-16 10:48:46 +02:00
.unwrap();
let document = Document::from(&*page);
let patch = document
.find(Class("analysis-holder"))
.next()
.unwrap()
.find(Name("strong"))
.next()
.unwrap()
.text();
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();
champions.insert(id, positions);
}
(champions, patch)
}
fn get_champ_data_with_win_pourcentage(
&self,
id: &str,
position: &str,
2021-03-10 12:22:00 +01:00
client: &ureq::Agent,
) -> Option<(Vec<Value>, f64)> {
2020-06-28 18:34:31 +02:00
let req = client
2018-06-16 10:48:46 +02:00
.get(&format!(
"https://champion.gg/champion/{}/{}?league=",
id, position
))
2021-03-10 12:22:00 +01:00
.call()
2018-06-16 10:48:46 +02:00
.unwrap();
2021-03-10 12:22:00 +01:00
let response_status = req.status();
if 300 > response_status && response_status >= 200 {
2018-06-16 10:48:46 +02:00
lazy_static! {
static ref RE: Regex =
Regex::new(r"(?m)^\s+matchupData\.championData = (.*)$").unwrap();
}
2021-03-10 12:22:00 +01:00
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_none() {
blocks.push(self.make_item_set(&data[&path[0]][&path[1]], label));
}
}
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.))
2018-06-16 10:48:46 +02:00
} else {
None
}
}
}