536a766960
* Fixed random subreddit issue * Fixed large subreddit icon rendering * Formatting fix * Fix dodgy HTML rendering issues * Revert "Fix dodgy HTML rendering issues" This reverts commit 58be5f449b72f271d2b3c046870b652d1e715289.
114 lines
3.0 KiB
Rust
114 lines
3.0 KiB
Rust
// CRATES
|
|
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};
|
|
|
|
// STRUCTS
|
|
struct SearchParams {
|
|
q: String,
|
|
sort: String,
|
|
t: String,
|
|
before: String,
|
|
after: String,
|
|
restrict_sr: String,
|
|
}
|
|
|
|
// STRUCTS
|
|
struct Subreddit {
|
|
name: String,
|
|
url: String,
|
|
icon: String,
|
|
description: String,
|
|
subscribers: (String, String),
|
|
}
|
|
|
|
#[derive(Template)]
|
|
#[template(path = "search.html", escape = "none")]
|
|
struct SearchTemplate {
|
|
posts: Vec<Post>,
|
|
subreddits: Vec<Subreddit>,
|
|
sub: String,
|
|
params: SearchParams,
|
|
prefs: Preferences,
|
|
}
|
|
|
|
// SERVICES
|
|
pub async fn find(req: Request<Body>) -> Result<Response<Body>, 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() {
|
|
"relevance".to_string()
|
|
} else {
|
|
param(&path, "sort")
|
|
};
|
|
|
|
let subreddits = if param(&path, "restrict_sr").is_empty() {
|
|
search_subreddits(&query).await
|
|
} else {
|
|
Vec::new()
|
|
};
|
|
|
|
match Post::fetch(&path, String::new()).await {
|
|
Ok((posts, after)) => template(SearchTemplate {
|
|
posts,
|
|
subreddits,
|
|
sub,
|
|
params: SearchParams {
|
|
q: query.replace('"', """),
|
|
sort,
|
|
t: param(&path, "t"),
|
|
before: param(&path, "after"),
|
|
after,
|
|
restrict_sr: param(&path, "restrict_sr"),
|
|
},
|
|
prefs: Preferences::new(req),
|
|
}),
|
|
Err(msg) => error(req, msg).await,
|
|
}
|
|
}
|
|
|
|
async fn search_subreddits(q: &str) -> Vec<Subreddit> {
|
|
let subreddit_search_path = format!("/subreddits/search.json?q={}&limit=3", q.replace(' ', "+"));
|
|
|
|
// Send a request to the url
|
|
match json(subreddit_search_path).await {
|
|
// If success, receive JSON in response
|
|
Ok(response) => {
|
|
match response["data"]["children"].as_array() {
|
|
// For each subreddit from subreddit list
|
|
Some(list) => list
|
|
.iter()
|
|
.map(|subreddit| {
|
|
// Fetch subreddit icon either from the community_icon or icon_img value
|
|
let community_icon: &str = subreddit["data"]["community_icon"].as_str().map_or("", |s| s.split('?').collect::<Vec<&str>>()[0]);
|
|
let icon = if community_icon.is_empty() {
|
|
val(&subreddit, "icon_img")
|
|
} else {
|
|
community_icon.to_string()
|
|
};
|
|
|
|
Subreddit {
|
|
name: val(subreddit, "display_name_prefixed"),
|
|
url: val(subreddit, "url"),
|
|
icon: format_url(&icon),
|
|
description: val(subreddit, "public_description"),
|
|
subscribers: format_num(subreddit["data"]["subscribers"].as_f64().unwrap_or_default() as i64),
|
|
}
|
|
})
|
|
.collect::<Vec<Subreddit>>(),
|
|
_ => Vec::new(),
|
|
}
|
|
}
|
|
// If the Reddit API returns an error, exit this function
|
|
_ => Vec::new(),
|
|
}
|
|
}
|