use anyhow::Result; use scraper::{ElementRef, Selector, selectable::Selectable}; use serde::{Deserialize, Serialize}; use time_rs::OffsetDateTime; use crate::{ClientScraper, Event, EventScraper, Fight, Fighter}; pub enum ONE {} impl EventScraper for ONE { async fn scrape(client: &C) -> Result> { let page = client.get("https://www.onefc.com/events/").await?; // should panic if selectors are invalid let selector_event = Selector::parse("#upcoming-events-section .is-event").unwrap(); let selector_check = Selector::parse("a.smart-link").unwrap(); let selector_event_url = Selector::parse("a.is-image-zoom[href]").unwrap(); for event_fragment in page.select(&selector_event) { do_thing(client, event_fragment).await; if event_fragment .select(&selector_check) .next() .map(|e| e.attr("href")) .flatten() .is_none() { continue; } let Some(url) = event_fragment .select(&selector_event_url) .next() .map(|e| e.attr("href")) .flatten() else { continue; }; } todo!() } } #[derive(Deserialize)] struct Location { name: String, } #[derive(Deserialize)] #[serde(rename_all = "camelCase")] struct EventData { name: String, image: Vec, location: Location, #[serde(with = "time_rs::serde::rfc3339")] start_date: OffsetDateTime, } async fn do_thing(client: &C, elem: ElementRef<'_>) -> Option> { let selector_check = Selector::parse("a.smart-link").unwrap(); let selector_event_url = Selector::parse("a.is-image-zoom[href]").unwrap(); let selector_data = Selector::parse("#site-main script[type=\"application/ld+json\"]").unwrap(); let mut events = Vec::new(); elem.select(&selector_check) .next() .map(|e| e.attr("href")) .flatten()?; let url = elem .select(&selector_event_url) .next() .map(|e| e.attr("href")) .flatten()?; let page = client.get(url).await.ok()?; let data_elem = page.select(&selector_data).next()?; let data_str: String = data_elem.text().collect(); let data: EventData = serde_json::from_str(&data_str).ok()?; data.start_date.unix_timestamp(); Some(events) }