Format code using black

This commit is contained in:
Rodolphe Breard 2019-07-24 19:07:41 +02:00
parent 7f1e07503a
commit c15512e799
29 changed files with 412 additions and 475 deletions

View file

@ -1,7 +1,9 @@
from django.contrib import admin
from .models import LogSource
class LogSourceAdmin(admin.ModelAdmin):
list_display = ('name', 'slug', 'hidden')
list_display = ("name", "slug", "hidden")
admin.site.register(LogSource, LogSourceAdmin)

View file

@ -2,4 +2,4 @@ from django.apps import AppConfig
class LogsConfig(AppConfig):
name = 'chat'
name = "chat"

View file

@ -7,8 +7,8 @@ import datetime
class SearchForm(forms.Form):
source = forms.CharField(max_length=128)
date = forms.DateField(
label=_('date'),
label=_("date"),
initial=datetime.date.today(),
widget=DateInput(format='%Y-%m-%d'),
input_formats=['%Y-%m-%d'],
widget=DateInput(format="%Y-%m-%d"),
input_formats=["%Y-%m-%d"],
)

View file

@ -3,7 +3,7 @@ from chat.models import Entry
class Command(BaseCommand):
help = 'Generates the CSS files used by Pygments'
help = "Generates the CSS files used by Pygments"
def handle(self, *args, **options):
for e in Entry.objects.all():

View file

@ -3,22 +3,20 @@ from . import views
urlpatterns = [
path('', views.chat_view, name='chat'),
path('logs/', views.LogEntriesView.as_view(), name='log_index'),
path("", views.chat_view, name="chat"),
path("logs/", views.LogEntriesView.as_view(), name="log_index"),
path(
'logs/<slug:source>/<int:year>/<int:month>/<int:day>/',
"logs/<slug:source>/<int:year>/<int:month>/<int:day>/",
views.LogEntriesView.as_view(),
name='log_day'
name="log_day",
),
path(
'logs/switch/source/<int:pk>/',
"logs/switch/source/<int:pk>/",
views.switch_log_source,
name='log_switch_source'
name="log_switch_source",
),
path(
'logs/switch/entry/<int:pk>/',
views.switch_log_entry,
name='log_switch_entry'
"logs/switch/entry/<int:pk>/", views.switch_log_entry, name="log_switch_entry"
),
path('logs/search/', views.log_search_view, name='log_search'),
path("logs/search/", views.log_search_view, name="log_search"),
]

View file

@ -15,22 +15,19 @@ import datetime
def chat_view(request):
ctx = {
'debug': settings.DEBUG,
'bosh_url': settings.KHAGANAT_XMPP_BOSH_URL,
'jid': settings.KHAGANAT_XMPP_JID,
'rooms': settings.KHAGANAT_XMPP_ROOMS,
'websocket_url': settings.KHAGANAT_XMPP_WEBSOCKET_URL,
"debug": settings.DEBUG,
"bosh_url": settings.KHAGANAT_XMPP_BOSH_URL,
"jid": settings.KHAGANAT_XMPP_JID,
"rooms": settings.KHAGANAT_XMPP_ROOMS,
"websocket_url": settings.KHAGANAT_XMPP_WEBSOCKET_URL,
}
return render(request, 'chat/chat_conversejs.html', ctx)
return render(request, "chat/chat_conversejs.html", ctx)
def _get_dates():
now = datetime.date.today()
start_date = now - datetime.timedelta(
days=settings.KHAGANAT_LOGS_MAX_DAYS
)
end_date = now - datetime.timedelta(
days=settings.KHAGANAT_LOGS_MIN_DAYS - 1
)
start_date = now - datetime.timedelta(days=settings.KHAGANAT_LOGS_MAX_DAYS)
end_date = now - datetime.timedelta(days=settings.KHAGANAT_LOGS_MIN_DAYS - 1)
return (now, start_date, end_date)
@ -39,9 +36,9 @@ def _switch_hidden(request, obj, pk):
e.hidden = not e.hidden
e.save()
next_page = request.GET.get('next', '/')
next_page = request.GET.get("next", "/")
if not is_link_legit(next_page):
next_page = reverse('log_index')
next_page = reverse("log_index")
return redirect(next_page)
@ -56,22 +53,27 @@ def switch_log_entry(request, pk):
def log_search_view(request):
if request.method == 'POST':
if request.method == "POST":
form = SearchForm(request.POST)
if form.is_valid():
date = form.cleaned_data['date']
return redirect(reverse('log_day', kwargs={
'source': form.cleaned_data['source'],
'year': date.year,
'month': date.month,
'day': date.day,
}))
raise Http404('No search parameters.')
date = form.cleaned_data["date"]
return redirect(
reverse(
"log_day",
kwargs={
"source": form.cleaned_data["source"],
"year": date.year,
"month": date.month,
"day": date.day,
},
)
)
raise Http404("No search parameters.")
class LogEntriesView(generic.ListView):
template_name = 'chat/entries.html'
context_object_name = 'entries'
template_name = "chat/entries.html"
context_object_name = "entries"
filter_nsfw = False
def is_nsfw(self):
@ -93,17 +95,17 @@ class LogEntriesView(generic.ListView):
"""Return the date object corresponding to the URL parameters
or None if missing.
"""
has_date = all([
self.kwargs.get('year') is not None,
self.kwargs.get('month') is not None,
self.kwargs.get('day') is not None,
])
has_date = all(
[
self.kwargs.get("year") is not None,
self.kwargs.get("month") is not None,
self.kwargs.get("day") is not None,
]
)
if not has_date:
return None
return datetime.date(
self.kwargs['year'],
self.kwargs['month'],
self.kwargs['day']
self.kwargs["year"], self.kwargs["month"], self.kwargs["day"]
)
def get_dates(self, source):
@ -114,26 +116,22 @@ class LogEntriesView(generic.ListView):
nb_max = settings.KHAGANAT_LOGS_MAX_DAYS
nb_max -= settings.KHAGANAT_LOGS_MIN_DAYS
lst = LogEntry.objects.filter(
source=source,
)
lst = LogEntry.objects.filter(source=source)
if not self.request.user.is_staff:
lst = lst.filter(
hidden=False,
created__range=(start_date, end_date)
)
lst = lst.annotate(
date=TruncDate('created')
).values('date').annotate(
nb=Count('date')
).order_by('-date')[:nb_max]
return [o['date'] for o in lst]
lst = lst.filter(hidden=False, created__range=(start_date, end_date))
lst = (
lst.annotate(date=TruncDate("created"))
.values("date")
.annotate(nb=Count("date"))
.order_by("-date")[:nb_max]
)
return [o["date"] for o in lst]
def get_source(self):
"""Return the current source."""
if self.kwargs.get('source') is None:
if self.kwargs.get("source") is None:
return None
return LogSource.objects.get(slug=self.kwargs['source'])
return LogSource.objects.get(slug=self.kwargs["source"])
def get_sources(self):
"""Return available sources."""
@ -144,32 +142,29 @@ class LogEntriesView(generic.ListView):
qs = qs.filter(
hidden=False,
source__hidden=False,
created__range=(start_date, end_date)
created__range=(start_date, end_date),
)
qs = qs.values(
'source', 'source__name', 'source__slug',
'source__id', 'source__hidden'
).annotate(
nb=Count('id')
)
"source", "source__name", "source__slug", "source__id", "source__hidden"
).annotate(nb=Count("id"))
out = []
for src in qs:
dts = self.get_dates(src['source'])
src['first_date'] = dts[0] if dts else None
dts = self.get_dates(src["source"])
src["first_date"] = dts[0] if dts else None
out.append(src)
return out
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = SearchForm()
context['sources'] = self.get_sources()
context['current_source'] = self.get_source()
context['dates'] = self.get_dates(context['current_source'])
context['current_date'] = self.get_date()
context['filter_nsfw'] = self.filter_nsfw
context['current_url'] = self.request.get_full_path()
context["form"] = SearchForm()
context["sources"] = self.get_sources()
context["current_source"] = self.get_source()
context["dates"] = self.get_dates(context["current_source"])
context["current_date"] = self.get_date()
context["filter_nsfw"] = self.filter_nsfw
context["current_url"] = self.request.get_full_path()
return context
def get_queryset(self):
@ -180,10 +175,12 @@ class LogEntriesView(generic.ListView):
is_staff = self.request.user.is_staff
now = datetime.date.today()
out_of_bounds = any((
(now - dt).days > settings.KHAGANAT_LOGS_MAX_DAYS,
(now - dt).days < settings.KHAGANAT_LOGS_MIN_DAYS,
))
out_of_bounds = any(
(
(now - dt).days > settings.KHAGANAT_LOGS_MAX_DAYS,
(now - dt).days < settings.KHAGANAT_LOGS_MIN_DAYS,
)
)
if out_of_bounds and not is_staff:
return LogEntry.objects.none()
src = self.get_source()
@ -191,14 +188,11 @@ class LogEntriesView(generic.ListView):
return LogEntry.objects.none()
if src.hidden and not is_staff:
return LogEntry.objects.none()
qs = LogEntry.objects.filter(
source=src,
created__year=dt.year
).filter(
created__month=dt.month,
).filter(
created__day=dt.day
qs = (
LogEntry.objects.filter(source=src, created__year=dt.year)
.filter(created__month=dt.month)
.filter(created__day=dt.day)
)
if not is_staff:
qs = qs.filter(hidden=False)
return qs.order_by('created')
return qs.order_by("created")

View file

@ -2,4 +2,4 @@ from django.apps import AppConfig
class KhaganatConfig(AppConfig):
name = 'khaganat'
name = "khaganat"

View file

@ -24,73 +24,73 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config('KHAGANAT_SECRET_KEY')
SECRET_KEY = config("KHAGANAT_SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config('KHAGANAT_DEBUG', default=False, cast=bool)
DEBUG = config("KHAGANAT_DEBUG", default=False, cast=bool)
ALLOWED_HOSTS = config('KHAGANAT_HOSTNAMES', default='', cast=Csv())
INTERNAL_IPS = config('KHAGANAT_INTERNAL_IPS', default='127.0.0.1,::1', cast=Csv())
ALLOWED_HOSTS = config("KHAGANAT_HOSTNAMES", default="", cast=Csv())
INTERNAL_IPS = config("KHAGANAT_INTERNAL_IPS", default="127.0.0.1,::1", cast=Csv())
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'bulma',
'chat.apps.LogsConfig',
'khaganat.apps.KhaganatConfig',
'navbar.apps.NavbarConfig',
'neluser.apps.NeluserConfig',
'npb.apps.NpbConfig',
'nsfw.apps.NsfwConfig',
'pages.apps.PagesConfig',
'static_extra.apps.KhaganatStaticFilesConfig',
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"bulma",
"chat.apps.LogsConfig",
"khaganat.apps.KhaganatConfig",
"navbar.apps.NavbarConfig",
"neluser.apps.NeluserConfig",
"npb.apps.NpbConfig",
"nsfw.apps.NsfwConfig",
"pages.apps.PagesConfig",
"static_extra.apps.KhaganatStaticFilesConfig",
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = 'khaganat.urls'
ROOT_URLCONF = "khaganat.urls"
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
]
},
},
}
]
WSGI_APPLICATION = 'khaganat.wsgi.application'
WSGI_APPLICATION = "khaganat.wsgi.application"
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
}
}
@ -98,32 +98,27 @@ DATABASES = {
# Emailing
# https://docs.djangoproject.com/fr/2.0/topics/email/
EMAIL_HOST = config('KHAGANAT_EMAIL_HOST', default='localhost')
EMAIL_PORT = config('KHAGANAT_EMAIL_PORT', default=25, cast=int)
EMAIL_HOST_USER = config('KHAGANAT_EMAIL_HOST_USER', default='')
EMAIL_HOST_PASSWORD = config('KHAGANAT_EMAIL_HOST_PASSWORD', default='')
EMAIL_USE_TLS = config('KHAGANAT_EMAIL_USE_STARTTLS', default=False, cast=bool)
EMAIL_USE_SSL = config('KHAGANAT_EMAIL_USE_TLS', default=False, cast=bool)
EMAIL_HOST = config("KHAGANAT_EMAIL_HOST", default="localhost")
EMAIL_PORT = config("KHAGANAT_EMAIL_PORT", default=25, cast=int)
EMAIL_HOST_USER = config("KHAGANAT_EMAIL_HOST_USER", default="")
EMAIL_HOST_PASSWORD = config("KHAGANAT_EMAIL_HOST_PASSWORD", default="")
EMAIL_USE_TLS = config("KHAGANAT_EMAIL_USE_STARTTLS", default=False, cast=bool)
EMAIL_USE_SSL = config("KHAGANAT_EMAIL_USE_TLS", default=False, cast=bool)
EMAIL_SUBJECT_PREFIX = config('KHAGANAT_EMAIL_SUBJECT_PREFIX', default='')
DEFAULT_FROM_EMAIL = config(
'KHAGANAT_DEFAULT_FROM_EMAIL',
default='no-reply@localhost'
)
EMAIL_SUBJECT_PREFIX = config("KHAGANAT_EMAIL_SUBJECT_PREFIX", default="")
DEFAULT_FROM_EMAIL = config("KHAGANAT_DEFAULT_FROM_EMAIL", default="no-reply@localhost")
# User model
# https://docs.djangoproject.com/en/2.0/topics/auth/customizing/
AUTH_USER_MODEL = 'neluser.NelUser'
LOGIN_URL = reverse_lazy('login')
AUTH_USER_MODEL = "neluser.NelUser"
LOGIN_URL = reverse_lazy("login")
LOGIN_REDIRECT_URL = reverse_lazy(
config('KHAGANAT_LOGIN_REDIRECT_URL', default='index')
config("KHAGANAT_LOGIN_REDIRECT_URL", default="index")
)
REGISTER_REQUIRE_VALIDATION = config(
'KHAGANAT_REGISTER_REQUIRE_VALIDATION',
default=True,
cast=bool
"KHAGANAT_REGISTER_REQUIRE_VALIDATION", default=True, cast=bool
)
@ -132,33 +127,24 @@ REGISTER_REQUIRE_VALIDATION = config(
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
LANGUAGE_CODE = config('KHAGANAT_LANGUAGE_CODE', default='fr')
LANGUAGE_CODE = config("KHAGANAT_LANGUAGE_CODE", default="fr")
# https://github.com/django/django/blob/master/django/conf/global_settings.py
LANGUAGES = [
('en', _('English')),
('fr', _('French')),
]
LANGUAGES = [("en", _("English")), ("fr", _("French"))]
TIME_ZONE = config('KHAGANAT_TIME_ZONE', default='Europe/Paris')
TIME_ZONE = config("KHAGANAT_TIME_ZONE", default="Europe/Paris")
USE_I18N = True
@ -170,36 +156,36 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = config('KHAGANAT_STATIC_URL', default='/static/')
STATIC_ROOT = config('KHAGANAT_STATIC_ROOT', default='') or None
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_extra')]
STATICFILES_DIRS += config('KHAGANAT_STATIC_DIRS', default='', cast=Csv()) or []
STATIC_URL = config("KHAGANAT_STATIC_URL", default="/static/")
STATIC_ROOT = config("KHAGANAT_STATIC_ROOT", default="") or None
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static_extra")]
STATICFILES_DIRS += config("KHAGANAT_STATIC_DIRS", default="", cast=Csv()) or []
# Logs configuration
KHAGANAT_LOGS_MIN_DAYS = config('KHAGANAT_LOGS_MIN_DAYS', default=0, cast=int)
KHAGANAT_LOGS_MAX_DAYS = config('KHAGANAT_LOGS_MAX_DAYS', default=7, cast=int)
KHAGANAT_LOGS_MIN_DAYS = config("KHAGANAT_LOGS_MIN_DAYS", default=0, cast=int)
KHAGANAT_LOGS_MAX_DAYS = config("KHAGANAT_LOGS_MAX_DAYS", default=7, cast=int)
# TLS
# https://docs.djangoproject.com/fr/2.0/ref/settings/#std:setting-SECURE_PROXY_SSL_HEADER
if config('KHAGANAT_FORCE_HTTPS', default=False, cast=bool):
if config("KHAGANAT_FORCE_HTTPS", default=False, cast=bool):
SECURE_PROXY_SSL_HEADER = (
config('KHAGANAT_HTTPS_HEADER_NAME', default='HTTP_X_FORWARDED_PROTO'),
config('KHAGANAT_HTTPS_HEADER_VALUE', default='https')
config("KHAGANAT_HTTPS_HEADER_NAME", default="HTTP_X_FORWARDED_PROTO"),
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')
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")
# Converse.js
KHAGANAT_XMPP_BOSH_URL = config('KHAGANAT_XMPP_BOSH_URL', default='') or None
KHAGANAT_XMPP_JID = config('KHAGANAT_XMPP_JID', default='') or None
KHAGANAT_XMPP_ROOMS = config('KHAGANAT_XMPP_ROOMS', default='', cast=Csv()) or []
KHAGANAT_XMPP_WEBSOCKET_URL = config('KHAGANAT_XMPP_WEBSOCKET_URL', default='') or None
KHAGANAT_XMPP_BOSH_URL = config("KHAGANAT_XMPP_BOSH_URL", default="") or None
KHAGANAT_XMPP_JID = config("KHAGANAT_XMPP_JID", default="") or None
KHAGANAT_XMPP_ROOMS = config("KHAGANAT_XMPP_ROOMS", default="", cast=Csv()) or []
KHAGANAT_XMPP_WEBSOCKET_URL = config("KHAGANAT_XMPP_WEBSOCKET_URL", default="") or None

View file

@ -19,16 +19,14 @@ from django.contrib import admin
from django.urls import include, path
from pages.views import index
urlpatterns = [
path('', index),
]
urlpatterns = [path("", index)]
urlpatterns += i18n_patterns(
path('', index),
path('admin/', admin.site.urls),
path('account/', include('neluser.urls')),
path('page/', include('pages.urls')),
path('paste/', include('npb.urls', namespace='npb')),
path('chat/', include('chat.urls')),
path('nsfw/', include('nsfw.urls')),
path("", index),
path("admin/", admin.site.urls),
path("account/", include("neluser.urls")),
path("page/", include("pages.urls")),
path("paste/", include("npb.urls", namespace="npb")),
path("chat/", include("chat.urls")),
path("nsfw/", include("nsfw.urls")),
)

View file

@ -6,10 +6,8 @@ from .models import Element, ElementDescription, ElementSeparator
class ElementDescriptionAdminForm(forms.ModelForm):
class Meta:
model = ElementDescription
widgets = {
'description': forms.widgets.Textarea,
}
fields = '__all__'
widgets = {"description": forms.widgets.Textarea}
fields = "__all__"
class ElementDescriptionInline(admin.StackedInline):
@ -19,8 +17,8 @@ class ElementDescriptionInline(admin.StackedInline):
class ElementAdmin(admin.ModelAdmin):
list_display = ('__str__', 'parent', 'link', 'weight')
ordering = ('parent', 'weight')
list_display = ("__str__", "parent", "link", "weight")
ordering = ("parent", "weight")
inlines = [ElementDescriptionInline]

View file

@ -2,4 +2,4 @@ from django.apps import AppConfig
class NavbarConfig(AppConfig):
name = 'navbar'
name = "navbar"

View file

@ -6,72 +6,70 @@ import os
class Command(BaseCommand):
help = 'Generates the CSS files used by Pygments'
help = "Generates the CSS files used by Pygments"
def export_static(self, curr_lang):
self.stdout.write('Plain HTML export for language %s' % curr_lang)
output_dir = os.path.join(self.export_dir, 'html')
output_file = 'khanav_%s.html' % curr_lang
self.stdout.write("Plain HTML export for language %s" % curr_lang)
output_dir = os.path.join(self.export_dir, "html")
output_file = "khanav_%s.html" % curr_lang
os.makedirs(output_dir, mode=0o755, exist_ok=True)
with open(os.path.join(output_dir, output_file), 'w') as f:
ctx = get_base_context(curr_lang, '/')
html = render_to_string('navbar/navbar.html', ctx)
with open(os.path.join(output_dir, output_file), "w") as f:
ctx = get_base_context(curr_lang, "/")
html = render_to_string("navbar/navbar.html", ctx)
f.write(html)
def export_docuwiki(self, langs):
self.stdout.write(
'Docuwiki export for languages %s' % ', '.join(langs)
)
self.stdout.write("Docuwiki export for languages %s" % ", ".join(langs))
output_langs = []
for lang in langs:
ctx = get_base_context(lang, '/')
output_langs.append({
'name': lang,
'html': render_to_string('navbar/navbar.html', ctx)
})
output_dir = os.path.join(self.export_dir, 'docuwiki')
ctx = get_base_context(lang, "/")
output_langs.append(
{"name": lang, "html": render_to_string("navbar/navbar.html", ctx)}
)
output_dir = os.path.join(self.export_dir, "docuwiki")
os.makedirs(output_dir, mode=0o755, exist_ok=True)
with open(os.path.join(output_dir, 'khanav.php'), 'w') as f:
f.write(render_to_string('navbar/export_docuwiki.html', {
'output_langs': output_langs
}))
with open(os.path.join(output_dir, "khanav.php"), "w") as f:
f.write(
render_to_string(
"navbar/export_docuwiki.html", {"output_langs": output_langs}
)
)
def add_arguments(self, parser):
parser.add_argument(
'--dir', '-d',
help='Export directory.',
default=os.path.join(settings.BASE_DIR, 'build/navbar'),
dest='export_dir'
"--dir",
"-d",
help="Export directory.",
default=os.path.join(settings.BASE_DIR, "build/navbar"),
dest="export_dir",
)
parser.add_argument(
'--lang', '-l',
help='Language to export.',
action='append',
dest='langs'
"--lang", "-l", help="Language to export.", action="append", dest="langs"
)
parser.add_argument(
'--plain', '--html',
help='Export for plain HTML.',
action='store_true',
dest='static'
"--plain",
"--html",
help="Export for plain HTML.",
action="store_true",
dest="static",
)
parser.add_argument(
'--docuwiki',
help='Export for docuwiki.',
action='store_true',
dest='docuwiki'
"--docuwiki",
help="Export for docuwiki.",
action="store_true",
dest="docuwiki",
)
def handle(self, *args, **options):
if options['langs'] is None:
raise CommandError('No language specified.')
if 'all' in options['langs']:
options['langs'] = [name for name, _ in settings.LANGUAGES]
self.export_dir = options['export_dir']
if options["langs"] is None:
raise CommandError("No language specified.")
if "all" in options["langs"]:
options["langs"] = [name for name, _ in settings.LANGUAGES]
self.export_dir = options["export_dir"]
if options['static']:
for lang in options['langs']:
if options["static"]:
for lang in options["langs"]:
self.export_static(lang)
if options['docuwiki']:
self.export_docuwiki(options['langs'])
self.stdout.write(self.style.SUCCESS('Ok.'))
if options["docuwiki"]:
self.export_docuwiki(options["langs"])
self.stdout.write(self.style.SUCCESS("Ok."))

View file

@ -6,44 +6,35 @@ import os
class Element(models.Model):
parent = models.ForeignKey(
'Element',
"Element",
on_delete=models.CASCADE,
null=True,
blank=True,
limit_choices_to={'parent': None}
limit_choices_to={"parent": None},
)
link = models.CharField(max_length=512, blank=True)
new_window = models.BooleanField(default=False)
add_locale = models.BooleanField(default=False)
icon = models.FilePathField(
path='navbar/static/navbar/icons',
match=".png",
null=True,
blank=True
path="navbar/static/navbar/icons", match=".png", null=True, blank=True
)
weight = models.PositiveSmallIntegerField()
def icon_path(self):
return os.path.join('navbar/icons', os.path.basename(self.icon))
return os.path.join("navbar/icons", os.path.basename(self.icon))
def children(self):
return sorted(
list(Element.objects.filter(parent=self.id).order_by('weight')) +
list(
ElementSeparator.objects.filter(parent=self.id)
.order_by('weight')
),
key=lambda c: c.weight
list(Element.objects.filter(parent=self.id).order_by("weight"))
+ list(ElementSeparator.objects.filter(parent=self.id).order_by("weight")),
key=lambda c: c.weight,
)
def description(self):
lang = get_language()
if lang is None:
lang = settings.LANGUAGE_CODE
return ElementDescription.objects.filter(
element=self.id,
language=lang
).first()
return ElementDescription.objects.filter(element=self.id, language=lang).first()
def localized_link(self):
link = self.link
@ -71,9 +62,7 @@ class ElementDescription(models.Model):
class ElementSeparator(models.Model):
parent = models.ForeignKey(
Element,
on_delete=models.CASCADE,
limit_choices_to={'parent': None}
Element, on_delete=models.CASCADE, limit_choices_to={"parent": None}
)
weight = models.PositiveSmallIntegerField()
@ -81,4 +70,4 @@ class ElementSeparator(models.Model):
return True
def __str__(self):
return '{} ({})'.format(self.parent, self.weight)
return "{} ({})".format(self.parent, self.weight)

View file

@ -13,46 +13,39 @@ import re
register = template.Library()
path_re = re.compile('^(/[a-z]+)/(.*)')
path_re = re.compile("^(/[a-z]+)/(.*)")
def get_lang_name(lang_code):
li = get_language_info(lang_code)
return li['name_local']
return li["name_local"]
def get_lang_data(path_info, lang_code, curr_lang):
lang_name = get_lang_name(lang_code)
rm = resolve(path_info)
activate_lang(lang_code)
lang_url = reverse(
rm.view_name,
current_app='npb',
args=rm.args,
kwargs=rm.kwargs
)
lang_url = reverse(rm.view_name, current_app="npb", args=rm.args, kwargs=rm.kwargs)
activate_lang(curr_lang)
return (lang_code, lang_name, lang_url)
def get_base_context(lang, url):
return {
'user': None,
'current_url': url,
'elems': Element.objects.filter(parent=None).order_by('weight'),
'current_lang_code': lang,
'current_lang_name': get_lang_name(lang),
'all_langs': [
get_lang_data(url, l[0], lang) for l in settings.LANGUAGES
],
"user": None,
"current_url": url,
"elems": Element.objects.filter(parent=None).order_by("weight"),
"current_lang_code": lang,
"current_lang_name": get_lang_name(lang),
"all_langs": [get_lang_data(url, l[0], lang) for l in settings.LANGUAGES],
}
@register.simple_tag(takes_context=True)
def navbar(context):
request = context['request']
request = context["request"]
curr_lang = get_language()
ctx = get_base_context(curr_lang, request.path_info)
ctx['user'] = request.user
tpl = TemplateResponse(request, 'navbar/navbar.html', context=ctx).render()
ctx["user"] = request.user
tpl = TemplateResponse(request, "navbar/navbar.html", context=ctx).render()
return mark_safe(tpl.rendered_content)

View file

@ -5,16 +5,26 @@ from .views import send_activation_email
class NelUserAdmin(admin.ModelAdmin):
list_display = ('email', 'date_joined', 'last_login', 'is_active', 'is_staff', 'is_superuser')
readonly_fields = ('date_joined', 'last_login')
list_filter = ('is_active', 'is_staff', 'is_superuser')
search_fields = ('email', )
list_display = (
"email",
"date_joined",
"last_login",
"is_active",
"is_staff",
"is_superuser",
)
readonly_fields = ("date_joined", "last_login")
list_filter = ("is_active", "is_staff", "is_superuser")
search_fields = ("email",)
fieldsets = [
(_('info'), {'fields': ['is_active', 'email', 'date_joined', 'last_login']}),
(_('user_permissions'), {'fields': ['is_staff', 'is_superuser', 'groups', 'user_permissions']}),
(_('misc'), {'fields': ['nsfw_allowed']}),
(_("info"), {"fields": ["is_active", "email", "date_joined", "last_login"]}),
(
_("user_permissions"),
{"fields": ["is_staff", "is_superuser", "groups", "user_permissions"]},
),
(_("misc"), {"fields": ["nsfw_allowed"]}),
]
actions = ['resend_activation_link']
actions = ["resend_activation_link"]
def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)
@ -24,6 +34,8 @@ class NelUserAdmin(admin.ModelAdmin):
for user in queryset:
if not user.is_active:
send_activation_email(request, user)
resend_activation_link.short_description = _('resend_activation_link')
resend_activation_link.short_description = _("resend_activation_link")
admin.site.register(NelUser, NelUserAdmin)

View file

@ -2,4 +2,4 @@ from django.apps import AppConfig
class NeluserConfig(AppConfig):
name = 'neluser'
name = "neluser"

View file

@ -15,54 +15,48 @@ class RegistrationForm(UserCreationForm):
class ChangePasswordForm(forms.Form):
current_password = forms.CharField(
label=_('current_password'),
widget=forms.PasswordInput
)
new_password = forms.CharField(
label=_('new_password'),
widget=forms.PasswordInput
label=_("current_password"), widget=forms.PasswordInput
)
new_password = forms.CharField(label=_("new_password"), widget=forms.PasswordInput)
new_password_confirm = forms.CharField(
label=_('new_password_confirm'),
widget=forms.PasswordInput
label=_("new_password_confirm"), widget=forms.PasswordInput
)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
self.request = kwargs.pop("request")
return super().__init__(*args, **kwargs)
def clean(self):
cleaned_data = super().clean()
old_pass = cleaned_data.get('current_password')
new_pass = cleaned_data.get('new_password')
new_pass_confirm = cleaned_data.get('new_password_confirm')
old_pass = cleaned_data.get("current_password")
new_pass = cleaned_data.get("new_password")
new_pass_confirm = cleaned_data.get("new_password_confirm")
user = self.request.user
if new_pass != new_pass_confirm:
msg = _('The new password does not match its confirmation.')
msg = _("The new password does not match its confirmation.")
raise forms.ValidationError(msg)
try:
validate_password(new_pass, user=user)
except ValidationError as error:
raise forms.ValidationError(error)
if not user.check_password(old_pass):
msg = _('The current password is incorrect.')
msg = _("The current password is incorrect.")
raise forms.ValidationError(msg)
class DeleteAccountForm(forms.Form):
current_password = forms.CharField(
label=_('current_password'),
widget=forms.PasswordInput
label=_("current_password"), widget=forms.PasswordInput
)
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
self.request = kwargs.pop("request")
return super().__init__(*args, **kwargs)
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get('current_password')
password = cleaned_data.get("current_password")
user = self.request.user
if not user.check_password(password):
msg = _('The current password is incorrect.')
msg = _("The current password is incorrect.")
raise forms.ValidationError(msg)

View file

@ -11,7 +11,7 @@ class NelUserManager(BaseUserManager):
def _create_user(self, email, password, **extra_fields):
if not email:
raise ValueError('The given email must be set')
raise ValueError("The given email must be set")
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
@ -19,59 +19,56 @@ class NelUserManager(BaseUserManager):
return user
def create_user(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
extra_fields.setdefault("is_staff", False)
extra_fields.setdefault("is_superuser", False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
extra_fields.setdefault("is_active", True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
if extra_fields.get("is_staff") is not True:
raise ValueError("Superuser must have is_staff=True.")
if extra_fields.get("is_superuser") is not True:
raise ValueError("Superuser must have is_superuser=True.")
return self._create_user(email, password, **extra_fields)
class NelUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email'), unique=True, null=True)
email = models.EmailField(_("email"), unique=True, null=True)
is_staff = models.BooleanField(
_('staff status'),
_("staff status"),
default=False,
help_text=_(
'Designates whether the user can log into this admin site.'
),
help_text=_("Designates whether the user can log into this admin site."),
)
is_active = models.BooleanField(
_('active'),
_("active"),
default=False,
help_text=_(
'Designates whether this user should be treated as active. '
'Unselect this instead of deleting accounts.'
"Designates whether this user should be treated as active. "
"Unselect this instead of deleting accounts."
),
)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
date_joined = models.DateTimeField(_("date joined"), default=timezone.now)
nsfw_allowed = models.BooleanField(
_('NSFW flag'),
_("NSFW flag"),
default=False,
help_text=_(
'Indicate whether or not adult or sensitive content should '
'be displayed.'
)
"Indicate whether or not adult or sensitive content should " "be displayed."
),
)
objects = NelUserManager()
EMAIL_FIELD = 'email'
USERNAME_FIELD = 'email'
EMAIL_FIELD = "email"
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
verbose_name = _("user")
verbose_name_plural = _("users")
def __str__(self):
return self.email.strip()

View file

@ -6,70 +6,65 @@ from . import views
urlpatterns = [
# Login and logout
path(
'login/',
auth_views.LoginView.as_view(template_name='neluser/login.html'),
name='login'
"login/",
auth_views.LoginView.as_view(template_name="neluser/login.html"),
name="login",
),
path(
'logout/',
auth_views.LogoutView.as_view(next_page=reverse_lazy('index')),
name='logout'
"logout/",
auth_views.LogoutView.as_view(next_page=reverse_lazy("index")),
name="logout",
),
# Account activation
path('register/', views.register, name='register'),
path('activate/<uidb64>/<token>/', views.activate, name='activate'),
path("register/", views.register, name="register"),
path("activate/<uidb64>/<token>/", views.activate, name="activate"),
# Forgotten password
path(
'forgotten_password/',
"forgotten_password/",
auth_views.PasswordResetView.as_view(
template_name='neluser/password_reset.html',
email_template_name='neluser/password_reset_email.txt',
html_email_template_name='neluser/password_reset_email.html',
subject_template_name='neluser/password_reset_email_subject.txt'
template_name="neluser/password_reset.html",
email_template_name="neluser/password_reset_email.txt",
html_email_template_name="neluser/password_reset_email.html",
subject_template_name="neluser/password_reset_email_subject.txt",
),
name='password_reset'
name="password_reset",
),
path(
'forgotten_password/done/',
"forgotten_password/done/",
auth_views.PasswordResetDoneView.as_view(
template_name='neluser/password_reset_email_sent.html'
template_name="neluser/password_reset_email_sent.html"
),
name='password_reset_done'
name="password_reset_done",
),
path(
'password/reset/<uidb64>/<token>/',
"password/reset/<uidb64>/<token>/",
auth_views.PasswordResetConfirmView.as_view(
template_name='neluser/password_reset_confirm.html'
template_name="neluser/password_reset_confirm.html"
),
name='password_reset_confirm'
name="password_reset_confirm",
),
path(
'password/reset/done/',
"password/reset/done/",
auth_views.PasswordResetCompleteView.as_view(
template_name='neluser/password_reset_done.html'
template_name="neluser/password_reset_done.html"
),
name='password_reset_complete'
name="password_reset_complete",
),
# --------
# Settings
# --------
path('settings/', views.settings_default, name='settings'),
path("settings/", views.settings_default, name="settings"),
# Preferences
path('settings/preferences/nsfw/', views.set_nsfw, name='set_nsfw'),
path("settings/preferences/nsfw/", views.set_nsfw, name="set_nsfw"),
# Security
path(
'settings/security/password/',
"settings/security/password/",
views.ChangePasswordView.as_view(),
name='password_change'
name="password_change",
),
path(
'settings/security/delete_account/',
"settings/security/delete_account/",
views.DeleteAccountView.as_view(),
name='delete_account'
name="delete_account",
),
]

View file

@ -21,39 +21,39 @@ from .models import NelUser
@login_required
def settings_default(request):
next_page = reverse_lazy('set_nsfw')
next_page = reverse_lazy("set_nsfw")
return redirect(next_page)
@login_required
def set_nsfw(request):
ctx = {
'nsfw_allowed': is_nsfw_allowed(request),
'current_url': reverse_lazy('set_nsfw'),
'tab': 'preferences',
'active_block': 'nsfw_filter'
"nsfw_allowed": is_nsfw_allowed(request),
"current_url": reverse_lazy("set_nsfw"),
"tab": "preferences",
"active_block": "nsfw_filter",
}
return render(request, 'neluser/settings/preferences/nsfw.html', ctx)
return render(request, "neluser/settings/preferences/nsfw.html", ctx)
class ChangePasswordView(LoginRequiredMixin, FormView):
template_name = 'neluser/settings/security/password.html'
template_name = "neluser/settings/security/password.html"
form_class = ChangePasswordForm
success_url = reverse_lazy('password_change')
success_url = reverse_lazy("password_change")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['tab'] = 'security'
context['active_block'] = 'password'
context["tab"] = "security"
context["active_block"] = "password"
return context
def get_form_kwargs(self):
kw = super().get_form_kwargs()
kw['request'] = self.request
kw["request"] = self.request
return kw
def form_valid(self, form):
new_password = form.cleaned_data['new_password']
new_password = form.cleaned_data["new_password"]
user = self.request.user
user.set_password(new_password)
user.save()
@ -61,50 +61,49 @@ class ChangePasswordView(LoginRequiredMixin, FormView):
class DeleteAccountView(LoginRequiredMixin, FormView):
template_name = 'neluser/settings/security/delete_account.html'
template_name = "neluser/settings/security/delete_account.html"
form_class = DeleteAccountForm
success_url = reverse_lazy('delete_account')
success_url = reverse_lazy("delete_account")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['tab'] = 'security'
context['active_block'] = 'delete_account'
context["tab"] = "security"
context["active_block"] = "delete_account"
return context
def get_form_kwargs(self):
kw = super().get_form_kwargs()
kw['request'] = self.request
kw["request"] = self.request
return kw
def form_valid(self, form):
self.request.user.delete()
logout(self.request)
messages.info(self.request, _('Your account has been deleted.'))
messages.info(self.request, _("Your account has been deleted."))
return super().form_valid(form)
def send_activation_email(request, user):
current_site = get_current_site(request)
context = {
'email': user.email,
'domain': current_site.domain,
'site_name': current_site.name,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'user': user,
'token': default_token_generator.make_token(user),
'protocol': 'https' if request.is_secure() else 'http',
"email": user.email,
"domain": current_site.domain,
"site_name": current_site.name,
"uid": urlsafe_base64_encode(force_bytes(user.pk)),
"user": user,
"token": default_token_generator.make_token(user),
"protocol": "https" if request.is_secure() else "http",
}
subject = render_to_string('neluser/activate_email_subject.txt', context)
subject = ''.join(subject.splitlines())
subject = render_to_string("neluser/activate_email_subject.txt", context)
subject = "".join(subject.splitlines())
email_message = EmailMultiAlternatives(
subject,
render_to_string('neluser/activate_email.txt', context),
render_to_string("neluser/activate_email.txt", context),
settings.DEFAULT_FROM_EMAIL,
[user.email]
[user.email],
)
email_message.attach_alternative(
render_to_string('neluser/activate_email.html', context),
'text/html'
render_to_string("neluser/activate_email.html", context), "text/html"
)
email_message.send()
@ -115,24 +114,21 @@ def activate(request, uidb64, token):
if default_token_generator.check_token(user, token):
user.is_active = True
user.save()
return render(
request,
'neluser/activate_done.html'
)
return render(request, "neluser/activate_done.html")
raise Http404("Unable to activate user %d with token %s." % (uid, token))
def register(request):
if request.method == 'GET':
if request.method == "GET":
form = RegistrationForm()
elif request.method == 'POST':
elif request.method == "POST":
form = RegistrationForm(data=request.POST)
if form.is_valid():
user = form.save(commit=False)
user.set_password(form.cleaned_data.get('password1'))
user.set_password(form.cleaned_data.get("password1"))
user.is_active = not settings.REGISTER_REQUIRE_VALIDATION
user.save()
if settings.REGISTER_REQUIRE_VALIDATION:
send_activation_email(request, user)
return render(request, 'neluser/register_done.html')
return render(request, 'neluser/register.html', {'form': form})
return render(request, "neluser/register_done.html")
return render(request, "neluser/register.html", {"form": form})

View file

@ -2,4 +2,4 @@ from django.apps import AppConfig
class NsfwConfig(AppConfig):
name = 'nsfw'
name = "nsfw"

View file

@ -4,7 +4,7 @@ from . import views
urlpatterns = [
path('', views.warn_view, name='nsfw'),
path('enable/<max_age>/', views.enable_view, name='enable_nsfw'),
path('disable/', views.disable_view, name='disable_nsfw'),
path("", views.warn_view, name="nsfw"),
path("enable/<max_age>/", views.enable_view, name="enable_nsfw"),
path("disable/", views.disable_view, name="disable_nsfw"),
]

View file

@ -13,7 +13,7 @@ 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 ''
s = request.COOKIES.get(settings.KHAGANAT_NSFW_NAME) or ""
return s.lower() in settings.KHAGANAT_NSFW_OK
@ -21,9 +21,9 @@ def disable_view(request):
if isinstance(request.user, NelUser):
request.user.nsfw_allowed = False
request.user.save()
next_url = QueryDict(request.META.get('QUERY_STRING')).get('next')
next_url = QueryDict(request.META.get("QUERY_STRING")).get("next")
if not is_link_legit(next_url):
next_url = reverse('index')
next_url = reverse("index")
response = HttpResponseRedirect(next_url)
response.delete_cookie(settings.KHAGANAT_NSFW_NAME)
return response
@ -34,64 +34,55 @@ def enable_view(request, max_age):
max_age = int(max_age) or None
except ValueError:
max_age = None
next_url = QueryDict(request.META.get('QUERY_STRING')).get('next')
next_url = QueryDict(request.META.get("QUERY_STRING")).get("next")
if not is_link_legit(next_url):
next_url = reverse('index')
next_url = reverse("index")
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,
settings.KHAGANAT_NSFW_OK[0],
max_age=max_age
settings.KHAGANAT_NSFW_NAME, settings.KHAGANAT_NSFW_OK[0], max_age=max_age
)
return response
def warn_view(request):
next_url = QueryDict(request.META.get('QUERY_STRING')).get('next') or '/'
next_url = QueryDict(request.META.get("QUERY_STRING")).get("next") or "/"
if not is_link_legit(next_url):
next_url = '/'
prev_url = QueryDict(request.META.get('QUERY_STRING')).get('prev')
next_url = "/"
prev_url = QueryDict(request.META.get("QUERY_STRING")).get("prev")
if not is_link_legit(prev_url):
prev_url = None
context = {
'prev_url': prev_url,
'go_home': True,
'next_url': next_url,
'is_authenticated': request.user.is_authenticated,
"prev_url": prev_url,
"go_home": True,
"next_url": next_url,
"is_authenticated": request.user.is_authenticated,
}
return render(request, 'nsfw/redirect_page.html', context=context)
return render(request, "nsfw/redirect_page.html", context=context)
def warn_msg(request, next_url=None):
context = {
'prev_url': None,
'go_home': False,
'next_url': next_url,
'is_authenticated': request.user.is_authenticated,
"prev_url": None,
"go_home": False,
"next_url": next_url,
"is_authenticated": request.user.is_authenticated,
}
ret = render_to_string(
request,
'nsfw/redirect_page.html',
context=context
)
ret = render_to_string(request, "nsfw/redirect_page.html", context=context)
return ret
def redirect(request):
dest = '{to_url}?next={next_url}'.format(
to_url=reverse(warn_view),
next_url=request.get_full_path()
dest = "{to_url}?next={next_url}".format(
to_url=reverse(warn_view), next_url=request.get_full_path()
)
return HttpResponseRedirect(dest)
def alert(request, next_url=None):
context = {
'next_url': next_url,
}
msg = render_to_string('nsfw/disabled_alert.html', context=context)
messages.info(request, msg, extra_tags='safe')
context = {"next_url": next_url}
msg = render_to_string("nsfw/disabled_alert.html", context=context)
messages.info(request, msg, extra_tags="safe")

View file

@ -2,4 +2,4 @@ from django.apps import AppConfig
class PagesConfig(AppConfig):
name = 'pages'
name = "pages"

View file

@ -24,14 +24,14 @@ class PageContent(models.Model):
return markdown.markdown(
self.content,
extensions=[
'markdown.extensions.extra',
'markdown.extensions.admonition',
'markdown.extensions.nl2br',
'markdown.extensions.sane_lists',
'markdown.extensions.smarty',
'markdown.extensions.toc',
"markdown.extensions.extra",
"markdown.extensions.admonition",
"markdown.extensions.nl2br",
"markdown.extensions.sane_lists",
"markdown.extensions.smarty",
"markdown.extensions.toc",
],
output_format='html5',
output_format="html5",
)
def __str__(self):

View file

@ -7,9 +7,6 @@ register = template.Library()
@register.simple_tag(takes_context=True)
def get_page(context, slug):
request = context['request']
obj = PageContent.objects.filter(
language=get_language(),
page__slug=slug
).first
request = context["request"]
obj = PageContent.objects.filter(language=get_language(), page__slug=slug).first
return obj

View file

@ -3,6 +3,6 @@ from . import views
urlpatterns = [
path('<slug:slug>/', views.PageView.as_view(), name='page'),
path('', views.index, name='index'),
path("<slug:slug>/", views.PageView.as_view(), name="page"),
path("", views.index, name="index"),
]

View file

@ -8,13 +8,13 @@ from .models import Page, PageContent
def index(request):
default_page = Page.objects.filter(default=True).first()
return HttpResponseRedirect(reverse('page', args=(default_page.slug, )))
return HttpResponseRedirect(reverse("page", args=(default_page.slug,)))
class PageView(generic.DetailView):
model = PageContent
context_object_name = 'page'
template_name = 'pages/page.html'
context_object_name = "page"
template_name = "pages/page.html"
def dispatch(self, request, *args, **kwargs):
if self.get_object().page.is_nsfw:
@ -26,9 +26,8 @@ class PageView(generic.DetailView):
def get_object(self):
obj = PageContent.objects.filter(
language=get_language(),
page__slug=self.kwargs['slug']
language=get_language(), page__slug=self.kwargs["slug"]
).first()
if obj is None:
raise Http404('Page not found: %s' % self.kwargs['slug'])
raise Http404("Page not found: %s" % self.kwargs["slug"])
return obj

View file

@ -2,4 +2,4 @@ from django.contrib.staticfiles.apps import StaticFilesConfig
class KhaganatStaticFilesConfig(StaticFilesConfig):
ignore_patterns = ['CVS', '.*', '*~', 'sass']
ignore_patterns = ["CVS", ".*", "*~", "sass"]