team list

This commit is contained in:
Robin Appelman 2023-11-18 21:53:17 +01:00
commit 202917c318
12 changed files with 128772 additions and 5 deletions

View file

@ -3,10 +3,10 @@ mod error;
#[doc(hidden)]
pub mod parser;
use crate::data::{MembershipHistory, Player, RosterHistory, Seasons, Team, TeamSeason};
use crate::data::{MembershipHistory, Player, RosterHistory, Seasons, Team, TeamRef, TeamSeason};
use crate::parser::{
Parser, PlayerDetailsParser, PlayerParser, SeasonsParser, TeamMatchesParser, TeamParser,
TeamRosterHistoryParser,
Parser, PlayerDetailsParser, PlayerParser, SeasonsParser, TeamLookupParser, TeamMatchesParser,
TeamParser, TeamRosterHistoryParser,
};
pub use error::*;
use reqwest::redirect::Policy;
@ -24,6 +24,7 @@ pub struct UgcClient {
team_roster_history_parser: TeamRosterHistoryParser,
team_matches_parser: TeamMatchesParser,
seasons_parser: SeasonsParser,
team_lookup_parser: TeamLookupParser,
}
/// "API client" for ugc by scraping the website
@ -37,6 +38,7 @@ impl UgcClient {
team_roster_history_parser: TeamRosterHistoryParser::new(),
team_matches_parser: TeamMatchesParser::new(),
seasons_parser: SeasonsParser::new(),
team_lookup_parser: TeamLookupParser::new(),
}
}
@ -130,4 +132,33 @@ impl UgcClient {
.await?;
self.seasons_parser.parse(&body)
}
async fn teams(&self, link: &str) -> Result<Vec<TeamRef>> {
let body = self.client.get(link).send().await?.text().await?;
self.team_lookup_parser.parse(&body)
}
/// Get a list of all 9v9 teams
pub async fn teams_9v9(&self) -> Result<Vec<TeamRef>> {
self.teams("https://www.ugcleague.com/team_lookup_tf2h.cfm")
.await
}
/// Get a list of all 6v6 teams
pub async fn teams_6v6(&self) -> Result<Vec<TeamRef>> {
self.teams("https://www.ugcleague.com/team_lookup_tf26.cfm")
.await
}
/// Get a list of all 4v4 teams
pub async fn teams_4v4(&self) -> Result<Vec<TeamRef>> {
self.teams("https://www.ugcleague.com/team_lookup_tf24.cfm")
.await
}
/// Get a list of all 2v2 teams
pub async fn teams_2v2(&self) -> Result<Vec<TeamRef>> {
self.teams("https://www.ugcleague.com/team_lookup_tf22.cfm")
.await
}
}

View file

@ -8,6 +8,7 @@ mod player;
mod player_details;
mod seasons;
mod team;
mod team_lookup;
mod team_matches;
mod team_roster_history;
@ -15,6 +16,7 @@ pub use player::*;
pub use player_details::*;
pub use seasons::*;
pub use team::*;
pub use team_lookup::*;
pub use team_matches::*;
pub use team_roster_history::*;

65
src/parser/team_lookup.rs Normal file
View file

@ -0,0 +1,65 @@
use super::Parser;
use crate::data::TeamRef;
use crate::parser::{team_id_from_link, ElementExt};
use crate::{ParseError, Result};
use scraper::{Html, Selector};
const SELECTOR_SELECT: &str = "select[name=\"clan_select\"]";
const SELECTOR_OPTION: &str = "option[value^=\"team_page\"]";
pub struct TeamLookupParser {
selector_select: Selector,
selector_option: Selector,
}
impl Default for TeamLookupParser {
fn default() -> Self {
Self::new()
}
}
impl TeamLookupParser {
pub fn new() -> Self {
TeamLookupParser {
selector_select: Selector::parse(SELECTOR_SELECT).unwrap(),
selector_option: Selector::parse(SELECTOR_OPTION).unwrap(),
}
}
}
impl Parser for TeamLookupParser {
type Output = Vec<TeamRef>;
fn parse(&self, document: &str) -> Result<Self::Output> {
let document = Html::parse_document(document);
let select =
document
.select(&self.selector_select)
.next()
.ok_or(ParseError::ElementNotFound {
selector: SELECTOR_SELECT,
role: "team list",
})?;
select
.select(&self.selector_option)
.map(|option| {
let link = option.attr("value").ok_or(ParseError::EmptyText {
role: "team link",
selector: SELECTOR_OPTION,
})?;
let text = option.first_text().ok_or(ParseError::EmptyText {
role: "team name",
selector: SELECTOR_OPTION,
})?;
let (_, name) = text.split_once("-").unwrap_or_default();
let id = team_id_from_link(link)?;
Ok(TeamRef {
id,
name: name.trim().to_string(),
})
})
.collect()
}
}