From fc61d801dde881734df64661519da589b23bc0d6 Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Sun, 16 May 2021 11:56:27 +0200
Subject: [PATCH] Ensure that favicons are always created and updated

---
 aleksis/core/apps.py              | 17 ++++++++++++++---
 aleksis/core/settings.py          | 11 +++++++----
 aleksis/core/util/core_helpers.py | 20 ++++++++++++++------
 3 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/aleksis/core/apps.py b/aleksis/core/apps.py
index fa48d0440..fbde60ece 100644
--- a/aleksis/core/apps.py
+++ b/aleksis/core/apps.py
@@ -14,7 +14,7 @@ from .registries import (
     site_preferences_registry,
 )
 from .util.apps import AppConfig
-from .util.core_helpers import has_person
+from .util.core_helpers import get_or_create_favicon, has_person
 from .util.sass_helpers import clean_scss
 
 
@@ -41,6 +41,8 @@ class CoreConfig(AppConfig):
     def ready(self):
         super().ready()
 
+        from django.conf import settings  # noqa
+
         # Autodiscover various modules defined by AlekSIS
         autodiscover_modules("form_extensions", "model_extensions", "checks")
 
@@ -66,6 +68,10 @@ class CoreConfig(AppConfig):
         plugin_dir.register(MediaBackupAgeHealthCheck)
         plugin_dir.register(BackupJobHealthCheck)
 
+        # Ensure that default Favicon object exists
+        for name, default in settings.DEFAULT_FAVICON_PATHS.items():
+            get_or_create_favicon(name, default, is_favicon=name == "favicon")
+
     @classmethod
     def _load_data_checks(cls):
         """Get all data checks from all loaded models."""
@@ -85,6 +91,8 @@ class CoreConfig(AppConfig):
         new_value: Optional[Any] = None,
         **kwargs,
     ) -> None:
+        from django.conf import settings  # noqa
+
         if section == "theme":
             if name in ("primary", "secondary"):
                 clean_scss()
@@ -95,11 +103,14 @@ class CoreConfig(AppConfig):
 
                 if new_value:
                     Favicon.on_site.update_or_create(
-                        title=name,
-                        defaults={"isFavicon": name == "favicon", "faviconImage": new_value,},
+                        title=name, defaults={"isFavicon": is_favicon, "faviconImage": new_value},
                     )
                 else:
                     Favicon.on_site.filter(title=name, isFavicon=is_favicon).delete()
+                    if name in settings.DEFAULT_FAVICON_PATHS:
+                        get_or_create_favicon(
+                            name, settings.DEFAULT_FAVICON_PATHS[name], is_favicon=is_favicon
+                        )
 
     def post_migrate(
         self,
diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py
index 5d840d0c5..6047648f6 100644
--- a/aleksis/core/settings.py
+++ b/aleksis/core/settings.py
@@ -588,7 +588,10 @@ if _settings.get("dev.uwsgi.celery", DEBUG):
     UWSGI["attach-daemon"].append(f"celery -A aleksis.core worker --concurrency={concurrency}")
     UWSGI["attach-daemon"].append("celery -A aleksis.core beat")
 
-_default_icon_path = os.path.join(STATIC_ROOT, "img/aleksis-icon.png")
+DEFAULT_FAVICON_PATHS = {
+    "pwa_icon": os.path.join(STATIC_ROOT, "img/aleksis-icon.png"),
+    "favicon": os.path.join(STATIC_ROOT, "img/aleksis-icon.png"),
+}
 PWA_APP_NAME = lazy_preference("general", "title")
 PWA_APP_DESCRIPTION = lazy_preference("general", "description")
 PWA_APP_THEME_COLOR = lazy_preference("theme", "primary")
@@ -596,14 +599,14 @@ PWA_APP_BACKGROUND_COLOR = "#ffffff"
 PWA_APP_DISPLAY = "standalone"
 PWA_APP_ORIENTATION = "any"
 PWA_APP_ICONS = lazy_get_favicons(
-    "pwa_icon", default=_default_icon_path, config={"android": [192, 512]}
+    "pwa_icon", default=DEFAULT_FAVICON_PATHS["pwa_icon"], config={"android": [192, 512]}
 )
 PWA_APP_ICONS_APPLE = lazy_get_favicons(
-    "pwa_icon", default=_default_icon_path, config={"apple": [76, 114, 152, 180]}
+    "pwa_icon", default=DEFAULT_FAVICON_PATHS["pwa_icon"], config={"apple": [76, 114, 152, 180]}
 )
 PWA_APP_SPLASH_SCREEN = lazy_get_favicons(
     "pwa_icon",
-    default=_default_icon_path,
+    default=DEFAULT_FAVICON_PATHS["pwa_icon"],
     config={"apple": [192]},
     add_attrs={
         "media": "(device-width: 320px) and (device-height: 568px) and"
diff --git a/aleksis/core/util/core_helpers.py b/aleksis/core/util/core_helpers.py
index b986d5d08..7f2cd5a91 100644
--- a/aleksis/core/util/core_helpers.py
+++ b/aleksis/core/util/core_helpers.py
@@ -126,6 +126,19 @@ def lazy_preference(section: str, name: str) -> Callable[[str, str], Any]:
     return lazy(_get_preference, str)(section, name)
 
 
+def get_or_create_favicon(title: str, default: str, is_favicon: bool = False) -> "Favicon":
+    """Ensure that there is always a favicon object."""
+    from favicon.models import Favicon  # noqa
+
+    favicon, created = Favicon.on_site.update_or_create(
+        title=title, defaults={"isFavicon": is_favicon}
+    )
+    if created:
+        favicon.faviconImage.save(os.path.basename(default), File(open(default, "rb")))
+        favicon.save()
+    return favicon
+
+
 def lazy_get_favicons(
     title: str,
     config: dict[str, list[int]],
@@ -137,12 +150,7 @@ def lazy_get_favicons(
         add_attrs = {}
 
     def _get_favicons() -> list[dict[str, str]]:
-        from favicon.models import Favicon  # noqa
-
-        favicon, created = Favicon.on_site.get_or_create(title=title)
-        if created:
-            favicon.faviconImage.save(os.path.basename(default), File(open(default, "rb")))
-            favicon.save()
+        favicon = get_or_create_favicon(title, default)
         favicon_imgs = favicon.get_favicons(config_override=config)
 
         return [
-- 
GitLab