diff --git a/bookwyrm/migrations/0188_theme_loads.py b/bookwyrm/migrations/0188_theme_loads.py new file mode 100644 index 000000000..846aaf549 --- /dev/null +++ b/bookwyrm/migrations/0188_theme_loads.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.23 on 2023-11-20 18:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0187_partial_publication_dates"), + ] + + operations = [ + migrations.AddField( + model_name="theme", + name="loads", + field=models.BooleanField(blank=True, null=True), + ), + ] diff --git a/bookwyrm/models/site.py b/bookwyrm/models/site.py index a27c4b70d..b962d597b 100644 --- a/bookwyrm/models/site.py +++ b/bookwyrm/models/site.py @@ -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 diff --git a/bookwyrm/templates/settings/themes.html b/bookwyrm/templates/settings/themes.html index d27aeb0ce..c077fa5e3 100644 --- a/bookwyrm/templates/settings/themes.html +++ b/bookwyrm/templates/settings/themes.html @@ -12,6 +12,15 @@ {% endblock %} {% block panel %} +{% if broken_theme %} +
+ + + {% trans "One of your themes appears to be broken. Selecting this theme will make the application unusable." %} + +
+{% endif %} + {% if success %}
@@ -98,6 +107,9 @@ {% trans "Actions" %} + + {% trans "Status" %} + {% for theme in themes %} @@ -112,6 +124,37 @@ + + {% if theme.loads is None %} + +
+ {% csrf_token %} + +
+ + {% elif not theme.loads %} + + + + + {% trans "Broken theme" %} + + + + {% else %} + + + + + {% trans "Loaded successfully" %} + + + + {% endif %} + {% endfor %} diff --git a/bookwyrm/tests/views/admin/test_themes.py b/bookwyrm/tests/views/admin/test_themes.py index bc6377681..296cd4d8d 100644 --- a/bookwyrm/tests/views/admin/test_themes.py +++ b/bookwyrm/tests/views/admin/test_themes.py @@ -86,3 +86,25 @@ class AdminThemesViews(TestCase): with self.assertRaises(PermissionDenied): view(request) + + def test_test_theme(self): + """Testing testing testing test""" + theme = models.Theme.objects.first() + self.assertIsNone(theme.loads) + request = self.factory.post("") + request.user = self.local_user + + views.test_theme(request, theme.id) + theme.refresh_from_db() + self.assertTrue(theme.loads) + + def test_test_theme_broken(self): + """Testing test for testing when it's a bad theme""" + theme = models.Theme.objects.create(name="bad theme", path="dsf/sdf/sdf.sdf") + self.assertIsNone(theme.loads) + request = self.factory.post("") + request.user = self.local_user + + views.test_theme(request, theme.id) + theme.refresh_from_db() + self.assertIs(False, theme.loads) diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 0b65018cf..dd943b7b5 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -109,6 +109,11 @@ urlpatterns = [ views.delete_theme, name="settings-themes-delete", ), + re_path( + r"^settings/themes/(?P\d+)/test/?$", + views.test_theme, + name="settings-themes-test", + ), re_path( r"^settings/announcements/?$", views.Announcements.as_view(), diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index 63f9d54b5..7076eb3ed 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -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 diff --git a/bookwyrm/views/admin/themes.py b/bookwyrm/views/admin/themes.py index 5658d243a..284a90833 100644 --- a/bookwyrm/views/admin/themes.py +++ b/bookwyrm/views/admin/themes.py @@ -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")