(#23) Implement FERRIT_SFW_ONLY (#24)

This commit is contained in:
Matt 2022-10-21 20:21:20 -04:00 committed by GitHub
parent 4afd963c64
commit 8906b66cb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 38 additions and 14 deletions

View File

@ -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());
}
@ -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('&') {
let kv: Vec<&str> = param.split('=').collect();
if kv.len() < 2 {
// Reject invalid query parameter.

View File

@ -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());
}

View File

@ -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},
@ -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();

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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;
@ -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> {

View File

@ -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 %}

View File

@ -11,6 +11,10 @@
<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 %}

View File

@ -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">
@ -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">
@ -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>