Skip to content
This repository has been archived by the owner on Nov 7, 2022. It is now read-only.

Implement FERRIT_SFW_ONLY #24

Merged
merged 2 commits into from
Oct 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/duplicates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ pub async fn item(req: Request<Body>) -> Result<Response<Body>, String> {
let post = parse_post(&response[0]["data"]["children"][0]).await;

// Return landing page if this post if this Reddit deems this post
// NSFW, but we have also disabled the display of NSFW content.
if setting(&req, "show_nsfw") != "on" && post.nsfw {
// NSFW, but we have also disabled the display of NSFW content
// or if the instance is SFW-only.
if post.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) {
return Ok(nsfw_landing(req).await.unwrap_or_default());
}

Expand Down Expand Up @@ -125,9 +126,7 @@ pub async fn item(req: Request<Body>) -> Result<Response<Body>, String> {
let query_str = req.uri().query().unwrap_or_default().to_string();

if !query_str.is_empty() {
let query: Vec<&str> = query_str.split('&').collect::<Vec<&str>>();

for param in query.into_iter() {
for param in query_str.split('&') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this. I'm a Rust neophyte so any way my code can be optimized is good by me.

let kv: Vec<&str> = param.split('=').collect();
if kv.len() < 2 {
// Reject invalid query parameter.
Expand Down
5 changes: 3 additions & 2 deletions src/post.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ pub async fn item(req: Request<Body>) -> Result<Response<Body>, String> {
let post = parse_post(&response[0]["data"]["children"][0]).await;

// Return landing page if this post if this Reddit deems this post
// NSFW, but we have also disabled the display of NSFW content.
if setting(&req, "show_nsfw") != "on" && post.nsfw {
// NSFW, but we have also disabled the display of NSFW content
// or if the instance is SFW-only.
if post.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) {
return Ok(nsfw_landing(req).await.unwrap_or_default());
}

Expand Down
9 changes: 7 additions & 2 deletions src/search.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// CRATES
use crate::utils::{catch_random, error, filter_posts, format_num, format_url, get_filters, param, redirect, setting, template, val, Post, Preferences};
use crate::utils::{self, catch_random, error, filter_posts, format_num, format_url, get_filters, param, redirect, setting, template, val, Post, Preferences};
use crate::{
client::json,
subreddit::{can_access_quarantine, quarantine},
Expand Down Expand Up @@ -48,7 +48,12 @@ struct SearchTemplate {

// SERVICES
pub async fn find(req: Request<Body>) -> Result<Response<Body>, String> {
let nsfw_results = if setting(&req, "show_nsfw") == "on" { "&include_over_18=on" } else { "" };
// This ensures that during a search, no NSFW posts are fetched at all
let nsfw_results = if setting(&req, "show_nsfw") == "on" && !utils::sfw_only() {
"&include_over_18=on"
} else {
""
};
let path = format!("{}.json?{}{}&raw_json=1", req.uri().path(), req.uri().query().unwrap_or_default(), nsfw_results);
let query = param(&path, "q").unwrap_or_default();

Expand Down
4 changes: 2 additions & 2 deletions src/subreddit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ pub async fn community(req: Request<Body>) -> Result<Response<Body>, String> {
};

// Return landing page if this post if this is NSFW community but the user
// has disabled the display of NSFW content.
if setting(&req, "show_nsfw") != "on" && sub.nsfw {
// has disabled the display of NSFW content or if the instance is SFW-only.
if sub.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) {
return Ok(nsfw_landing(req).await.unwrap_or_default());
}

Expand Down
5 changes: 3 additions & 2 deletions src/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ pub async fn profile(req: Request<Body>) -> Result<Response<Body>, String> {
let user = user(&username).await.unwrap_or_default();

// Return landing page if this post if this Reddit deems this user NSFW,
// but we have also disabled the display of NSFW content.
if setting(&req, "show_nsfw") != "on" && user.nsfw {
// but we have also disabled the display of NSFW content or if the instance
// is SFW-only.
if user.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) {
return Ok(nsfw_landing(req).await.unwrap_or_default());
}

Expand Down
8 changes: 8 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use regex::Regex;
use rust_embed::RustEmbed;
use serde_json::Value;
use std::collections::{HashMap, HashSet};
use std::env;
use std::str::FromStr;
use time::{macros::format_description, Duration, OffsetDateTime};
use url::Url;
Expand Down Expand Up @@ -849,6 +850,13 @@ pub async fn error(req: Request<Body>, msg: String) -> Result<Response<Body>, St
Ok(Response::builder().status(404).header("content-type", "text/html").body(body.into()).unwrap_or_default())
}

/// Set the FERRIT_SFW_ONLY environment variable to anything, to enable SFW-only mode.
/// If environment variable is set, this bool will be true. Otherwise it will be false.
/// This variable is set by the instance operator, and as such, side-steps the user config
pub fn sfw_only() -> bool {
env::var("FERRIT_SFW_ONLY").is_ok()
}

/// Render the landing page for NSFW content when the user has not enabled
/// "show NSFW posts" in settings.
pub async fn nsfw_landing(req: Request<Body>) -> Result<Response<Body>, String> {
Expand Down
2 changes: 1 addition & 1 deletion templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<nav>
<div id="logo">
<a id="ferrit_logo" href="/"><span id="ferrit_logo_p1">ferr</span><span id="ferrit_logo_p2">it.</span></a>
<span id="version">v{{ env!("CARGO_PKG_VERSION") }}</span>
<span id="version">v{{ env!("CARGO_PKG_VERSION") }}{% if crate::utils::sfw_only() %} <span title="This instance is SFW-only.">💼</span>{% endif %}</span>
{% block subscriptions %}{% endblock %}
</div>
{% block search %}{% endblock %}
Expand Down
4 changes: 4 additions & 0 deletions templates/nsfwlanding.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ <h1>😱 u/{{ res }}'s content is NSFW!</h1>
<h1>😱 This post is NSFW!</h1>
{% endif %}
<br />
{% if crate::utils::sfw_only() %}
<p>This instance of Ferrit is SFW-only.</p>
{% else %}
<p>Enable "Show NSFW posts" in <a href="/settings">settings</a> to view this {% if res_type == crate::utils::ResourceType::Subreddit %}subreddit{% else if res_type == crate::utils::ResourceType::User %}user's posts or comments{% else if res_type == crate::utils::ResourceType::Post %}post{% endif %}.</p>
{% endif %}
</div>
{% endblock %}
6 changes: 6 additions & 0 deletions templates/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
{% call utils::options(prefs.comment_sort, ["confidence", "top", "new", "controversial", "old"], "confidence") %}
</select>
</div>
{% if !crate::utils::sfw_only() %}
<div id="show_nsfw">
<label for="show_nsfw">Show NSFW posts:</label>
<input type="hidden" value="off" name="show_nsfw">
Expand All @@ -59,6 +60,7 @@
<input type="hidden" value="off" name="blur_nsfw">
<input type="checkbox" name="blur_nsfw" {% if prefs.blur_nsfw == "on" %}checked{% endif %}>
</div>
{% endif %}
<div id="autoplay_videos">
<label for="autoplay_videos">Autoplay videos</label>
<input type="hidden" value="off" name="autoplay_videos">
Expand Down Expand Up @@ -116,6 +118,10 @@
<div id="settings_note">
<p><b>Note:</b> settings and subscriptions are saved in browser cookies. Clearing your cookies will reset them.</p><br>
<p>You can restore your current settings and subscriptions after clearing your cookies using <a href="/settings/restore/?theme={{ prefs.theme }}&front_page={{ prefs.front_page }}&layout={{ prefs.layout }}&wide={{ prefs.wide }}&post_sort={{ prefs.post_sort }}&comment_sort={{ prefs.comment_sort }}&show_nsfw={{ prefs.show_nsfw }}&blur_nsfw={{ prefs.blur_nsfw }}&use_hls={{ prefs.use_hls }}&hide_hls_notification={{ prefs.hide_hls_notification }}&subscriptions={{ prefs.subscriptions.join("%2B") }}&filters={{ prefs.filters.join("%2B") }}">this link</a>.</p>
<br />
{% if crate::utils::sfw_only() %}
<p>This instance is SFW-only. It will block all NSFW content.</p>
{% endif %}
</div>
</div>

Expand Down