From 7d709d9884f9f68f56199b90c67cba909496e378 Mon Sep 17 00:00:00 2001 From: Alyxia Sother Date: Tue, 7 Oct 2025 00:46:08 +0200 Subject: [PATCH 1/2] Add thatskyshop support --- src/feeds.rs | 1 + src/feeds/thatskyshop.rs | 75 ++++++++++++++++++++++++++++++++++++++++ src/main.rs | 1 + src/util/net.rs | 21 +++++++++++ 4 files changed, 98 insertions(+) create mode 100644 src/feeds/thatskyshop.rs diff --git a/src/feeds.rs b/src/feeds.rs index be171f5..5b624c4 100644 --- a/src/feeds.rs +++ b/src/feeds.rs @@ -8,3 +8,4 @@ pub mod moxie; pub mod nue; pub mod pwn_cat; pub mod bsky; +pub mod thatskyshop; diff --git a/src/feeds/thatskyshop.rs b/src/feeds/thatskyshop.rs new file mode 100644 index 0000000..ee627eb --- /dev/null +++ b/src/feeds/thatskyshop.rs @@ -0,0 +1,75 @@ +use axum::{extract::Query}; +use rss::{ChannelBuilder, ItemBuilder}; +use serde::Deserialize; +use serde_json::json; +use crate::util::{net, res}; + +#[derive(Deserialize)] +pub struct QueryData { + handle: String +} + +pub async fn rss(query: Query) -> res::Res { + let handle = &query.handle; + let url = "https://thatskyshop.com/api/2025-10/graphql.json"; + + let client = reqwest::Client::new(); + + let product_data: Response = { + let res = net::post_json(&client, url, &json!({ + "operationName": "Product", + "query": format!("query Product($handle: String) {{ product(handle: $handle) {{ title onlineStoreUrl availableForSale }} }}"), + "variables": { + "handle": &handle + } + })).await?; + + match serde_json::from_str(&res) { + Ok(val) => val, + Err(_) => return res::err_static("Failed to parse response JSON") + } + }; + + dbg!(&product_data.data.product.available_for_sale); + + let product = product_data.data.product; + let item = ItemBuilder::default() + .title(format!( + "{} - {}", + product.title, + if product.available_for_sale { + "ON SALE!!!" + } else { + "Sold out" + } + )) + .link(product.url) + .build(); + + let feed = ChannelBuilder::default() + .title(format!("thatskyshop - {} Tracker", product.title)) + .link("https://thatskyshop.com") + .items(Vec::from([item])) + .build(); + + res::ok(feed.to_string()) +} + +#[derive(Deserialize)] +struct Response { + data: ProductContainer +} + +#[derive(Deserialize)] +struct ProductContainer { + product: Product +} + +#[derive(Deserialize)] +struct Product { + title: String, + #[serde(rename(deserialize = "onlineStoreUrl"))] + url: String, + #[serde(rename(deserialize = "availableForSale"))] + available_for_sale: bool, +} diff --git a/src/main.rs b/src/main.rs index 66f5302..42d1415 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ async fn main() { .route("/moxie.rss", get(feeds::moxie::rss)) .route("/nue.rss", get(feeds::nue::rss)) .route("/pwn_cat.rss", get(feeds::pwn_cat::rss)) + .route("/thatskyshop.rss", get(feeds::thatskyshop::rss)) ; let port = match env::var("PORT") { diff --git a/src/util/net.rs b/src/util/net.rs index 1f68421..8bed157 100644 --- a/src/util/net.rs +++ b/src/util/net.rs @@ -1,3 +1,4 @@ +use axum::http::HeaderMap; use axum::response::Response; use reqwest::header; use scraper::Html; @@ -19,6 +20,26 @@ pub async fn fetch_txt(client: &reqwest::Client, url: &str) -> Result Result { + let res = client + .post(url) + .header(header::CONTENT_TYPE, "application/json") + .header(header::ACCEPT, "application/json") + .body(json.to_string()) + .send() + .await; + + let res = match res { + Ok(res) => res, + Err(_) => return res::err(format!("Failed to fetch {}", url)) + }; + + match res.text().await { + Ok(text) => Ok(text), + Err(_) => res::err(format!("Failed to parse text response from {}", url)) + } +} + /// Fetches the contents of a URL and parses the HTML. pub async fn fetch(client: &reqwest::Client, url: &str) -> Result { fetch_txt(client, url).await -- 2.55.0 From 23d53d1d5ebb473fc202b59bc1d89446e4d542b6 Mon Sep 17 00:00:00 2001 From: Alyxia Sother Date: Tue, 7 Oct 2025 00:49:35 +0200 Subject: [PATCH 2/2] Remove stray use statement --- src/feeds/thatskyshop.rs | 2 +- src/util/net.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/feeds/thatskyshop.rs b/src/feeds/thatskyshop.rs index ee627eb..3f9e209 100644 --- a/src/feeds/thatskyshop.rs +++ b/src/feeds/thatskyshop.rs @@ -1,4 +1,4 @@ -use axum::{extract::Query}; +use axum::extract::Query; use rss::{ChannelBuilder, ItemBuilder}; use serde::Deserialize; use serde_json::json; diff --git a/src/util/net.rs b/src/util/net.rs index 8bed157..7a66bf0 100644 --- a/src/util/net.rs +++ b/src/util/net.rs @@ -1,4 +1,3 @@ -use axum::http::HeaderMap; use axum::response::Response; use reqwest::header; use scraper::Html; -- 2.55.0

AltStyle によって変換されたページ (->オリジナル) /