mirror of
https://codeberg.org/icewind/ugc-scaper.git
synced 2026-06-04 02:34:11 +02:00
add transactions
This commit is contained in:
parent
0cada6847a
commit
bd2cd8afe6
9 changed files with 2907 additions and 32 deletions
|
|
@ -12,6 +12,7 @@ mod team;
|
|||
mod team_lookup;
|
||||
mod team_matches;
|
||||
mod team_roster_history;
|
||||
mod transactions;
|
||||
|
||||
pub use match_page::*;
|
||||
pub use player::*;
|
||||
|
|
@ -21,6 +22,7 @@ pub use team::*;
|
|||
pub use team_lookup::*;
|
||||
pub use team_matches::*;
|
||||
pub use team_roster_history::*;
|
||||
pub use transactions::*;
|
||||
|
||||
pub trait Parser {
|
||||
type Output;
|
||||
|
|
@ -28,8 +30,9 @@ pub trait Parser {
|
|||
}
|
||||
|
||||
trait ElementExt<'a> {
|
||||
fn first_text(&'a self) -> Option<&'a str>;
|
||||
fn nth_text(&'a self, n: usize) -> Option<&'a str>;
|
||||
fn first_text(&self) -> Option<&'a str>;
|
||||
fn nth_text(&self, n: usize) -> Option<&'a str>;
|
||||
fn last_text(&self) -> Option<&'a str>;
|
||||
}
|
||||
|
||||
impl<'a> ElementExt<'a> for ElementRef<'a> {
|
||||
|
|
@ -42,6 +45,9 @@ impl<'a> ElementExt<'a> for ElementRef<'a> {
|
|||
.nth(n - 1)
|
||||
.map(str::trim)
|
||||
}
|
||||
fn last_text(&self) -> Option<&'a str> {
|
||||
self.text().map(str::trim).filter(|s| !s.is_empty()).last()
|
||||
}
|
||||
}
|
||||
|
||||
fn select_text<'a>(el: ElementRef<'a>, selector: &Selector) -> Option<&'a str> {
|
||||
|
|
|
|||
96
src/parser/transactions.rs
Normal file
96
src/parser/transactions.rs
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
use super::Parser;
|
||||
use crate::data::{TeamRef, Transaction};
|
||||
use crate::parser::{
|
||||
select_last_text, select_text, steam_id_from_link, team_id_from_link, ElementExt,
|
||||
};
|
||||
use crate::{ParseError, Result};
|
||||
use scraper::{Html, Selector};
|
||||
|
||||
const SELECTOR_TRANSACTION_ROW: &str = "table.table.table-condensed.table-striped tr";
|
||||
const SELECTOR_TRANSACTION_PLAYER_LINK: &str = "a[href^=\"players_page\"][title^=\"Roster\"]";
|
||||
const SELECTOR_TRANSACTION_ACTION: &str = "td:nth-child(4) span b";
|
||||
const SELECTOR_TRANSACTION_TEAM_LINK: &str = "a[href^=\"team_page\"]";
|
||||
const SELECTOR_TRANSACTION_TEAM_NAME: &str = "td:nth-child(5)";
|
||||
|
||||
pub struct TransactionParser {
|
||||
selector_row: Selector,
|
||||
selector_player: Selector,
|
||||
selector_action: Selector,
|
||||
selector_team_link: Selector,
|
||||
selector_team_name: Selector,
|
||||
}
|
||||
|
||||
impl Default for TransactionParser {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl TransactionParser {
|
||||
pub fn new() -> Self {
|
||||
TransactionParser {
|
||||
selector_row: Selector::parse(SELECTOR_TRANSACTION_ROW).unwrap(),
|
||||
selector_player: Selector::parse(SELECTOR_TRANSACTION_PLAYER_LINK).unwrap(),
|
||||
selector_action: Selector::parse(SELECTOR_TRANSACTION_ACTION).unwrap(),
|
||||
selector_team_link: Selector::parse(SELECTOR_TRANSACTION_TEAM_LINK).unwrap(),
|
||||
selector_team_name: Selector::parse(SELECTOR_TRANSACTION_TEAM_NAME).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parser for TransactionParser {
|
||||
type Output = Vec<Transaction>;
|
||||
|
||||
fn parse(&self, document: &str) -> Result<Self::Output> {
|
||||
let document = Html::parse_document(document);
|
||||
|
||||
document
|
||||
.select(&self.selector_row)
|
||||
.filter(|row| row.select(&self.selector_player).next().is_some())
|
||||
.map(|row| {
|
||||
let player_link = row.select(&self.selector_player).next().ok_or(
|
||||
ParseError::ElementNotFound {
|
||||
selector: SELECTOR_TRANSACTION_PLAYER_LINK,
|
||||
role: "player link",
|
||||
},
|
||||
)?;
|
||||
let name = player_link.first_text().ok_or(ParseError::EmptyText {
|
||||
selector: SELECTOR_TRANSACTION_PLAYER_LINK,
|
||||
role: "player name",
|
||||
})?;
|
||||
let steam_id = steam_id_from_link(player_link.attr("href").unwrap_or_default())?;
|
||||
|
||||
let action = select_text(row, &self.selector_action)
|
||||
.ok_or(ParseError::ElementNotFound {
|
||||
selector: SELECTOR_TRANSACTION_ACTION,
|
||||
role: "transaction action",
|
||||
})?
|
||||
.parse()?;
|
||||
|
||||
let team_link = row.select(&self.selector_team_link).next().ok_or(
|
||||
ParseError::ElementNotFound {
|
||||
selector: SELECTOR_TRANSACTION_TEAM_LINK,
|
||||
role: "team link",
|
||||
},
|
||||
)?;
|
||||
let team_id = team_id_from_link(team_link.attr("href").unwrap_or_default())?;
|
||||
let team_name = select_last_text(row, &self.selector_team_name).ok_or(
|
||||
ParseError::EmptyText {
|
||||
selector: SELECTOR_TRANSACTION_TEAM_LINK,
|
||||
role: "team link",
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(Transaction {
|
||||
name: name.to_string(),
|
||||
steam_id,
|
||||
action,
|
||||
team: TeamRef {
|
||||
id: team_id,
|
||||
name: team_name.to_string(),
|
||||
},
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue