Fixed Sorting

This commit is contained in:
spikecodes 2020-11-17 16:03:28 -08:00
parent 2c06ae1d8f
commit 05ea0fe1fd
10 changed files with 49 additions and 48 deletions

View File

@ -32,13 +32,10 @@ async fn main() -> std::io::Result<()> {
// POST SERVICES // POST SERVICES
.service(post::short) .service(post::short)
.service(post::page) .service(post::page)
.service(post::sorted)
// SUBREDDIT SERVICES // SUBREDDIT SERVICES
.service(subreddit::page) .service(subreddit::page)
.service(subreddit::sorted)
// POPULAR SERVICES // POPULAR SERVICES
.service(popular::page) .service(popular::page)
// .service(popular::sorted)
// USER SERVICES // USER SERVICES
.service(user::page) .service(user::page)
}) })

View File

@ -1,12 +1,15 @@
// CRATES // CRATES
use actix_web::{get, web, HttpResponse, Result}; use actix_web::{get, web, HttpResponse, Result};
use askama::Template; use askama::Template;
use serde::Deserialize;
#[path = "subreddit.rs"] #[path = "subreddit.rs"]
mod subreddit; mod subreddit;
use subreddit::{posts, Post}; use subreddit::{posts, Post};
#[path = "utils.rs"]
mod utils;
use utils::{Params};
// STRUCTS // STRUCTS
#[derive(Template)] #[derive(Template)]
#[template(path = "popular.html", escape = "none")] #[template(path = "popular.html", escape = "none")]
@ -15,11 +18,6 @@ struct PopularTemplate {
sort: String, sort: String,
} }
#[derive(Deserialize)]
pub struct Params {
sort: Option<String>,
}
// RENDER // RENDER
async fn render(sub_name: String, sort: String) -> Result<HttpResponse> { async fn render(sub_name: String, sort: String) -> Result<HttpResponse> {
let posts: Vec<Post> = posts(sub_name, &sort).await; let posts: Vec<Post> = posts(sub_name, &sort).await;

View File

@ -6,7 +6,7 @@ use pulldown_cmark::{html, Options, Parser};
#[path = "utils.rs"] #[path = "utils.rs"]
mod utils; mod utils;
use utils::{Comment, Flair, Post, val}; use utils::{Params, Comment, Flair, Post, val};
// STRUCTS // STRUCTS
#[derive(Template)] #[derive(Template)]
@ -42,13 +42,11 @@ async fn short(web::Path(id): web::Path<String>) -> Result<HttpResponse> {
} }
#[get("/r/{sub}/comments/{id}/{title}/")] #[get("/r/{sub}/comments/{id}/{title}/")]
async fn page(web::Path((_sub, id)): web::Path<(String, String)>) -> Result<HttpResponse> { async fn page(web::Path((_sub, id)): web::Path<(String, String)>, params: web::Query<Params>) -> Result<HttpResponse> {
render(id.to_string(), "confidence".to_string()).await match &params.sort {
} Some(sort) => render(id, sort.to_string()).await,
None => render(id, "confidence".to_string()).await,
#[get("/r/{sub}/comments/{id}/{title}/{sort}")] }
async fn sorted(web::Path((_sub, id, _title, sort)): web::Path<(String, String, String, String)>) -> Result<HttpResponse> {
render(id.to_string(), sort).await
} }
// UTILITIES // UTILITIES

View File

@ -5,7 +5,7 @@ use chrono::{TimeZone, Utc};
#[path = "utils.rs"] #[path = "utils.rs"]
mod utils; mod utils;
pub use utils::{Flair, Post, Subreddit, val}; pub use utils::{Params, Flair, Post, Subreddit, val};
// STRUCTS // STRUCTS
#[derive(Template)] #[derive(Template)]
@ -33,21 +33,20 @@ async fn render(sub_name: String, sort: String) -> Result<HttpResponse> {
// SERVICES // SERVICES
#[allow(dead_code)] #[allow(dead_code)]
#[get("/r/{sub}")] #[get("/r/{sub}")]
async fn page(web::Path(sub): web::Path<String>) -> Result<HttpResponse> { async fn page(web::Path(sub): web::Path<String>, params: web::Query<Params>) -> Result<HttpResponse> {
render(sub, String::from("hot")).await match &params.sort {
} Some(sort) => render(sub, sort.to_string()).await,
None => render(sub, "hot".to_string()).await,
#[allow(dead_code)] }
#[get("/r/{sub}/{sort}")]
async fn sorted(web::Path((sub, sort)): web::Path<(String, String)>) -> Result<HttpResponse> {
render(sub, sort).await
} }
// SUBREDDIT // SUBREDDIT
async fn subreddit(sub: &String) -> Subreddit { async fn subreddit(sub: &String) -> Subreddit {
// Make a GET request to the Reddit's JSON API for the metadata of this subreddit
let url: String = format!("https://www.reddit.com/r/{}/about.json", sub); let url: String = format!("https://www.reddit.com/r/{}/about.json", sub);
let resp: String = reqwest::get(&url).await.unwrap().text().await.unwrap(); let resp: String = reqwest::get(&url).await.unwrap().text().await.unwrap();
// Parse the response from Reddit as JSON
let data: serde_json::Value = serde_json::from_str(resp.as_str()).expect("Failed to parse JSON"); let data: serde_json::Value = serde_json::from_str(resp.as_str()).expect("Failed to parse JSON");
let icon: String = String::from(data["data"]["community_icon"].as_str().unwrap()); //val(&data, "community_icon"); let icon: String = String::from(data["data"]["community_icon"].as_str().unwrap()); //val(&data, "community_icon");
@ -64,9 +63,11 @@ async fn subreddit(sub: &String) -> Subreddit {
// POSTS // POSTS
pub async fn posts(sub: String, sort: &String) -> Vec<Post> { pub async fn posts(sub: String, sort: &String) -> Vec<Post> {
// Make a GET request to the Reddit's JSON API for the content of this subreddit
let url: String = format!("https://www.reddit.com/r/{}/{}.json", sub, sort); let url: String = format!("https://www.reddit.com/r/{}/{}.json", sub, sort);
let resp: String = reqwest::get(&url).await.unwrap().text().await.unwrap(); let resp: String = reqwest::get(&url).await.unwrap().text().await.unwrap();
// Parse the response from Reddit as JSON
let popular: serde_json::Value = serde_json::from_str(resp.as_str()).expect("Failed to parse JSON"); let popular: serde_json::Value = serde_json::from_str(resp.as_str()).expect("Failed to parse JSON");
let post_list = popular["data"]["children"].as_array().unwrap(); let post_list = popular["data"]["children"].as_array().unwrap();

View File

@ -5,7 +5,7 @@ use chrono::{TimeZone, Utc};
#[path = "utils.rs"] #[path = "utils.rs"]
mod utils; mod utils;
use utils::{Flair, Post, User, val, nested_val}; use utils::{Params, Flair, Post, User, val, nested_val};
// STRUCTS // STRUCTS
#[derive(Template)] #[derive(Template)]
@ -26,13 +26,11 @@ async fn render(username: String, sort: String) -> Result<HttpResponse> {
// SERVICES // SERVICES
#[get("/u/{username}")] #[get("/u/{username}")]
async fn page(web::Path(username): web::Path<String>) -> Result<HttpResponse> { async fn page(web::Path(username): web::Path<String>, params: web::Query<Params>) -> Result<HttpResponse> {
render(username, "hot".to_string()).await match &params.sort {
} Some(sort) => render(username, sort.to_string()).await,
None => render(username, "hot".to_string()).await,
#[get("/u/{username}/{sort}")] }
async fn sorted(web::Path((username, sort)): web::Path<(String, String)>) -> Result<HttpResponse> {
render(username, sort).await
} }
// USER // USER

View File

@ -1,6 +1,8 @@
#[allow(dead_code)]
// Post flair with text, background color and foreground color // Post flair with text, background color and foreground color
pub struct Flair(pub String, pub String, pub String); pub struct Flair(pub String, pub String, pub String);
#[allow(dead_code)]
// Post containing content, metadata and media // Post containing content, metadata and media
pub struct Post { pub struct Post {
pub title: String, pub title: String,
@ -42,6 +44,7 @@ pub struct Subreddit {
pub icon: String, pub icon: String,
} }
#[allow(dead_code)]
// val() function used to parse JSON from Reddit APIs // val() function used to parse JSON from Reddit APIs
pub async fn val(j: &serde_json::Value, k: &str) -> String { pub async fn val(j: &serde_json::Value, k: &str) -> String {
String::from(j["data"][k].as_str().unwrap_or("")) String::from(j["data"][k].as_str().unwrap_or(""))
@ -51,4 +54,10 @@ pub async fn val(j: &serde_json::Value, k: &str) -> String {
// nested_val() function used to parse JSON from Reddit APIs // nested_val() function used to parse JSON from Reddit APIs
pub async fn nested_val(j: &serde_json::Value, n: &str, k: &str) -> String { pub async fn nested_val(j: &serde_json::Value, n: &str, k: &str) -> String {
String::from(j["data"][n][k].as_str().unwrap()) String::from(j["data"][n][k].as_str().unwrap())
}
// Parser for query params, used in sorting (eg. /r/rust/?sort=hot)
#[derive(serde::Deserialize)]
pub struct Params {
pub sort: Option<String>,
} }

View File

@ -18,9 +18,9 @@
</header> </header>
<main> <main>
<div id="sort"> <div id="sort">
<div id="sort_hot"><a href="/?sort=hot">Hot</a></div> <div id="sort_hot"><a href="?sort=hot">Hot</a></div>
<div id="sort_top"><a href="/?sort=top">Top</a></div> <div id="sort_top"><a href="?sort=top">Top</a></div>
<div id="sort_new"><a href="/?sort=new">New</a></div> <div id="sort_new"><a href="?sort=new">New</a></div>
</div> </div>
{% for post in posts %} {% for post in posts %}
<div class="post"> <div class="post">

View File

@ -43,11 +43,11 @@
</div> </div>
</div> </div>
<div id="sort"> <div id="sort">
<div id="sort_confidence"><a href="{{ post.url }}confidence">Best</a></div> <div id="sort_confidence"><a href="?sort=confidence">Best</a></div>
<div id="sort_top"><a href="{{ post.url }}top">Top</a></div> <div id="sort_top"><a href="?sort=top">Top</a></div>
<div id="sort_new"><a href="{{ post.url }}new">New</a></div> <div id="sort_new"><a href="?sort=new">New</a></div>
<div id="sort_controversial"><a href="{{ post.url }}controversial">Controversial</a></div> <div id="sort_controversial"><a href="?sort=controversial">Controversial</a></div>
<div id="sort_old"><a href="{{ post.url }}old">Old</a></div> <div id="sort_old"><a href="?sort=old">Old</a></div>
</div> </div>
{% for comment in comments %} {% for comment in comments %}
<div class="comment"> <div class="comment">

View File

@ -29,9 +29,9 @@
</div> </div>
<main> <main>
<div id="sort"> <div id="sort">
<div id="sort_hot"><a href="/r/{{ sub.name }}/hot">Hot</a></div> <div id="sort_hot"><a href="?sort=hot">Hot</a></div>
<div id="sort_top"><a href="/r/{{ sub.name }}/top">Top</a></div> <div id="sort_top"><a href="?sort=top">Top</a></div>
<div id="sort_new"><a href="/r/{{ sub.name }}/new">New</a></div> <div id="sort_new"><a href="?sort=new">New</a></div>
</div> </div>
{% for post in posts %} {% for post in posts %}
<div class="post"> <div class="post">

View File

@ -29,9 +29,9 @@
</div> </div>
<main> <main>
<div id="sort"> <div id="sort">
<div id="sort_hot"><a href="/u/{{ user.name }}/?sort=hot">Hot</a></div> <div id="sort_hot"><a href="?sort=hot">Hot</a></div>
<div id="sort_top"><a href="/u/{{ user.name }}/?sort=top">Top</a></div> <div id="sort_top"><a href="?sort=top">Top</a></div>
<div id="sort_new"><a href="/u/{{ user.name }}/?sort=new">New</a></div> <div id="sort_new"><a href="?sort=new">New</a></div>
</div> </div>
{% for post in posts %} {% for post in posts %}
<div class="post"> <div class="post">