Merge pull request 'remove_box' (#10) from remove_box into master
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #10
This commit is contained in:
commit
d1061daf11
5 changed files with 152 additions and 185 deletions
|
@ -95,6 +95,8 @@ fn extract_json(pattern: &str, page: &str) -> String {
|
|||
}
|
||||
|
||||
impl DataSource for CGGDataSource {
|
||||
fn init(&self, _client: &ureq::Agent) {}
|
||||
|
||||
fn get_alias(&self) -> &str {
|
||||
"CGG"
|
||||
}
|
||||
|
@ -103,10 +105,10 @@ impl DataSource for CGGDataSource {
|
|||
0
|
||||
}
|
||||
|
||||
fn get_champs_with_positions_and_patch(
|
||||
fn get_champs_with_positions(
|
||||
&self,
|
||||
client: &ureq::Agent,
|
||||
) -> (IndexMap<String, Vec<String>>, String) {
|
||||
) -> IndexMap<u32, Vec<String>> {
|
||||
let req = client.get("https://champion.gg").call().unwrap();
|
||||
let page = &req.into_string().unwrap();
|
||||
|
||||
|
@ -122,11 +124,10 @@ impl DataSource for CGGDataSource {
|
|||
.unwrap()
|
||||
.insert(entry.0.to_owned(), entry.1.to_owned());
|
||||
}
|
||||
let patch = datas.lol.champions_report[0].patch.to_owned();
|
||||
|
||||
let mut champions: IndexMap<String, Vec<String>> = IndexMap::new();
|
||||
let mut champions: IndexMap<u32, Vec<String>> = IndexMap::new();
|
||||
for champ in &datas.lol.champions_report {
|
||||
let id = champ.champion_id.to_string();
|
||||
let id = champ.champion_id;
|
||||
if champions.contains_key(&id) {
|
||||
let mut roles = champions.get(&id).unwrap().to_owned();
|
||||
roles.push(champ.role.to_owned());
|
||||
|
@ -140,7 +141,7 @@ impl DataSource for CGGDataSource {
|
|||
CHAMPIONS_REPORT.lock().unwrap().push(report);
|
||||
}
|
||||
|
||||
(champions, patch)
|
||||
champions
|
||||
}
|
||||
|
||||
fn get_champ_data_with_win_pourcentage(
|
||||
|
@ -206,6 +207,7 @@ impl DataSource for CGGDataSource {
|
|||
win_rate: stat.win_rate.unwrap(),
|
||||
games: stat.games.unwrap(),
|
||||
kda: stat.kda.unwrap(),
|
||||
patch: champ.patch.to_owned()
|
||||
},
|
||||
));
|
||||
}
|
||||
|
|
|
@ -35,17 +35,20 @@ pub struct Stat {
|
|||
pub win_rate: f64,
|
||||
pub games: u32,
|
||||
pub kda: f64,
|
||||
pub patch: String
|
||||
}
|
||||
|
||||
pub trait DataSource {
|
||||
fn init(&self, client: &ureq::Agent);
|
||||
|
||||
fn get_alias(&self) -> &str;
|
||||
|
||||
fn get_timeout(&self) -> u64;
|
||||
|
||||
fn get_champs_with_positions_and_patch(
|
||||
fn get_champs_with_positions(
|
||||
&self,
|
||||
client: &ureq::Agent,
|
||||
) -> (IndexMap<String, Vec<String>>, String);
|
||||
) -> IndexMap<u32, Vec<String>>;
|
||||
|
||||
fn get_champ_data_with_win_pourcentage(
|
||||
&self,
|
||||
|
@ -58,7 +61,6 @@ pub trait DataSource {
|
|||
&self,
|
||||
champ: &ChampInfo,
|
||||
positions: &[String],
|
||||
ver: &str,
|
||||
path: &PathBuf,
|
||||
client: &ureq::Agent,
|
||||
) {
|
||||
|
@ -98,7 +100,7 @@ pub trait DataSource {
|
|||
"{} {} {} - {:.2}% wins - {} games - {:.2} kda",
|
||||
self.get_alias(),
|
||||
build.0,
|
||||
ver,
|
||||
build.2.patch,
|
||||
build.2.win_rate,
|
||||
build.2.games,
|
||||
build.2.kda
|
||||
|
|
|
@ -3,13 +3,12 @@ use crate::data_source::{Build, DataSource, Item, Stat};
|
|||
use crate::time::Duration;
|
||||
use crate::ChampInfo;
|
||||
use indexmap::IndexMap;
|
||||
use lazy_static::lazy_static;
|
||||
use serde_derive::Deserialize;
|
||||
use serde_json::{json, Value};
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub struct KBDataSource {
|
||||
token: Option<String>,
|
||||
internal_classname_mapping: IndexMap<String, String>,
|
||||
}
|
||||
pub struct KBDataSource;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct ChampionResponse {
|
||||
|
@ -74,8 +73,9 @@ struct KBBuild {
|
|||
#[serde(rename = "skillOrder")]
|
||||
skill_order: String,
|
||||
wins: f64,
|
||||
games: f64,
|
||||
games: u32,
|
||||
summoner: Summoner,
|
||||
patch: Patch,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
|
@ -90,17 +90,11 @@ struct Summoner {
|
|||
name: String,
|
||||
}
|
||||
|
||||
impl KBDataSource {
|
||||
pub fn new(client: &ureq::Agent) -> KBDataSource {
|
||||
let mut datasource = KBDataSource {
|
||||
token: None,
|
||||
internal_classname_mapping: IndexMap::new(),
|
||||
};
|
||||
datasource.token = datasource.get_auth_token(client);
|
||||
datasource.internal_classname_mapping = datasource.get_classname_mapping(client);
|
||||
datasource
|
||||
}
|
||||
lazy_static! {
|
||||
static ref TOKEN: Mutex<Option<String>> = Mutex::new(None);
|
||||
}
|
||||
|
||||
impl KBDataSource {
|
||||
// It will be better to use Result...
|
||||
fn get_auth_token(&self, client: &ureq::Agent) -> Option<String> {
|
||||
let mut bundle = match client.get("https://koreanbuilds.net/bundle.js").call() {
|
||||
|
@ -126,22 +120,9 @@ impl KBDataSource {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_classname_mapping(&self, client: &ureq::Agent) -> IndexMap<String, String> {
|
||||
let mut mapping = IndexMap::new();
|
||||
if let Some(data) = self.get_champion_response(client) {
|
||||
for champ in data.champions {
|
||||
mapping.insert(champ.classname, champ.name);
|
||||
}
|
||||
};
|
||||
mapping
|
||||
}
|
||||
|
||||
fn get_champion_response(&self, client: &ureq::Agent) -> Option<ChampionResponse> {
|
||||
let token = match self.token.clone() {
|
||||
Some(t) => t,
|
||||
None => String::new(),
|
||||
};
|
||||
match client
|
||||
if let Some(token) = TOKEN.lock().unwrap().as_ref() {
|
||||
return match client
|
||||
.get("https://api.koreanbuilds.net/champions?patchid=-1")
|
||||
.set("Accept", "application/json")
|
||||
.set("Authorization", token.as_str())
|
||||
|
@ -152,7 +133,9 @@ impl KBDataSource {
|
|||
Err(_) => None,
|
||||
},
|
||||
Err(_) => None,
|
||||
};
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn get_positions(position: Option<Position>) -> Vec<String> {
|
||||
|
@ -285,15 +268,22 @@ impl KBDataSource {
|
|||
build.position.to_owned().to_uppercase(),
|
||||
blocks,
|
||||
Stat {
|
||||
win_rate: (build.wins / build.games) * 100.,
|
||||
games: build.games as u32,
|
||||
win_rate: (build.wins / build.games as f64) * 100.,
|
||||
games: build.games,
|
||||
kda: 0.0,
|
||||
patch: build.patch.patch_version.to_owned(),
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl DataSource for KBDataSource {
|
||||
fn init(&self, client: &ureq::Agent) {
|
||||
if let Some(t) = self.get_auth_token(client) {
|
||||
TOKEN.lock().unwrap().replace(t);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_alias(&self) -> &str {
|
||||
"KB"
|
||||
}
|
||||
|
@ -302,25 +292,18 @@ impl DataSource for KBDataSource {
|
|||
300
|
||||
}
|
||||
|
||||
fn get_champs_with_positions_and_patch(
|
||||
&self,
|
||||
client: &ureq::Agent,
|
||||
) -> (IndexMap<String, Vec<String>>, String) {
|
||||
fn get_champs_with_positions(&self, client: &ureq::Agent) -> IndexMap<u32, Vec<String>> {
|
||||
let mut champions = IndexMap::new();
|
||||
let data: ChampionResponse = match self.get_champion_response(client) {
|
||||
Some(val) => val,
|
||||
None => {
|
||||
return (champions, String::new());
|
||||
return champions;
|
||||
}
|
||||
};
|
||||
let patch = match data.patches.get(0) {
|
||||
Some(p) => p.patch_version.clone(),
|
||||
None => return (champions, String::new()),
|
||||
};
|
||||
for champ in data.champions {
|
||||
champions.insert(champ.classname, KBDataSource::get_positions(champ.builds));
|
||||
champions.insert(champ.id, KBDataSource::get_positions(champ.builds));
|
||||
}
|
||||
(champions, patch)
|
||||
champions
|
||||
}
|
||||
|
||||
fn get_champ_data_with_win_pourcentage(
|
||||
|
@ -330,12 +313,11 @@ impl DataSource for KBDataSource {
|
|||
client: &ureq::Agent,
|
||||
) -> Vec<(String, Vec<Value>, Stat)> {
|
||||
let mut champ_data = vec![];
|
||||
if let Some(token) = self.token.clone() {
|
||||
if let Some(map_id) = self.internal_classname_mapping.get(&champ.id) {
|
||||
if let Some(token) = TOKEN.lock().unwrap().as_ref() {
|
||||
let data: BuildResponse = match client
|
||||
.get(&format!(
|
||||
"https://api.koreanbuilds.net/builds?chmpname={}&patchid=-2&position=COMPOSITE",
|
||||
map_id
|
||||
champ.id
|
||||
))
|
||||
.set("Accept", "application/json")
|
||||
.set("Authorization", token.as_str())
|
||||
|
@ -362,13 +344,11 @@ impl DataSource for KBDataSource {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if let Some(b) = build {
|
||||
champ_data.push(self.get_build(&b));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
champ_data
|
||||
}
|
||||
}
|
||||
|
@ -379,10 +359,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_get_auth_token() {
|
||||
let datasource = KBDataSource {
|
||||
token: None,
|
||||
internal_classname_mapping: IndexMap::new(),
|
||||
};
|
||||
let datasource = KBDataSource;
|
||||
let client = ureq::AgentBuilder::new()
|
||||
.timeout(Duration::from_secs(10))
|
||||
.build();
|
||||
|
@ -397,10 +374,11 @@ mod tests {
|
|||
let client = ureq::AgentBuilder::new()
|
||||
.timeout(Duration::from_secs(10))
|
||||
.build();
|
||||
let datasource = KBDataSource::new(&client);
|
||||
let champs_with_positions_and_patch =
|
||||
datasource.get_champs_with_positions_and_patch(&client);
|
||||
assert!(champs_with_positions_and_patch.0.len() > 0);
|
||||
let datasource = KBDataSource;
|
||||
datasource.init(&client);
|
||||
let champs_with_positions =
|
||||
datasource.get_champs_with_positions(&client);
|
||||
assert!(champs_with_positions.len() > 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -408,15 +386,16 @@ mod tests {
|
|||
let client = ureq::AgentBuilder::new()
|
||||
.timeout(Duration::from_secs(10))
|
||||
.build();
|
||||
let datasource = KBDataSource::new(&client);
|
||||
let datasource = KBDataSource;
|
||||
datasource.init(&client);
|
||||
let champ = ChampInfo {
|
||||
id: String::from("Aatrox"),
|
||||
name: String::from("Aatrox"),
|
||||
id: String::from("Annie"),
|
||||
name: String::from("Annie"),
|
||||
key: String::from("1"),
|
||||
};
|
||||
let result = datasource.get_champ_data_with_win_pourcentage(
|
||||
&champ,
|
||||
&vec!["TOP".to_string()],
|
||||
&vec!["MID".to_string()],
|
||||
&client,
|
||||
);
|
||||
assert!(!result.is_empty());
|
||||
|
|
90
src/main.rs
90
src/main.rs
|
@ -1,5 +1,4 @@
|
|||
use indexmap::IndexMap;
|
||||
use lazy_static::lazy_static;
|
||||
#[cfg(target_os = "windows")]
|
||||
use log::debug;
|
||||
use log::{error, info, LevelFilter};
|
||||
|
@ -75,62 +74,53 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
.init()?;
|
||||
info!("CGG Item Sets");
|
||||
|
||||
lazy_static! {
|
||||
static ref LOL_CHAMPS_DIR: PathBuf = match lol_champ_dir() {
|
||||
let lol_champs_dir: PathBuf = match lol_champ_dir() {
|
||||
Ok(x) => x,
|
||||
Err(_e) => PathBuf::from(DEFAULT_LOL_CHAMPS_DIR),
|
||||
};
|
||||
static ref CLIENT: ureq::Agent = ureq::AgentBuilder::new()
|
||||
info!("LoL Champs Folder: {}", lol_champs_dir.to_str().unwrap());
|
||||
|
||||
let client: ureq::Agent = ureq::AgentBuilder::new()
|
||||
.user_agent(USER_AGENT_VALUE)
|
||||
.timeout(Duration::from_secs(10))
|
||||
.build();
|
||||
static ref REALM: Realm = CLIENT
|
||||
|
||||
let realm: Realm = client
|
||||
.get("https://ddragon.leagueoflegends.com/realms/euw.json")
|
||||
.call()
|
||||
.unwrap()
|
||||
.into_json()
|
||||
.unwrap();
|
||||
static ref CHAMPION: Champion = CLIENT
|
||||
.call()?
|
||||
.into_json()?;
|
||||
info!("LoL version: {}", realm.v);
|
||||
|
||||
let champion: Champion = client
|
||||
.get(&format!(
|
||||
"https://ddragon.leagueoflegends.com/cdn/{}/data/en_US/champion.json",
|
||||
REALM.v
|
||||
realm.v
|
||||
))
|
||||
.call()
|
||||
.unwrap()
|
||||
.into_json()
|
||||
.unwrap();
|
||||
static ref DATA_SOURCES: Vec<Box<dyn DataSource + Sync + Send>> = vec![
|
||||
Box::new(PBDataSource),
|
||||
Box::new(CGGDataSource),
|
||||
Box::new(KBDataSource::new(&CLIENT)),
|
||||
.call()?
|
||||
.into_json()?;
|
||||
info!("LoL numbers of champs: {}", champion.data.len());
|
||||
|
||||
static DATA_SOURCES: [&'static (dyn DataSource + Sync + Send); 3] = [
|
||||
&PBDataSource,
|
||||
&CGGDataSource,
|
||||
&KBDataSource,
|
||||
];
|
||||
}
|
||||
DATA_SOURCES.par_iter().for_each(|data_source| {
|
||||
|
||||
info!("LoL Champs Folder: {}", LOL_CHAMPS_DIR.to_str().unwrap());
|
||||
info!("LoL version: {}", REALM.v);
|
||||
info!("LoL numbers of champs: {}", CHAMPION.data.len());
|
||||
|
||||
let mut threads = vec![];
|
||||
for data_source in DATA_SOURCES.iter() {
|
||||
threads.push(thread::spawn(move || {
|
||||
let init = Instant::now();
|
||||
execute_data_source(&data_source, &CLIENT, &CHAMPION, &LOL_CHAMPS_DIR);
|
||||
execute_data_source(*data_source, &client, &champion, &lol_champs_dir);
|
||||
info!(
|
||||
"{}: done in {} ms",
|
||||
data_source.get_alias(),
|
||||
init.elapsed().as_millis()
|
||||
);
|
||||
}));
|
||||
}
|
||||
for child in threads {
|
||||
let _ = child.join();
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_champ_from_key(champs: &Champion, key: &str) -> Option<String> {
|
||||
fn get_champ_from_key(champs: &Champion, key: u32) -> Option<String> {
|
||||
for champ in champs.data.values() {
|
||||
if key == champ.key {
|
||||
if key.to_string() == champ.key {
|
||||
return Some(champ.id.to_owned());
|
||||
}
|
||||
}
|
||||
|
@ -138,14 +128,15 @@ fn get_champ_from_key(champs: &Champion, key: &str) -> Option<String> {
|
|||
}
|
||||
|
||||
fn execute_data_source(
|
||||
data_source: &Box<dyn DataSource + Sync + Send>,
|
||||
data_source: &(dyn DataSource + Sync + Send),
|
||||
client: &ureq::Agent,
|
||||
champion: &Champion,
|
||||
lol_champs_dir: &PathBuf,
|
||||
) {
|
||||
let (champs, patch) = data_source.get_champs_with_positions_and_patch(&client);
|
||||
data_source.init(client);
|
||||
|
||||
let champs = data_source.get_champs_with_positions(&client);
|
||||
|
||||
info!("{} version: {}", data_source.get_alias(), patch);
|
||||
info!(
|
||||
"{} numbers of champs: {}",
|
||||
data_source.get_alias(),
|
||||
|
@ -159,8 +150,7 @@ fn execute_data_source(
|
|||
client,
|
||||
champion,
|
||||
lol_champs_dir,
|
||||
&patch,
|
||||
id,
|
||||
*id,
|
||||
positions,
|
||||
);
|
||||
});
|
||||
|
@ -171,8 +161,7 @@ fn execute_data_source(
|
|||
client,
|
||||
champion,
|
||||
lol_champs_dir,
|
||||
&patch,
|
||||
id,
|
||||
*id,
|
||||
positions,
|
||||
);
|
||||
thread::sleep(Duration::from_millis(data_source.get_timeout()));
|
||||
|
@ -181,33 +170,26 @@ fn execute_data_source(
|
|||
}
|
||||
|
||||
fn get_and_write_item_set(
|
||||
data_source: &Box<dyn DataSource + Sync + Send>,
|
||||
data_source: &(dyn DataSource + Sync + Send),
|
||||
client: &ureq::Agent,
|
||||
champion: &Champion,
|
||||
lol_champs_dir: &PathBuf,
|
||||
patch: &str,
|
||||
id: &str,
|
||||
id: u32,
|
||||
positions: &[String],
|
||||
) {
|
||||
let mut champ_id: String = id.to_owned();
|
||||
|
||||
if id.parse::<u32>().is_ok() {
|
||||
if let Some(c_id) = get_champ_from_key(&champion, &champ_id) {
|
||||
champ_id = c_id;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(champ_id) = get_champ_from_key(&champion, id) {
|
||||
if let Some(champ) = champion.data.get(&champ_id) {
|
||||
if positions.is_empty() {
|
||||
error!("{}: {} empty positions", data_source.get_alias(), &champ_id);
|
||||
} else {
|
||||
let path = lol_champs_dir.join(&champ_id).join("Recommended");
|
||||
fs::create_dir_all(&path).unwrap();
|
||||
data_source.write_item_set(&champ, &positions, &patch, &path, &client);
|
||||
data_source.write_item_set(&champ, &positions, &path, &client);
|
||||
}
|
||||
} else {
|
||||
error!("{} not found in LoL champs", &champ_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
|
|
|
@ -6,6 +6,8 @@ use crate::ChampInfo;
|
|||
|
||||
pub struct PBDataSource;
|
||||
impl DataSource for PBDataSource {
|
||||
fn init(&self, _client: &ureq::Agent) {}
|
||||
|
||||
fn get_alias(&self) -> &str {
|
||||
"PB"
|
||||
}
|
||||
|
@ -14,11 +16,11 @@ impl DataSource for PBDataSource {
|
|||
0
|
||||
}
|
||||
|
||||
fn get_champs_with_positions_and_patch(
|
||||
fn get_champs_with_positions(
|
||||
&self,
|
||||
_client: &ureq::Agent,
|
||||
) -> (IndexMap<String, Vec<String>>, String) {
|
||||
(IndexMap::new(), String::new())
|
||||
) -> IndexMap<u32, Vec<String>> {
|
||||
IndexMap::new()
|
||||
}
|
||||
|
||||
fn get_champ_data_with_win_pourcentage(
|
||||
|
|
Loading…
Add table
Reference in a new issue