diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..3e3b551 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,82 @@ +use reqwest::{Error as ReqwestError, StatusCode}; +use rss::{Channel, Error as RssError}; +use regex::Regex; +use std::io::Cursor; + +use worker::{Request, Env, Response, Router, event, Headers}; + +#[derive(Debug)] +enum CustomError { + Reqwest(ReqwestError), + Rss(RssError), +} + +impl From for CustomError { + fn from(error: ReqwestError) -> Self { + CustomError::Reqwest(error) + } +} + +impl From for CustomError { + fn from(error: RssError) -> Self { + CustomError::Rss(error) + } +} + +#[event(fetch)] +pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> worker::Result{ + let router = Router::new(); + router + .get_async("/", |_, ctx| async move { + let rss = match fetch_modified_rss().await { + Ok(r) => r, + Err(e) => "".to_owned(), + }; + + let res = Response::from_bytes(rss.into()).unwrap(); + let mut headers = Headers::new(); + headers.set("content-type", "application/rss+xml"); + + Ok(res.with_headers(headers)) + }).run(req, env).await +} + +async fn fetch_modified_rss() -> Result { + let url = "https://news.ycombinator.com/rss"; + + let resp = reqwest::get(url).await?; + let body = resp.text().await?; + + let cursor = Cursor::new(body); + let channel = match Channel::read_from(cursor) { + Ok(channel) => channel, + Err(RssError::InvalidStartTag) => { + eprintln!("Invalid start tag found in the feed. Please check the feed URL or try again later."); + return Ok(String::new()); + }, + Err(err) => return Err(err.into()), + }; + + let items = channel.into_items(); + + let updated_items = items + .iter() + .map(|item| { + let mut new_item = item.clone(); + let description = item.description().unwrap_or_default(); + let new_description = remove_comment_link(description); + new_item.set_description(new_description); + new_item + }) + .collect::>(); + + let mut modified_rss = Channel::default(); + modified_rss.set_items(updated_items); + + Ok(modified_rss.to_string()) +} + +fn remove_comment_link(description: &str) -> String { + let re = Regex::new(r"(?i)]*>comments").unwrap(); + re.replace(description, "").to_string() +} diff --git a/wrangler.toml b/wrangler.toml new file mode 100644 index 0000000..7979334 --- /dev/null +++ b/wrangler.toml @@ -0,0 +1,19 @@ +name = "hn-rss" +type = "javascript" +workers_dev = true +compatibility_date = "2022-01-20" + +[vars] +WORKERS_RS_VERSION = "0.0.18" + +[build] +command = "cargo install -q worker-build && worker-build --release" # required + +[build.upload] +dir = "build/worker" +format = "modules" +main = "./shim.mjs" + +[[build.upload.rules]] +globs = ["**/*.wasm"] +type = "CompiledWasm"