NSFW Support
This commit is contained in:
parent
3516404a5f
commit
0957f2e339
14
src/post.rs
14
src/post.rs
@ -28,7 +28,7 @@ async fn render(id: String, sort: Option<String>, comment_id: Option<String>) ->
|
||||
// Build the Reddit JSON API url
|
||||
let url: String = match comment_id {
|
||||
None => format!("{}.json?sort={}", id, sorting),
|
||||
Some(val) => format!("{}.json?sort={}&comment={}", id, sorting, val)
|
||||
Some(val) => format!("{}.json?sort={}&comment={}", id, sorting, val),
|
||||
};
|
||||
|
||||
// Send a request to the url, receive JSON in response
|
||||
@ -111,13 +111,18 @@ async fn markdown_to_html(md: &str) -> String {
|
||||
|
||||
// POSTS
|
||||
async fn parse_post(json: serde_json::Value) -> Result<Post, &'static str> {
|
||||
// Retrieve post (as opposed to comments) from JSON
|
||||
let post_data: &serde_json::Value = &json["data"]["children"][0];
|
||||
|
||||
// Grab UTC time as unix timestamp
|
||||
let unix_time: i64 = post_data["data"]["created_utc"].as_f64().unwrap().round() as i64;
|
||||
// Parse post score
|
||||
let score = post_data["data"]["score"].as_i64().unwrap();
|
||||
|
||||
// Determine the type of media along with the media URL
|
||||
let media = media(&post_data["data"]).await;
|
||||
|
||||
// Build a post using data parsed from Reddit post API
|
||||
let post = Post {
|
||||
title: val(post_data, "title").await,
|
||||
community: val(post_data, "subreddit").await,
|
||||
@ -131,8 +136,6 @@ async fn parse_post(json: serde_json::Value) -> Result<Post, &'static str> {
|
||||
url: val(post_data, "permalink").await,
|
||||
score: format_num(score),
|
||||
post_type: media.0,
|
||||
media: media.1,
|
||||
time: Utc.timestamp(unix_time, 0).format("%b %e %Y %H:%M UTC").to_string(),
|
||||
flair: Flair(
|
||||
val(post_data, "link_flair_text").await,
|
||||
val(post_data, "link_flair_background_color").await,
|
||||
@ -142,6 +145,9 @@ async fn parse_post(json: serde_json::Value) -> Result<Post, &'static str> {
|
||||
"white".to_string()
|
||||
},
|
||||
),
|
||||
nsfw: post_data["data"]["over_18"].as_bool().unwrap_or(false),
|
||||
media: media.1,
|
||||
time: Utc.timestamp(unix_time, 0).format("%b %e %Y %H:%M UTC").to_string(),
|
||||
};
|
||||
|
||||
Ok(post)
|
||||
@ -156,7 +162,7 @@ async fn parse_comments(json: serde_json::Value) -> Result<Vec<Comment>, &'stati
|
||||
let mut comments: Vec<Comment> = Vec::new();
|
||||
|
||||
// For each comment, retrieve the values to build a Comment object
|
||||
for comment in comment_data.iter() {
|
||||
for comment in comment_data {
|
||||
let unix_time: i64 = comment["data"]["created_utc"].as_f64().unwrap_or(0.0).round() as i64;
|
||||
if unix_time == 0 {
|
||||
continue;
|
||||
|
19
src/utils.rs
19
src/utils.rs
@ -11,11 +11,9 @@ use base64::encode;
|
||||
//
|
||||
// STRUCTS
|
||||
//
|
||||
#[allow(dead_code)]
|
||||
// Post flair with text, background color and foreground color
|
||||
pub struct Flair(pub String, pub String, pub String);
|
||||
|
||||
#[allow(dead_code)]
|
||||
// Post containing content, metadata and media
|
||||
pub struct Post {
|
||||
pub title: String,
|
||||
@ -26,12 +24,12 @@ pub struct Post {
|
||||
pub url: String,
|
||||
pub score: String,
|
||||
pub post_type: String,
|
||||
pub flair: Flair,
|
||||
pub nsfw: bool,
|
||||
pub media: String,
|
||||
pub time: String,
|
||||
pub flair: Flair,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
// Comment with content, post, score and data/time that it was posted
|
||||
pub struct Comment {
|
||||
pub id: String,
|
||||
@ -43,7 +41,6 @@ pub struct Comment {
|
||||
pub replies: Vec<Comment>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
// User struct containing metadata about user
|
||||
pub struct User {
|
||||
pub name: String,
|
||||
@ -53,7 +50,6 @@ pub struct User {
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
// Subreddit struct containing metadata about community
|
||||
pub struct Subreddit {
|
||||
pub name: String,
|
||||
@ -105,19 +101,16 @@ pub fn format_num(num: i64) -> String {
|
||||
// JSON PARSING
|
||||
//
|
||||
|
||||
#[allow(dead_code)]
|
||||
// val() function used to parse JSON from Reddit APIs
|
||||
pub async fn val(j: &serde_json::Value, k: &str) -> String {
|
||||
String::from(j["data"][k].as_str().unwrap_or(""))
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
// nested_val() function used to parse JSON from Reddit APIs
|
||||
pub async fn nested_val(j: &serde_json::Value, n: &str, k: &str) -> String {
|
||||
String::from(j["data"][n][k].as_str().unwrap())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub async fn fetch_posts(url: String, fallback_title: String) -> Result<(Vec<Post>, String), &'static str> {
|
||||
// Send a request to the url, receive JSON in response
|
||||
let req = request(url).await;
|
||||
@ -135,7 +128,7 @@ pub async fn fetch_posts(url: String, fallback_title: String) -> Result<(Vec<Pos
|
||||
|
||||
let mut posts: Vec<Post> = Vec::new();
|
||||
|
||||
for post in post_list.iter() {
|
||||
for post in post_list {
|
||||
let img = if val(post, "thumbnail").await.starts_with("https:/") {
|
||||
format_url(val(post, "thumbnail").await.as_str()).await
|
||||
} else {
|
||||
@ -158,8 +151,6 @@ pub async fn fetch_posts(url: String, fallback_title: String) -> Result<(Vec<Pos
|
||||
score: format_num(score),
|
||||
post_type: "link".to_string(),
|
||||
media: img,
|
||||
url: val(post, "permalink").await,
|
||||
time: Utc.timestamp(unix_time, 0).format("%b %e '%y").to_string(),
|
||||
flair: Flair(
|
||||
val(post, "link_flair_text").await,
|
||||
val(post, "link_flair_background_color").await,
|
||||
@ -169,6 +160,9 @@ pub async fn fetch_posts(url: String, fallback_title: String) -> Result<(Vec<Pos
|
||||
"white".to_string()
|
||||
},
|
||||
),
|
||||
nsfw: post["data"]["over_18"].as_bool().unwrap_or(false),
|
||||
url: val(post, "permalink").await,
|
||||
time: Utc.timestamp(unix_time, 0).format("%b %e '%y").to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
@ -180,7 +174,6 @@ pub async fn fetch_posts(url: String, fallback_title: String) -> Result<(Vec<Pos
|
||||
//
|
||||
|
||||
// Make a request to a Reddit API and parse the JSON response
|
||||
#[allow(dead_code)]
|
||||
pub async fn request(mut url: String) -> Result<serde_json::Value, &'static str> {
|
||||
url = format!("https://www.reddit.com/{}", url);
|
||||
|
||||
|
@ -48,6 +48,7 @@ main {
|
||||
footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
button {
|
||||
@ -199,6 +200,21 @@ a:not(.post_right):hover {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.post_score {
|
||||
margin-top: 20px;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.nsfw {
|
||||
color: #FF5C5D;
|
||||
margin-top: 20px;
|
||||
border: 1px solid #FF5C5D;
|
||||
padding: 5px;
|
||||
font-size: 12px;
|
||||
border-radius: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.post_subreddit {
|
||||
font-weight: bold;
|
||||
}
|
||||
@ -207,11 +223,6 @@ a:not(.post_right):hover {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.post_score {
|
||||
margin-top: 20px;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.post_right {
|
||||
padding: 20px 25px;
|
||||
flex-grow: 1;
|
||||
|
@ -12,6 +12,7 @@
|
||||
<div class="post">
|
||||
<div class="post_left">
|
||||
<h3 class="post_score">{{ post.score }}</h3>
|
||||
{% if post.nsfw %}<div class="nsfw">NSFW</div>{% endif %}
|
||||
</div>
|
||||
<div class="post_right">
|
||||
<h4>
|
||||
|
@ -27,6 +27,7 @@
|
||||
<div class="post highlighted">
|
||||
<div class="post_left">
|
||||
<h3 class="post_score">{{ post.score }}</h3>
|
||||
{% if post.nsfw %}<div class="nsfw">NSFW</div>{% endif %}
|
||||
</div>
|
||||
<div class="post_right">
|
||||
<h4>
|
||||
|
@ -31,6 +31,7 @@
|
||||
<div class="post">
|
||||
<div class="post_left">
|
||||
<h3 class="post_score">{{ post.score }}</h3>
|
||||
{% if post.nsfw %}<div class="nsfw">NSFW</div>{% endif %}
|
||||
</div>
|
||||
<div class="post_right">
|
||||
<h4>
|
||||
|
@ -25,6 +25,7 @@
|
||||
<div class='post'>
|
||||
<div class="post_left">
|
||||
<h3 class="post_score">{{ post.score }}</h3>
|
||||
{% if post.nsfw %}<div class="nsfw">NSFW</div>{% endif %}
|
||||
</div>
|
||||
<div class="post_right">
|
||||
<h4>
|
||||
|
Loading…
x
Reference in New Issue
Block a user