mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-11-22 17:41:08 +00:00
Give admins option to test if a theme loads correctly
If a theme is uploaded incorrectly or has errors in it, users can still select the theme but it will cause a 500 error on every page, making the app unusable and also making it impossible for them to switch to a functional theme. A better fix would be to fail gracefully, but in lieu of that, this will at least let admins confirm if a theme is broken safely.
This commit is contained in:
parent
4da96d937e
commit
d828ba0bc6
6 changed files with 88 additions and 1 deletions
18
bookwyrm/migrations/0187_theme_loads.py
Normal file
18
bookwyrm/migrations/0187_theme_loads.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.23 on 2023-11-20 17:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("bookwyrm", "0186_invite_request_notification"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="theme",
|
||||
name="loads",
|
||||
field=models.BooleanField(blank=True, null=True),
|
||||
),
|
||||
]
|
|
@ -149,6 +149,7 @@ class Theme(SiteModel):
|
|||
created_date = models.DateTimeField(auto_now_add=True)
|
||||
name = models.CharField(max_length=50, unique=True)
|
||||
path = models.CharField(max_length=50, unique=True)
|
||||
loads = models.BooleanField(null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
# pylint: disable=invalid-str-returned
|
||||
|
|
|
@ -12,6 +12,15 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
{% if broken_theme %}
|
||||
<div class="notification is-danger">
|
||||
<span class="icon icon-warning" aria-hidden="true"></span>
|
||||
<span>
|
||||
{% trans "One of your themes appears to be broken. Selecting this theme will make the application unusable." %}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if success %}
|
||||
<div class="notification is-success is-light">
|
||||
<span class="icon icon-check" aria-hidden="true"></span>
|
||||
|
@ -98,6 +107,9 @@
|
|||
<th>
|
||||
{% trans "Actions" %}
|
||||
</th>
|
||||
<th>
|
||||
{% trans "Status" %}
|
||||
</th>
|
||||
</tr>
|
||||
{% for theme in themes %}
|
||||
<tr>
|
||||
|
@ -112,6 +124,37 @@
|
|||
</button>
|
||||
</form>
|
||||
</td>
|
||||
<td>
|
||||
{% if theme.loads is None %}
|
||||
|
||||
<form method="POST" action="{% url 'settings-themes-test' theme.id %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="button is-small">
|
||||
<span class="icon icon-question-circle" aria-hidden="true"></span>
|
||||
<span>{% trans "Test theme" %}</span>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
{% elif not theme.loads %}
|
||||
|
||||
<span class="tag is-danger">
|
||||
<span class="icon icon-warning" aria-hidden="true"></span>
|
||||
<span>
|
||||
{% trans "Broken theme" %}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
{% else %}
|
||||
|
||||
<span class="tag is-success">
|
||||
<span class="icon icon-check" aria-hidden="true"></span>
|
||||
<span>
|
||||
{% trans "Loaded successfully" %}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
|
|
@ -109,6 +109,11 @@ urlpatterns = [
|
|||
views.delete_theme,
|
||||
name="settings-themes-delete",
|
||||
),
|
||||
re_path(
|
||||
r"^settings/themes/(?P<theme_id>\d+)/test/?$",
|
||||
views.test_theme,
|
||||
name="settings-themes-test",
|
||||
),
|
||||
re_path(
|
||||
r"^settings/announcements/?$",
|
||||
views.Announcements.as_view(),
|
||||
|
|
|
@ -30,7 +30,7 @@ from .admin.reports import (
|
|||
moderator_delete_user,
|
||||
)
|
||||
from .admin.site import Site, Registration, RegistrationLimited
|
||||
from .admin.themes import Themes, delete_theme
|
||||
from .admin.themes import Themes, delete_theme, test_theme
|
||||
from .admin.user_admin import UserAdmin, UserAdminList, ActivateUserAdmin
|
||||
|
||||
# user preferences
|
||||
|
|
|
@ -6,6 +6,8 @@ from django.utils.decorators import method_decorator
|
|||
from django.views import View
|
||||
from django.views.decorators.http import require_POST
|
||||
|
||||
from sass_processor.processor import sass_processor
|
||||
|
||||
from bookwyrm import forms, models
|
||||
|
||||
|
||||
|
@ -40,6 +42,7 @@ class Themes(View):
|
|||
def get_view_data():
|
||||
"""data for view"""
|
||||
return {
|
||||
"broken_theme": models.Theme.objects.filter(loads=False).exists(),
|
||||
"themes": models.Theme.objects.all(),
|
||||
"theme_form": forms.ThemeForm(),
|
||||
}
|
||||
|
@ -52,3 +55,20 @@ def delete_theme(request, theme_id):
|
|||
"""Remove a theme"""
|
||||
get_object_or_404(models.Theme, id=theme_id).delete()
|
||||
return redirect("settings-themes")
|
||||
|
||||
|
||||
@require_POST
|
||||
@permission_required("bookwyrm.system_administration", raise_exception=True)
|
||||
# pylint: disable=unused-argument
|
||||
def test_theme(request, theme_id):
|
||||
"""Remove a theme"""
|
||||
theme = get_object_or_404(models.Theme, id=theme_id)
|
||||
|
||||
try:
|
||||
sass_processor(theme.path)
|
||||
theme.loads = True
|
||||
except Exception: # pylint: disable=broad-except
|
||||
theme.loads = False
|
||||
|
||||
theme.save()
|
||||
return redirect("settings-themes")
|
||||
|
|
Loading…
Reference in a new issue