mirror of
https://codeberg.org/icewind/ugc-scaper.git
synced 2026-06-03 18:24:10 +02:00
steam group on roster page
This commit is contained in:
parent
b96789bff4
commit
df91032de4
12 changed files with 993 additions and 960 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1550,7 +1550,7 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ugc-scraper"
|
name = "ugc-scraper"
|
||||||
version = "0.3.3"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"insta",
|
"insta",
|
||||||
"main_error",
|
"main_error",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "ugc-scraper"
|
name = "ugc-scraper"
|
||||||
version = "0.3.3"
|
version = "0.4.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.67.0"
|
rust-version = "1.67.0"
|
||||||
description = "Scraper for ugcleague.com"
|
description = "Scraper for ugcleague.com"
|
||||||
|
|
|
||||||
4
api-server/Cargo.lock
generated
4
api-server/Cargo.lock
generated
|
|
@ -1851,9 +1851,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ugc-scraper"
|
name = "ugc-scraper"
|
||||||
version = "0.3.3"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "082110c325d2a7b6282d643f5753860ae04ae9890df4f145d10db25ad449c06f"
|
checksum = "5866c81814a2fc1495630ac7fd74c5564cceff96305ea10c7ee2dd85caadc45e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"scraper",
|
"scraper",
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||||
tokio = { version = "1.34.0", features = ["macros", "rt-multi-thread", "rt", "signal"] }
|
tokio = { version = "1.34.0", features = ["macros", "rt-multi-thread", "rt", "signal"] }
|
||||||
main_error = "0.1.2"
|
main_error = "0.1.2"
|
||||||
#ugc-scraper = { path = "../", version = "*" }
|
#ugc-scraper = { path = "../", version = "*" }
|
||||||
ugc-scraper = "0.3.3"
|
ugc-scraper = "0.4.0"
|
||||||
axum = "0.7.4"
|
axum = "0.7.4"
|
||||||
steamid-ng = "1.0.0"
|
steamid-ng = "1.0.0"
|
||||||
thiserror = "1.0.50"
|
thiserror = "1.0.50"
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ async fn main() -> MainResult {
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
println!("previous players ");
|
println!("previous players ");
|
||||||
let roster_history = client.team_roster_history(id).await?;
|
let roster_history = client.team_roster_history(id).await?.history;
|
||||||
for roster_item in roster_history {
|
for roster_item in roster_history {
|
||||||
if let Some(left) = roster_item.left {
|
if let Some(left) = roster_item.left {
|
||||||
println!(
|
println!(
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,14 @@ pub struct Record {
|
||||||
pub losses: u8,
|
pub losses: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub struct TeamRosterData {
|
||||||
|
pub steam_group: String,
|
||||||
|
pub history: Vec<RosterHistory>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||||
pub struct RosterHistory {
|
pub struct RosterHistory {
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ mod error;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|
||||||
use crate::data::{
|
use crate::data::{
|
||||||
GameMode, MapHistory, MatchInfo, MembershipHistory, Player, RosterHistory, Seasons, Team,
|
GameMode, MapHistory, MatchInfo, MembershipHistory, Player, Seasons, Team, TeamRef,
|
||||||
TeamRef, TeamSeason, Transaction,
|
TeamRosterData, TeamSeason, Transaction,
|
||||||
};
|
};
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
MapHistoryParser, MatchPageParser, Parser, PlayerDetailsParser, PlayerParser, SeasonsParser,
|
MapHistoryParser, MatchPageParser, Parser, PlayerDetailsParser, PlayerParser, SeasonsParser,
|
||||||
|
|
@ -101,7 +101,7 @@ impl UgcClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve team roster history
|
/// Retrieve team roster history
|
||||||
pub async fn team_roster_history(&self, id: u32) -> Result<Vec<RosterHistory>> {
|
pub async fn team_roster_history(&self, id: u32) -> Result<TeamRosterData> {
|
||||||
let body = self
|
let body = self
|
||||||
.client
|
.client
|
||||||
.get(&format!(
|
.get(&format!(
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,10 @@ impl Parser for TeamParser {
|
||||||
let steam_group = root
|
let steam_group = root
|
||||||
.select(&self.selector_steam_group)
|
.select(&self.selector_steam_group)
|
||||||
.next()
|
.next()
|
||||||
.and_then(|link| link.attr("href").map(String::from));
|
.and_then(|link| {
|
||||||
|
link.attr("href")
|
||||||
|
.map(|group| group.replace("http://http", "http"))
|
||||||
|
});
|
||||||
|
|
||||||
let division = select_text(root, &self.selector_team_division)
|
let division = select_text(root, &self.selector_team_division)
|
||||||
.ok_or(ParseError::ElementNotFound {
|
.ok_or(ParseError::ElementNotFound {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use super::Parser;
|
use super::Parser;
|
||||||
use crate::data::RosterHistory;
|
use crate::data::{RosterHistory, TeamRosterData};
|
||||||
use crate::parser::{select_text, ROSTER_HISTORY_DATE_FORMAT};
|
use crate::parser::{select_text, ROSTER_HISTORY_DATE_FORMAT};
|
||||||
use crate::{ParseError, Result};
|
use crate::{ParseError, Result};
|
||||||
use scraper::{Html, Selector};
|
use scraper::{Html, Selector};
|
||||||
|
|
@ -13,12 +13,15 @@ const SELECTOR_ROSTER_ID: &str = "h5 small";
|
||||||
const SELECTOR_ROSTER_JOINED: &str = "span.text-success small";
|
const SELECTOR_ROSTER_JOINED: &str = "span.text-success small";
|
||||||
const SELECTOR_ROSTER_LEFT: &str = "span.text-danger small";
|
const SELECTOR_ROSTER_LEFT: &str = "span.text-danger small";
|
||||||
|
|
||||||
|
const SELECTOR_STEAM: &str = r#"p.muted a[href*="//steamcommunity.com/groups"]"#;
|
||||||
|
|
||||||
pub struct TeamRosterHistoryParser {
|
pub struct TeamRosterHistoryParser {
|
||||||
selector_item: Selector,
|
selector_item: Selector,
|
||||||
selector_name: Selector,
|
selector_name: Selector,
|
||||||
selector_id: Selector,
|
selector_id: Selector,
|
||||||
selector_joined: Selector,
|
selector_joined: Selector,
|
||||||
selector_left: Selector,
|
selector_left: Selector,
|
||||||
|
selector_steam_group: Selector,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TeamRosterHistoryParser {
|
impl Default for TeamRosterHistoryParser {
|
||||||
|
|
@ -35,17 +38,29 @@ impl TeamRosterHistoryParser {
|
||||||
selector_id: Selector::parse(SELECTOR_ROSTER_ID).unwrap(),
|
selector_id: Selector::parse(SELECTOR_ROSTER_ID).unwrap(),
|
||||||
selector_joined: Selector::parse(SELECTOR_ROSTER_JOINED).unwrap(),
|
selector_joined: Selector::parse(SELECTOR_ROSTER_JOINED).unwrap(),
|
||||||
selector_left: Selector::parse(SELECTOR_ROSTER_LEFT).unwrap(),
|
selector_left: Selector::parse(SELECTOR_ROSTER_LEFT).unwrap(),
|
||||||
|
selector_steam_group: Selector::parse(SELECTOR_STEAM).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parser for TeamRosterHistoryParser {
|
impl Parser for TeamRosterHistoryParser {
|
||||||
type Output = Vec<RosterHistory>;
|
type Output = TeamRosterData;
|
||||||
|
|
||||||
fn parse(&self, document: &str) -> Result<Self::Output> {
|
fn parse(&self, document: &str) -> Result<Self::Output> {
|
||||||
let document = Html::parse_document(document);
|
let document = Html::parse_document(document);
|
||||||
|
|
||||||
document
|
let steam_group = document.select(&self.selector_steam_group).next().ok_or(
|
||||||
|
ParseError::ElementNotFound {
|
||||||
|
selector: SELECTOR_STEAM,
|
||||||
|
role: "team steam group",
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
let steam_group = steam_group
|
||||||
|
.attr("href")
|
||||||
|
.unwrap_or_default()
|
||||||
|
.replace("http://http", "http");
|
||||||
|
|
||||||
|
let history = document
|
||||||
.select(&self.selector_item)
|
.select(&self.selector_item)
|
||||||
.map(|item| {
|
.map(|item| {
|
||||||
let name =
|
let name =
|
||||||
|
|
@ -92,6 +107,10 @@ impl Parser for TeamRosterHistoryParser {
|
||||||
.transpose()?,
|
.transpose()?,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()?;
|
||||||
|
Ok(TeamRosterData {
|
||||||
|
history,
|
||||||
|
steam_group,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ expression: parsed
|
||||||
"image": "clan_avatars/32437_thumbnail.jpg",
|
"image": "clan_avatars/32437_thumbnail.jpg",
|
||||||
"format": "TF2 Highlander",
|
"format": "TF2 Highlander",
|
||||||
"timezone": null,
|
"timezone": null,
|
||||||
"steam_group": "http://https://steamcommunity.com/groups/xyxxx-",
|
"steam_group": "https://steamcommunity.com/groups/xyxxx-",
|
||||||
"division": "North America",
|
"division": "North America",
|
||||||
"description": "",
|
"description": "",
|
||||||
"titles": [
|
"titles": [
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ expression: parsed
|
||||||
"image": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/db/dbabbd8bab7ccf6d27a9d4ca2e73a76e085bb201_full.jpg",
|
"image": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/db/dbabbd8bab7ccf6d27a9d4ca2e73a76e085bb201_full.jpg",
|
||||||
"format": "TF2 Highlander",
|
"format": "TF2 Highlander",
|
||||||
"timezone": "West-Euro",
|
"timezone": "West-Euro",
|
||||||
"steam_group": "http://https://steamcommunity.com/groups/XenonxTF2",
|
"steam_group": "https://steamcommunity.com/groups/XenonxTF2",
|
||||||
"division": "Euro Platinum",
|
"division": "Euro Platinum",
|
||||||
"description": "Contact Kimo or Icewind for everything.",
|
"description": "Contact Kimo or Icewind for everything.",
|
||||||
"titles": [
|
"titles": [
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue