mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
A theme change compiled Bootswatch with libsass (34 MB, upstream deprecated) into two tracked files, which updates, rollbacks and new Docker containers then reset. The 27 themes now ship as static/css/themes/<theme>.min.css, built by "manage.py build_themes"; the Settings page only saves the theme name and every page links that file (zephyr when no settings are in context, as on the 500 page). libsass moves to dev/requirements.txt; a test checks that each shipped file is its theme compiled from dev/scss. The "Theme SASS Path" setting is removed, and the theme default "flaty", a typo that never applied, becomes zephyr, the theme those installs showed. The update and rollback steps restore an older version's rewritten theme files only where they are modified.
71 lines
2.9 KiB
Python
71 lines
2.9 KiB
Python
from pathlib import Path
|
|
|
|
from admin.decorators import superuser_only
|
|
from django.conf import settings
|
|
from django.contrib import messages
|
|
from django.http import HttpResponseRedirect
|
|
from django.shortcuts import render
|
|
from django.utils.translation import gettext_noop as _
|
|
from logs.views import addlogmsg
|
|
from operations.utils import BOUNDS
|
|
|
|
from appsettings.models import AppSettings
|
|
|
|
|
|
# the themes "manage.py build_themes" compiles; base.html links the chosen one
|
|
THEMES_DIR = Path(settings.BASE_DIR, "static", "css", "themes")
|
|
|
|
|
|
@superuser_only
|
|
def appsettings(request):
|
|
"""
|
|
:param request:
|
|
:return:
|
|
"""
|
|
bootstrap_theme = AppSettings.objects.get(key="BOOTSTRAP_THEME")
|
|
themes_list = sorted(p.name.removesuffix(".min.css") for p in THEMES_DIR.glob("*.min.css"))
|
|
|
|
# the theme has its own form; the other settings are listed one by one
|
|
appsettings = AppSettings.objects.exclude(
|
|
description__startswith="Bootstrap"
|
|
).order_by("name")
|
|
|
|
if request.method == "POST":
|
|
if "BOOTSTRAP_THEME" in request.POST:
|
|
theme = request.POST.get("BOOTSTRAP_THEME", "")
|
|
if theme not in themes_list:
|
|
messages.error(request, _("Unknown theme: %(theme)s") % {"theme": theme})
|
|
return HttpResponseRedirect(request.get_full_path())
|
|
bootstrap_theme.value = theme
|
|
bootstrap_theme.save()
|
|
msg = _("Theme is changed. Now: %(theme)s") % {"theme": theme}
|
|
messages.success(request, msg)
|
|
addlogmsg(request.user.username, "-", "", msg)
|
|
return HttpResponseRedirect(request.get_full_path())
|
|
|
|
for setting in appsettings:
|
|
if setting.key in request.POST:
|
|
if setting.key in BOUNDS:
|
|
low, high, _default = BOUNDS[setting.key]
|
|
raw = request.POST.get(setting.key, "")
|
|
if not (raw.isascii() and raw.isdigit() and len(raw) <= 4 and low <= int(raw) <= high):
|
|
messages.error(request, _("%(setting)s must be a whole number between %(low)s and %(high)s")
|
|
% {"setting": setting.name, "low": low, "high": high})
|
|
return HttpResponseRedirect(request.get_full_path())
|
|
try:
|
|
setting.value = request.POST.get(setting.key, "")
|
|
setting.save()
|
|
|
|
msg = _("%(setting)s is changed. Now: %(value)s") % {
|
|
"setting": setting.name,
|
|
"value": setting.value,
|
|
}
|
|
messages.success(request, msg)
|
|
except Exception as err:
|
|
msg = err
|
|
messages.error(request, msg)
|
|
|
|
addlogmsg(request.user.username, "-", "", msg)
|
|
return HttpResponseRedirect(request.get_full_path())
|
|
|
|
return render(request, "appsettings.html", locals())
|