KB: get all positions in one time
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
nyyu 2021-03-15 23:00:20 +01:00
parent 03e0d13ed2
commit 02823b6c3c
5 changed files with 282 additions and 230 deletions

View file

@ -146,63 +146,70 @@ impl DataSource for CGGDataSource {
fn get_champ_data_with_win_pourcentage(
&self,
champ: &ChampInfo,
position: &str,
positions: &Vec<String>,
_client: &ureq::Agent,
) -> Option<(Vec<Value>, Stat)> {
let mut some_champ: Option<&ChampionReport> = None;
let reports = CHAMPIONS_REPORT.lock().unwrap();
for champion in reports.iter() {
if champion.champion_id.to_string() == champ.key && champion.role == position {
some_champ = Some(champion);
break;
}
}
if let Some(champ) = some_champ {
let mut blocks = vec![];
blocks.push(self.make_item_set_from_list(
&champ.stats.starting_items,
"Highest % Win Starting Items | Skills: ",
&champ.stats.skills,
));
blocks.push(
self.make_item_set(&champ.stats.core_builds, "Highest % Win Core Build Path:"),
);
blocks
.push(self.make_item_set(&champ.stats.big_item_builds, "Highest % Win Big Items:"));
blocks.push(self.make_item_set_from_list(
&champ.stats.most_common_starting_items,
"Most Frequent Starting Items | Skills: ",
&champ.stats.most_common_skills,
));
blocks.push(self.make_item_set(
&champ.stats.most_common_core_builds,
"Most Frequent Build Path",
));
blocks.push(self.make_item_set(
&champ.stats.most_common_big_item_builds,
"Most Frequent Big Items:",
));
let mut key: String = String::new();
let champs_stats = CHAMPIONS_STATS.lock().unwrap();
for val in champs_stats.values() {
if val.champion_id.is_some() && val.champion_id.unwrap() == champ.champion_id {
key = val.stats.as_ref().unwrap().id.to_owned();
) -> Vec<(String, Vec<Value>, Stat)> {
let mut data = vec![];
for position in positions {
let mut some_champ: Option<&ChampionReport> = None;
let reports = CHAMPIONS_REPORT.lock().unwrap();
for champion in reports.iter() {
if champion.champion_id.to_string() == champ.key
&& champion.role == position.to_owned()
{
some_champ = Some(champion);
break;
}
}
if let Some(champ) = some_champ {
let mut blocks = vec![];
let stat = champs_stats.get(&key).unwrap();
return Some((
blocks,
Stat {
win_rate: stat.win_rate.unwrap(),
games: stat.games.unwrap(),
kda: stat.kda.unwrap(),
},
));
blocks.push(self.make_item_set_from_list(
&champ.stats.starting_items,
"Highest % Win Starting Items | Skills: ",
&champ.stats.skills,
));
blocks.push(
self.make_item_set(&champ.stats.core_builds, "Highest % Win Core Build Path:"),
);
blocks.push(
self.make_item_set(&champ.stats.big_item_builds, "Highest % Win Big Items:"),
);
blocks.push(self.make_item_set_from_list(
&champ.stats.most_common_starting_items,
"Most Frequent Starting Items | Skills: ",
&champ.stats.most_common_skills,
));
blocks.push(self.make_item_set(
&champ.stats.most_common_core_builds,
"Most Frequent Build Path",
));
blocks.push(self.make_item_set(
&champ.stats.most_common_big_item_builds,
"Most Frequent Big Items:",
));
let mut key: String = String::new();
let champs_stats = CHAMPIONS_STATS.lock().unwrap();
for val in champs_stats.values() {
if val.champion_id.is_some() && val.champion_id.unwrap() == champ.champion_id {
key = val.stats.as_ref().unwrap().id.to_owned();
}
}
let stat = champs_stats.get(&key).unwrap();
data.push((
position.to_owned(),
blocks,
Stat {
win_rate: stat.win_rate.unwrap(),
games: stat.games.unwrap(),
kda: stat.kda.unwrap(),
},
));
}
}
None
data
}
}

View file

@ -50,43 +50,79 @@ pub trait DataSource {
fn get_champ_data_with_win_pourcentage(
&self,
champ: &ChampInfo,
position: &str,
positions: &Vec<String>,
client: &ureq::Agent,
) -> Option<(Vec<Value>, Stat)>;
) -> Vec<(String, Vec<Value>, Stat)>;
fn write_item_set(
&self,
champ: &ChampInfo,
pos: &str,
positions: &Vec<String>,
ver: &str,
path: &PathBuf,
client: &ureq::Agent,
) {
info!("{}: Retrieving data for {} at {}", self.get_alias(), champ.name, pos);
let data = self.get_champ_data_with_win_pourcentage(champ, pos, client);
info!(
"{}: Retrieving data for {} at {}",
self.get_alias(),
champ.name,
positions.join(", ")
);
let data = self.get_champ_data_with_win_pourcentage(champ, positions, client);
match data {
Some(data) => {
let item_set = ItemSet {
title: format!("{} {} {} - {:.2}% wins - {} games - {:.2} kda", self.get_alias(), pos, ver, data.1.win_rate, data.1.games, data.1.kda),
type_: "custom".to_string(),
map: "any".to_string(),
mode: "any".to_string(),
priority: false,
sortrank: 0,
blocks: data.0,
};
for pos in positions {
let mut ok = false;
for build in &data {
if build.0 == pos.to_owned() {
ok = true;
break;
}
}
if !ok {
error!(
"{}: Can't get data for {} at {}",
self.get_alias(),
champ.id,
pos
);
}
}
info!("{}: Writing item set for {} at {}", self.get_alias(), champ.name, pos);
fs::write(
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 {}", self.get_alias(), champ.id, pos);
}
for build in data {
let item_set = ItemSet {
title: format!(
"{} {} {} - {:.2}% wins - {} games - {:.2} kda",
self.get_alias(),
build.0,
ver,
build.2.win_rate,
build.2.games,
build.2.kda
),
type_: "custom".to_string(),
map: "any".to_string(),
mode: "any".to_string(),
priority: false,
sortrank: 0,
blocks: build.1,
};
info!(
"{}: Writing item set for {} at {}",
self.get_alias(),
champ.name,
build.0
);
fs::write(
path.join(format!(
"{}_{}_{}.json",
self.get_alias(),
champ.id,
build.0
)),
serde_json::to_string_pretty(&item_set).unwrap(),
)
.unwrap();
}
}
}

View file

@ -51,6 +51,7 @@ struct BuildResponse {
#[derive(Deserialize, Debug)]
struct KBBuild {
position: String,
item0: KBItem,
item1: KBItem,
item2: KBItem,
@ -175,6 +176,111 @@ impl KBDataSource {
}
positions
}
fn get_build(&self, build: &KBBuild) -> (String, Vec<Value>, Stat) {
let mut starting_items: Vec<Item> = vec![];
let mut blocks = vec![];
if build.start_item0.item_id != 0 {
starting_items.push(Item {
id: build.start_item0.item_id.to_string(),
count: 1,
})
}
if build.start_item1.item_id != 0 {
starting_items.push(Item {
id: build.start_item1.item_id.to_string(),
count: 1,
})
}
if build.start_item2.item_id != 0 {
starting_items.push(Item {
id: build.start_item2.item_id.to_string(),
count: 1,
})
}
if build.start_item3.item_id != 0 {
starting_items.push(Item {
id: build.start_item3.item_id.to_string(),
count: 1,
})
}
if build.start_item4.item_id != 0 {
starting_items.push(Item {
id: build.start_item4.item_id.to_string(),
count: 1,
})
}
if build.start_item5.item_id != 0 {
starting_items.push(Item {
id: build.start_item5.item_id.to_string(),
count: 1,
})
}
blocks.push(json!(Build {
type_: format!("Early game items | skillOrder : {}", build.skill_order),
items: starting_items
}));
let mut final_items: Vec<Item> = vec![];
if build.item0.item_id != 0 {
final_items.push(Item {
id: build.item0.item_id.to_string(),
count: 1,
})
}
if build.item1.item_id != 0 {
final_items.push(Item {
id: build.item1.item_id.to_string(),
count: 1,
})
}
if build.item2.item_id != 0 {
final_items.push(Item {
id: build.item2.item_id.to_string(),
count: 1,
})
}
if build.item3.item_id != 0 {
final_items.push(Item {
id: build.item3.item_id.to_string(),
count: 1,
})
}
if build.item4.item_id != 0 {
final_items.push(Item {
id: build.item4.item_id.to_string(),
count: 1,
})
}
if build.item5.item_id != 0 {
final_items.push(Item {
id: build.item5.item_id.to_string(),
count: 1,
})
}
if build.item6.item_id != 0 {
final_items.push(Item {
id: build.item6.item_id.to_string(),
count: 1,
})
}
blocks.push(json!(Build {
type_: format!(
"Item order by time finished | Summoner : {}",
build.summoner.name
),
items: final_items
}));
(
build.position.to_owned().to_uppercase(),
blocks,
Stat {
win_rate: (build.wins / build.games) * 100.,
games: build.games as u32,
kda: 0.0,
},
)
}
}
impl DataSource for KBDataSource {
@ -210,145 +316,51 @@ impl DataSource for KBDataSource {
fn get_champ_data_with_win_pourcentage(
&self,
champ: &ChampInfo,
position: &str,
position: &Vec<String>,
client: &ureq::Agent,
) -> Option<(Vec<Value>, Stat)> {
let token = match self.token.clone() {
Some(t) => t,
None => return None,
};
let map_id = match self.internal_classname_mapping.get(&champ.id) {
Some(m_id) => m_id,
None => return None,
};
let data: BuildResponse = match client
.get(&format!(
"https://api.koreanbuilds.net/builds?chmpname={}&patchid=-2&position={}",
map_id, position
))
.set("Accept", "application/json")
.set("Authorization", token.as_str())
.call()
{
Ok(resp) => match resp.into_json() {
Ok(val) => val,
Err(_) => {
return None;
) -> 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) {
let data: BuildResponse = match client
.get(&format!(
"https://api.koreanbuilds.net/builds?chmpname={}&patchid=-2&position=COMPOSITE",
map_id
))
.set("Accept", "application/json")
.set("Authorization", token.as_str())
.call()
{
Ok(resp) => match resp.into_json() {
Ok(val) => val,
Err(_) => {
return vec![];
}
},
Err(_) => {
return vec![];
}
};
for pos in position {
let mut build: Option<&KBBuild> = None;
for b in &data.builds2 {
if b.position.to_uppercase() == pos.to_owned() {
build = Some(b);
break;
}
}
if let Some(b) = build {
champ_data.push(self.get_build(&b));
}
}
},
Err(_) => {
return None;
}
};
let mut blocks = vec![];
if !data.builds2.is_empty() {
let mut starting_items: Vec<Item> = vec![];
if data.builds2[0].start_item0.item_id != 0 {
starting_items.push(Item {
id: data.builds2[0].start_item0.item_id.to_string(),
count: 1,
})
}
if data.builds2[0].start_item1.item_id != 0 {
starting_items.push(Item {
id: data.builds2[0].start_item1.item_id.to_string(),
count: 1,
})
}
if data.builds2[0].start_item2.item_id != 0 {
starting_items.push(Item {
id: data.builds2[0].start_item2.item_id.to_string(),
count: 1,
})
}
if data.builds2[0].start_item3.item_id != 0 {
starting_items.push(Item {
id: data.builds2[0].start_item3.item_id.to_string(),
count: 1,
})
}
if data.builds2[0].start_item4.item_id != 0 {
starting_items.push(Item {
id: data.builds2[0].start_item4.item_id.to_string(),
count: 1,
})
}
if data.builds2[0].start_item5.item_id != 0 {
starting_items.push(Item {
id: data.builds2[0].start_item5.item_id.to_string(),
count: 1,
})
}
blocks.push(json!(Build {
type_: format!(
"Early game items | skillOrder : {}",
data.builds2[0].skill_order
),
items: starting_items
}));
let mut final_items: Vec<Item> = vec![];
if data.builds2[0].item0.item_id != 0 {
final_items.push(Item {
id: data.builds2[0].item0.item_id.to_string(),
count: 1,
})
}
if data.builds2[0].item1.item_id != 0 {
final_items.push(Item {
id: data.builds2[0].item1.item_id.to_string(),
count: 1,
})
}
if data.builds2[0].item2.item_id != 0 {
final_items.push(Item {
id: data.builds2[0].item2.item_id.to_string(),
count: 1,
})
}
if data.builds2[0].item3.item_id != 0 {
final_items.push(Item {
id: data.builds2[0].item3.item_id.to_string(),
count: 1,
})
}
if data.builds2[0].item4.item_id != 0 {
final_items.push(Item {
id: data.builds2[0].item4.item_id.to_string(),
count: 1,
})
}
if data.builds2[0].item5.item_id != 0 {
final_items.push(Item {
id: data.builds2[0].item5.item_id.to_string(),
count: 1,
})
}
if data.builds2[0].item6.item_id != 0 {
final_items.push(Item {
id: data.builds2[0].item6.item_id.to_string(),
count: 1,
})
}
blocks.push(json!(Build {
type_: format!(
"Item order by time finished | Summoner : {}",
data.builds2[0].summoner.name
),
items: final_items
}));
return Some((
blocks,
Stat {
win_rate: (data.builds2[0].wins / data.builds2[0].games) * 100.,
games: data.builds2[0].games as u32,
kda: 0.0,
},
));
}
None
champ_data
}
}
#[cfg(test)]
mod tests {
@ -391,14 +403,13 @@ mod tests {
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) => {
assert!(!value.0.is_empty());
assert!(value.1.win_rate > 0.);
}
None => assert!(false),
}
let result = datasource.get_champ_data_with_win_pourcentage(
&champ,
&vec!["TOP".to_string()],
&client,
);
assert!(!result.is_empty());
assert!(!result[0].1.is_empty());
assert!(result[0].2.win_rate > 0.);
}
}

View file

@ -162,7 +162,7 @@ fn execute_data_source(
&patch,
id,
positions,
)
);
});
} else {
champs.iter().for_each(|(id, positions)| {
@ -174,7 +174,8 @@ fn execute_data_source(
&patch,
id,
positions,
)
);
thread::sleep(Duration::from_millis(data_source.get_timeout()));
});
};
}
@ -202,10 +203,7 @@ fn get_and_write_item_set(
} else {
let path = lol_champs_dir.join(&champ_id).join("Recommended");
fs::create_dir_all(&path).unwrap();
positions.iter().for_each(|pos| {
data_source.write_item_set(&champ, &pos, &patch, &path, &client);
thread::sleep(Duration::from_millis(data_source.get_timeout()));
});
data_source.write_item_set(&champ, &positions, &patch, &path, &client);
}
} else {
error!("{} not found in LoL champs", &champ_id);

View file

@ -24,9 +24,9 @@ impl DataSource for PBDataSource {
fn get_champ_data_with_win_pourcentage(
&self,
_champ: &ChampInfo,
_position: &str,
_positions: &Vec<String>,
_client: &ureq::Agent,
) -> Option<(Vec<Value>, Stat)> {
None
) -> Vec<(String, Vec<Value>, Stat)> {
vec![]
}
}