Add the NSFW mode
This commit is contained in:
parent
f0a3ce06fa
commit
5b6609a46f
10 changed files with 239 additions and 12 deletions
|
@ -55,3 +55,5 @@ You can set the following variables in the `.env` file:
|
||||||
* `KHAGANAT_FORCE_HTTPS`: If True, enable the use of `KHAGANAT_HTTPS_HEADER_NAME` and `KHAGANAT_HTTPS_HEADER_VALUE` to set the `SECURE_PROXY_SSL_HEADER` configuration option. Default is `False`.
|
* `KHAGANAT_FORCE_HTTPS`: If True, enable the use of `KHAGANAT_HTTPS_HEADER_NAME` and `KHAGANAT_HTTPS_HEADER_VALUE` to set the `SECURE_PROXY_SSL_HEADER` configuration option. Default is `False`.
|
||||||
* `KHAGANAT_HTTPS_HEADER_NAME`: Header name for `SECURE_PROXY_SSL_HEADER`, default is `HTTP_X_FORWARDED_PROTO`.
|
* `KHAGANAT_HTTPS_HEADER_NAME`: Header name for `SECURE_PROXY_SSL_HEADER`, default is `HTTP_X_FORWARDED_PROTO`.
|
||||||
* `KHAGANAT_HTTPS_HEADER_VALUE`: Header value for `SECURE_PROXY_SSL_HEADER`, default is `https`.
|
* `KHAGANAT_HTTPS_HEADER_VALUE`: Header value for `SECURE_PROXY_SSL_HEADER`, default is `https`.
|
||||||
|
* `KHAGANAT_NSFW_TAGS`: Coma-separated list of words that triggers the content warning in logs, default is `\#nsfw`.
|
||||||
|
* `KHAGANAT_NSFW_NAME`: Name of the cookie holding the NSFW allowance, default is `nsfw_allowed`.
|
||||||
|
|
|
@ -183,3 +183,10 @@ if config('KHAGANAT_FORCE_HTTPS', default=False, cast=bool):
|
||||||
config('KHAGANAT_HTTPS_HEADER_NAME', default='HTTP_X_FORWARDED_PROTO'),
|
config('KHAGANAT_HTTPS_HEADER_NAME', default='HTTP_X_FORWARDED_PROTO'),
|
||||||
config('KHAGANAT_HTTPS_HEADER_VALUE', default='https')
|
config('KHAGANAT_HTTPS_HEADER_VALUE', default='https')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# NSFW
|
||||||
|
|
||||||
|
KHAGANAT_NSFW_TAGS = config('KHAGANAT_NSFW_TAGS', default='\\#nsfw', cast=Csv())
|
||||||
|
KHAGANAT_NSFW_NAME = config('KHAGANAT_NSFW_NAME', default='nsfw_allowed')
|
||||||
|
KHAGANAT_NSFW_OK = ('y', 'yes', 't', 'true', '1')
|
||||||
|
|
|
@ -6,6 +6,7 @@ from django.views import generic
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
|
from neluser import nsfw
|
||||||
from .models import Source, Entry
|
from .models import Source, Entry
|
||||||
from .forms import SearchForm
|
from .forms import SearchForm
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -102,6 +103,19 @@ class EntriesView(generic.ListView):
|
||||||
template_name = 'logs/entries.html'
|
template_name = 'logs/entries.html'
|
||||||
allow_empty = False
|
allow_empty = False
|
||||||
|
|
||||||
|
def is_nsfw(self):
|
||||||
|
for e in self.get_queryset():
|
||||||
|
for tag in settings.KHAGANAT_NSFW_TAGS:
|
||||||
|
if tag.lower() in e.content.lower():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
if not nsfw.is_nsfw_allowed(request):
|
||||||
|
if self.is_nsfw():
|
||||||
|
return nsfw.redirect(request)
|
||||||
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context['date'] = datetime.date(
|
context['date'] = datetime.date(
|
||||||
|
|
|
@ -2,7 +2,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 1.0\n"
|
"Project-Id-Version: 1.0\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2018-02-04 15:56+0100\n"
|
"POT-Creation-Date: 2018-05-27 18:28+0200\n"
|
||||||
"PO-Revision-Date: 2018-02-04 01:03+0100\n"
|
"PO-Revision-Date: 2018-02-04 01:03+0100\n"
|
||||||
"Last-Translator: Khaganat <assoc@khaganat.net>\n"
|
"Last-Translator: Khaganat <assoc@khaganat.net>\n"
|
||||||
"Language-Team: Khaganat <assoc@khaganat.net>\n"
|
"Language-Team: Khaganat <assoc@khaganat.net>\n"
|
||||||
|
@ -38,11 +38,19 @@ msgstr ""
|
||||||
msgid "date joined"
|
msgid "date joined"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: models.py:65
|
#: models.py:58
|
||||||
|
msgid "NSFW flag"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:61
|
||||||
|
msgid "Indicate whether or not adult or sensitive content should be displayed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: models.py:73
|
||||||
msgid "user"
|
msgid "user"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: models.py:66
|
#: models.py:74
|
||||||
msgid "users"
|
msgid "users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -58,6 +66,7 @@ msgstr "Your account has been activated."
|
||||||
|
|
||||||
#: templates/neluser/activate_done.html:10 templates/neluser/login.html:4
|
#: templates/neluser/activate_done.html:10 templates/neluser/login.html:4
|
||||||
#: templates/neluser/login.html:12
|
#: templates/neluser/login.html:12
|
||||||
|
#: templates/neluser/password_reset_done.html:10
|
||||||
msgid "login"
|
msgid "login"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -97,6 +106,40 @@ msgstr ""
|
||||||
msgid "forgotten_password"
|
msgid "forgotten_password"
|
||||||
msgstr "forgotten password"
|
msgstr "forgotten password"
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:4 templates/neluser/nsfw.html:8
|
||||||
|
msgid "NSFW content"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:9
|
||||||
|
msgid ""
|
||||||
|
"The content you were about to see is flagged as sensitive and therefore "
|
||||||
|
"cannot be seen while the safe mode is activated."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:11
|
||||||
|
msgid "Go back home"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:12
|
||||||
|
msgid "Permanently disable safe mode"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:14
|
||||||
|
msgid "Or disable safe mode for:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:15
|
||||||
|
msgid "5 minutes"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:16
|
||||||
|
msgid "1 hour"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:17
|
||||||
|
msgid "1 day"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: templates/neluser/password_reset.html:4
|
#: templates/neluser/password_reset.html:4
|
||||||
#: templates/neluser/password_reset_confirm.html:4
|
#: templates/neluser/password_reset_confirm.html:4
|
||||||
#: templates/neluser/password_reset_done.html:4
|
#: templates/neluser/password_reset_done.html:4
|
||||||
|
@ -120,7 +163,7 @@ msgstr "change my password"
|
||||||
msgid "reset_password_invalid_link"
|
msgid "reset_password_invalid_link"
|
||||||
msgstr "Sorry, we are unable to reset your password."
|
msgstr "Sorry, we are unable to reset your password."
|
||||||
|
|
||||||
#: templates/neluser/password_reset_done.html:8
|
#: templates/neluser/password_reset_done.html:9
|
||||||
msgid "password_reset_success"
|
msgid "password_reset_success"
|
||||||
msgstr "Your password has been changed."
|
msgstr "Your password has been changed."
|
||||||
|
|
||||||
|
@ -139,8 +182,9 @@ msgstr ""
|
||||||
|
|
||||||
#: templates/neluser/password_reset_email_sent.html:8
|
#: templates/neluser/password_reset_email_sent.html:8
|
||||||
msgid "password_reset_success_email"
|
msgid "password_reset_success_email"
|
||||||
msgstr "An email has been sent to your address. Please follow the link given "
|
msgstr ""
|
||||||
"in this email to reset your password."
|
"An email has been sent to your address. Please follow the link given in this "
|
||||||
|
"email to reset your password."
|
||||||
|
|
||||||
#: templates/neluser/password_reset_email_subject.txt:2
|
#: templates/neluser/password_reset_email_subject.txt:2
|
||||||
#, python-format
|
#, python-format
|
||||||
|
|
|
@ -2,7 +2,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 1.0\n"
|
"Project-Id-Version: 1.0\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2018-02-04 15:56+0100\n"
|
"POT-Creation-Date: 2018-05-27 18:28+0200\n"
|
||||||
"PO-Revision-Date: 2018-02-04 01:03+0100\n"
|
"PO-Revision-Date: 2018-02-04 01:03+0100\n"
|
||||||
"Last-Translator: Khaganat <assoc@khaganat.net>\n"
|
"Last-Translator: Khaganat <assoc@khaganat.net>\n"
|
||||||
"Language-Team: Khaganat <assoc@khaganat.net>\n"
|
"Language-Team: Khaganat <assoc@khaganat.net>\n"
|
||||||
|
@ -40,11 +40,19 @@ msgstr ""
|
||||||
msgid "date joined"
|
msgid "date joined"
|
||||||
msgstr "date d'inscription"
|
msgstr "date d'inscription"
|
||||||
|
|
||||||
#: models.py:65
|
#: models.py:58
|
||||||
|
msgid "NSFW flag"
|
||||||
|
msgstr "Affichage du contenu sensible"
|
||||||
|
|
||||||
|
#: models.py:61
|
||||||
|
msgid "Indicate whether or not adult or sensitive content should be displayed."
|
||||||
|
msgstr "Indique si le contenu adulte ou choquant doit être ou non affiché."
|
||||||
|
|
||||||
|
#: models.py:73
|
||||||
msgid "user"
|
msgid "user"
|
||||||
msgstr "utilisateur"
|
msgstr "utilisateur"
|
||||||
|
|
||||||
#: models.py:66
|
#: models.py:74
|
||||||
msgid "users"
|
msgid "users"
|
||||||
msgstr "utilisateurs"
|
msgstr "utilisateurs"
|
||||||
|
|
||||||
|
@ -60,6 +68,7 @@ msgstr "compte activé"
|
||||||
|
|
||||||
#: templates/neluser/activate_done.html:10 templates/neluser/login.html:4
|
#: templates/neluser/activate_done.html:10 templates/neluser/login.html:4
|
||||||
#: templates/neluser/login.html:12
|
#: templates/neluser/login.html:12
|
||||||
|
#: templates/neluser/password_reset_done.html:10
|
||||||
msgid "login"
|
msgid "login"
|
||||||
msgstr "connexion"
|
msgstr "connexion"
|
||||||
|
|
||||||
|
@ -99,6 +108,43 @@ msgstr "Activation de compte sur %(site_name)s"
|
||||||
msgid "forgotten_password"
|
msgid "forgotten_password"
|
||||||
msgstr "mot de passe oublié"
|
msgstr "mot de passe oublié"
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:4 templates/neluser/nsfw.html:8
|
||||||
|
msgid "NSFW content"
|
||||||
|
msgstr "Contenu sensible"
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:9
|
||||||
|
msgid ""
|
||||||
|
"The content you were about to see is flagged as sensitive and therefore "
|
||||||
|
"cannot be seen while the safe mode is activated."
|
||||||
|
msgstr ""
|
||||||
|
"Le contenu que vous vous apprêtiez à consulter est indiqué comme pouvant "
|
||||||
|
"choquer la sensibilité et ne peut donc pas être affiché tant que la "
|
||||||
|
"navigation filtrée est activée."
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:11
|
||||||
|
msgid "Go back home"
|
||||||
|
msgstr "Retourner à l'accueil"
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:12
|
||||||
|
msgid "Permanently disable safe mode"
|
||||||
|
msgstr "Définitivement désactiver la navigation filtrée"
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:14
|
||||||
|
msgid "Or disable safe mode for:"
|
||||||
|
msgstr "Ou désactiver la navigation filtrée pour :"
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:15
|
||||||
|
msgid "5 minutes"
|
||||||
|
msgstr "5 minutes"
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:16
|
||||||
|
msgid "1 hour"
|
||||||
|
msgstr "1 heure"
|
||||||
|
|
||||||
|
#: templates/neluser/nsfw.html:17
|
||||||
|
msgid "1 day"
|
||||||
|
msgstr "1 jour"
|
||||||
|
|
||||||
#: templates/neluser/password_reset.html:4
|
#: templates/neluser/password_reset.html:4
|
||||||
#: templates/neluser/password_reset_confirm.html:4
|
#: templates/neluser/password_reset_confirm.html:4
|
||||||
#: templates/neluser/password_reset_done.html:4
|
#: templates/neluser/password_reset_done.html:4
|
||||||
|
@ -122,7 +168,7 @@ msgstr "Modifier mon mot de passe"
|
||||||
msgid "reset_password_invalid_link"
|
msgid "reset_password_invalid_link"
|
||||||
msgstr "Désolé, nous ne sommes pas en mesure de modifier votre mot de passe."
|
msgstr "Désolé, nous ne sommes pas en mesure de modifier votre mot de passe."
|
||||||
|
|
||||||
#: templates/neluser/password_reset_done.html:8
|
#: templates/neluser/password_reset_done.html:9
|
||||||
msgid "password_reset_success"
|
msgid "password_reset_success"
|
||||||
msgstr "Votre mot de passe a été modifié."
|
msgstr "Votre mot de passe a été modifié."
|
||||||
|
|
||||||
|
@ -144,8 +190,9 @@ msgstr ""
|
||||||
|
|
||||||
#: templates/neluser/password_reset_email_sent.html:8
|
#: templates/neluser/password_reset_email_sent.html:8
|
||||||
msgid "password_reset_success_email"
|
msgid "password_reset_success_email"
|
||||||
msgstr "Un message a été envoyé sur votre messagerie électronique. Veuillez "
|
msgstr ""
|
||||||
"suivre le lien donné dans ce message afin de réinitialiser votre mot de passe."
|
"Un message a été envoyé sur votre messagerie électronique. Veuillez suivre "
|
||||||
|
"le lien donné dans ce message afin de réinitialiser votre mot de passe."
|
||||||
|
|
||||||
#: templates/neluser/password_reset_email_subject.txt:2
|
#: templates/neluser/password_reset_email_subject.txt:2
|
||||||
#, python-format
|
#, python-format
|
||||||
|
|
18
neluser/migrations/0003_neluser_nsfw_allowed.py
Normal file
18
neluser/migrations/0003_neluser_nsfw_allowed.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.0.2 on 2018-05-27 10:04
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('neluser', '0002_auto_20180204_2035'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='neluser',
|
||||||
|
name='nsfw_allowed',
|
||||||
|
field=models.BooleanField(default=False, help_text='Indicate whether or not adult or sensitive content should be displayed.', verbose_name='NSFW flag'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -54,6 +54,14 @@ class NelUser(AbstractBaseUser, PermissionsMixin):
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
|
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
|
||||||
|
nsfw_allowed = models.BooleanField(
|
||||||
|
_('NSFW flag'),
|
||||||
|
default=False,
|
||||||
|
help_text=_(
|
||||||
|
'Indicate whether or not adult or sensitive content should '
|
||||||
|
'be displayed.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
objects = NelUserManager()
|
objects = NelUserManager()
|
||||||
|
|
||||||
|
|
62
neluser/nsfw.py
Normal file
62
neluser/nsfw.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
from django.http import HttpResponseRedirect, QueryDict
|
||||||
|
from django.urls.exceptions import Resolver404
|
||||||
|
from django.shortcuts import render
|
||||||
|
from neluser.models import NelUser
|
||||||
|
from django.urls import reverse, resolve
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
def is_link_legit(url):
|
||||||
|
try:
|
||||||
|
resolve(url)
|
||||||
|
except Resolver404:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def is_nsfw_allowed(request):
|
||||||
|
if isinstance(request.user, NelUser):
|
||||||
|
if request.user.nsfw_allowed:
|
||||||
|
return True
|
||||||
|
s = request.COOKIES.get(settings.KHAGANAT_NSFW_NAME) or ''
|
||||||
|
return s.lower() in settings.KHAGANAT_NSFW_OK
|
||||||
|
|
||||||
|
|
||||||
|
def disable_view(request, max_age):
|
||||||
|
try:
|
||||||
|
max_age = int(max_age) or None
|
||||||
|
except ValueError:
|
||||||
|
max_age = None
|
||||||
|
next_url = QueryDict(request.META.get('QUERY_STRING')).get('next') or '/'
|
||||||
|
if not is_link_legit(next_url):
|
||||||
|
next_url = '/'
|
||||||
|
response = HttpResponseRedirect(next_url)
|
||||||
|
if isinstance(request.user, NelUser) and not max_age:
|
||||||
|
request.user.nsfw_allowed = True
|
||||||
|
request.user.save()
|
||||||
|
else:
|
||||||
|
response.set_cookie(
|
||||||
|
settings.KHAGANAT_NSFW_NAME,
|
||||||
|
'true',
|
||||||
|
max_age=max_age
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def warn_view(request):
|
||||||
|
next_url = QueryDict(request.META.get('QUERY_STRING')).get('next') or '/'
|
||||||
|
if not is_link_legit(next_url):
|
||||||
|
next_url = '/'
|
||||||
|
context = {
|
||||||
|
'next_url': next_url,
|
||||||
|
'is_authenticated': request.user.is_authenticated,
|
||||||
|
}
|
||||||
|
return render(request, 'neluser/nsfw.html', context=context)
|
||||||
|
|
||||||
|
|
||||||
|
def redirect(request):
|
||||||
|
dest = '{to_url}?next={next_url}'.format(
|
||||||
|
to_url=reverse(warn_view),
|
||||||
|
next_url=request.get_full_path()
|
||||||
|
)
|
||||||
|
return HttpResponseRedirect(dest)
|
20
neluser/templates/neluser/nsfw.html
Normal file
20
neluser/templates/neluser/nsfw.html
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{% extends "khaganat/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{% trans "NSFW content" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="content-bloc">
|
||||||
|
<h2>{% trans "NSFW content" %}</h2>
|
||||||
|
<p>{% trans "The content you were about to see is flagged as sensitive and therefore cannot be seen while the safe mode is activated." %}</p>
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-primary" href="{% url "index" %}" role="button">{% trans "Go back home" %}</a>
|
||||||
|
<a class="btn btn-danger" href="{% url "disable_nsfw" "0" %}?next={{ next_url }}" role="button">{% trans "Permanently disable safe mode" %}</a>
|
||||||
|
<br>
|
||||||
|
{% trans "Or disable safe mode for:" %}
|
||||||
|
<a class="badge badge-warning" href="{% url "disable_nsfw" "300" %}?next={{ next_url }}">{% trans "5 minutes" %}</a>
|
||||||
|
<a class="badge badge-warning" href="{% url "disable_nsfw" "3600" %}?next={{ next_url }}">{% trans "1 hour" %}</a>
|
||||||
|
<a class="badge badge-warning" href="{% url "disable_nsfw" "86400" %}?next={{ next_url }}">{% trans "1 day" %}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -1,6 +1,7 @@
|
||||||
from django.contrib.auth import views as auth_views
|
from django.contrib.auth import views as auth_views
|
||||||
from django.urls import reverse_lazy, path
|
from django.urls import reverse_lazy, path
|
||||||
from . import views
|
from . import views
|
||||||
|
from . import nsfw
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
@ -61,4 +62,8 @@ urlpatterns = [
|
||||||
),
|
),
|
||||||
name='password_reset_complete'
|
name='password_reset_complete'
|
||||||
),
|
),
|
||||||
|
|
||||||
|
# NSFW
|
||||||
|
path('nsfw/', nsfw.warn_view, name='nsfw'),
|
||||||
|
path('nsfw/disable/<max_age>/', nsfw.disable_view, name='disable_nsfw'),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue