use github_trending_rs::{Language, Param, SpokenLanguage, TrendExt};
use soupy::{Node, Queryable};
use std::{
collections::HashSet,
time::{Duration, SystemTime, UNIX_EPOCH},
};
use strum::IntoEnumIterator as _;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let date = std::env::args().nth(1);
let content = match date {
Some(date) => std::fs::read_to_string(format!("./tests/github-trends-{}.html", date))?,
None => {
let client = reqwest::ClientBuilder::new()
.connect_timeout(Duration::from_secs(5))
.timeout(Duration::from_secs(10))
.build()?;
let trending = client.github_trending().repositories().await?;
let secs = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs();
std::fs::write(
format!("./tests/github-trends-{}.html", secs),
trending.raw(),
)?;
trending.raw().to_owned()
}
};
let soup = soupy::Soup::html(content);
let items = soup
.attr("id", "languages-menuitems")
.first()
.expect("cant find languages menuitems");
let defined_langs: std::collections::HashSet<String> = Language::iter()
.map(|item| item.value().to_string())
.collect();
let parsed_langs: Option<std::collections::HashSet<String>> = items
.query()
.tag("a")
.into_iter()
.map(|item| {
item.get("href")
.and_then(|href| {
href.strip_prefix("/trending/")
.and_then(|href| href.strip_suffix("?since=daily"))
})
.map(|item| item.to_string())
})
.collect();
let parsed_langs = parsed_langs.expect("some parse failed");
let new_langs: HashSet<String> = parsed_langs
.difference(&defined_langs)
.map(ToOwned::to_owned)
.collect();
let removed_langs: HashSet<String> = defined_langs
.difference(&parsed_langs)
.map(ToOwned::to_owned)
.collect();
if !new_langs.is_empty() {
println!("New Programming Languages: {:?}", new_langs);
}
if !removed_langs.is_empty() {
println!("Removed Programming Languages: {:?}", removed_langs);
}
let defined_sls: std::collections::HashSet<String> = SpokenLanguage::iter()
.map(|item| item.value().to_string())
.collect();
let parsed_sls: Option<std::collections::HashSet<String>> = soup
.attr("data-filterable-for", "text-filter-field-spoken-language")
.first()
.expect("cant find spoken language list")
.query()
.tag("a")
.into_iter()
.map(|item| {
item.get("href")
.and_then(|href| href.strip_prefix("/trending?spoken_language_code="))
.map(ToOwned::to_owned)
})
.collect();
let parsed_sls = parsed_sls.expect("some spoken language parse failed");
let new_sls: HashSet<String> = parsed_sls
.difference(&defined_sls)
.map(ToOwned::to_owned)
.collect();
let removed_sls: HashSet<String> = defined_sls
.difference(&parsed_sls)
.map(ToOwned::to_owned)
.collect();
if !new_sls.is_empty() {
println!("New Spoken Languages: {:?}", new_sls);
}
if !removed_sls.is_empty() {
println!("Removed Spoken Languages: {:?}", removed_sls);
}
Ok(())
}