diff --git a/src/search.rs b/src/search.rs index cf1199a..e18eb0c 100644 --- a/src/search.rs +++ b/src/search.rs @@ -1,5 +1,5 @@ // CRATES -use crate::utils::{cookie, error, format_num, format_url, param, template, val, Post, Preferences}; +use crate::utils::{catch_random, cookie, error, format_num, format_url, param, template, val, Post, Preferences}; use crate::{client::json, RequestExt}; use askama::Template; use hyper::{Body, Request, Response}; @@ -38,6 +38,10 @@ pub async fn find(req: Request) -> Result, String> { let nsfw_results = if cookie(&req, "show_nsfw") == "on" { "&include_over_18=on" } else { "" }; let path = format!("{}.json?{}{}", req.uri().path(), req.uri().query().unwrap_or_default(), nsfw_results); let sub = req.param("sub").unwrap_or_default(); + // Handle random subreddits + if let Ok(random) = catch_random(&sub, "/find").await { + return Ok(random); + } let query = param(&path, "q"); let sort = if param(&path, "sort").is_empty() { diff --git a/src/subreddit.rs b/src/subreddit.rs index 0a850e6..d68eace 100644 --- a/src/subreddit.rs +++ b/src/subreddit.rs @@ -1,6 +1,6 @@ // CRATES use crate::esc; -use crate::utils::{cookie, error, format_num, format_url, param, redirect, rewrite_urls, template, val, Post, Preferences, Subreddit}; +use crate::utils::{catch_random, cookie, error, format_num, format_url, param, redirect, rewrite_urls, template, val, Post, Preferences, Subreddit}; use crate::{client::json, server::ResponseExt, RequestExt}; use askama::Template; use cookie::Cookie; @@ -45,6 +45,11 @@ pub async fn community(req: Request) -> Result, String> { front_page.to_owned() }); + // Handle random subreddits + if let Ok(random) = catch_random(&sub, "").await { + return Ok(random); + } + if req.param("sub").is_some() && sub.starts_with("u_") { return Ok(redirect(["/user/", &sub[2..]].concat())); } @@ -94,6 +99,11 @@ pub async fn community(req: Request) -> Result, String> { // Sub or unsub by setting subscription cookie using response "Set-Cookie" header pub async fn subscriptions(req: Request) -> Result, String> { let sub = req.param("sub").unwrap_or_default(); + // Handle random subreddits + if sub == "random" || sub == "randnsfw" { + return Err("Can't subscribe to random subreddit!".to_string()); + } + let query = req.uri().query().unwrap_or_default().to_string(); let action: Vec = req.uri().path().split('/').map(String::from).collect(); @@ -166,6 +176,11 @@ pub async fn subscriptions(req: Request) -> Result, String> pub async fn wiki(req: Request) -> Result, String> { let sub = req.param("sub").unwrap_or_else(|| "reddit.com".to_string()); + // Handle random subreddits + if let Ok(random) = catch_random(&sub, "/wiki").await { + return Ok(random); + } + let page = req.param("page").unwrap_or_else(|| "index".to_string()); let path: String = format!("/r/{}/wiki/{}.json?raw_json=1", sub, page); @@ -182,6 +197,10 @@ pub async fn wiki(req: Request) -> Result, String> { pub async fn sidebar(req: Request) -> Result, String> { let sub = req.param("sub").unwrap_or_else(|| "reddit.com".to_string()); + // Handle random subreddits + if let Ok(random) = catch_random(&sub, "/about/sidebar").await { + return Ok(random); + } // Build the Reddit JSON API url let path: String = format!("/r/{}/about.json?raw_json=1", sub); @@ -247,7 +266,7 @@ async fn subreddit(sub: &str) -> Result { let active: i64 = res["data"]["accounts_active"].as_u64().unwrap_or_default() as i64; // Fetch subreddit icon either from the community_icon or icon_img value - let community_icon: &str = res["data"]["community_icon"].as_str().map_or("", |s| s.split('?').collect::>()[0]); + let community_icon: &str = res["data"]["community_icon"].as_str().unwrap(); let icon = if community_icon.is_empty() { val(&res, "icon_img") } else { community_icon.to_string() }; let sub = Subreddit { diff --git a/src/utils.rs b/src/utils.rs index 3a905a6..dca2ad0 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -404,6 +404,19 @@ pub fn cookie(req: &Request, name: &str) -> String { cookie.value().to_string() } +// Detect and redirect in the event of a random subreddit +pub async fn catch_random(sub: &str, additional: &str) -> Result, String> { + if (sub == "random" || sub == "randnsfw") && !sub.contains('+') { + let new_sub = json(format!("/r/{}/about.json?raw_json=1", sub)).await?["data"]["display_name"] + .as_str() + .unwrap_or_default() + .to_string(); + return Ok(redirect(format!("/r/{}{}", new_sub, additional))); + } else { + return Err("No redirect needed".to_string()); + } +} + // Direct urls to proxy if proxy is enabled pub fn format_url(url: &str) -> String { if url.is_empty() || url == "self" || url == "default" || url == "nsfw" || url == "spoiler" {