Update web/core/context_processors.py

This commit is contained in:
Joshua Laymon 2025-09-06 04:14:55 +00:00
parent 46fef4274b
commit eb7b5d3abb

View File

@ -1,12 +1,9 @@
# core/context_processors.py # core/context_processors.py
from pathlib import Path from pathlib import Path
import os
from django.contrib.staticfiles import finders
from django.contrib.staticfiles.storage import staticfiles_storage
from .models_ann import Announcement, AnnouncementDismissal from .models_ann import Announcement, AnnouncementDismissal
from django.contrib.staticfiles import finders
import os
def app_version(request): def app_version(request):
version_file = Path(__file__).resolve().parent.parent / "version.txt" version_file = Path(__file__).resolve().parent.parent / "version.txt"
@ -17,50 +14,36 @@ def app_version(request):
version = "v0.0.0" version = "v0.0.0"
return {"APP_VERSION": version} return {"APP_VERSION": version}
def available_themes(request): def available_themes(request):
""" """
Return a list of theme names by scanning /static/themes/*.css. Return clean theme names by scanning /static/themes/*.css.
Works in development (finders) and production (staticfiles_storage). Fingerprinted files like 'classic.400a2f.css' are normalized to 'classic'.
Never returns an empty list.
""" """
names = set() bases = []
# A) Dev/app static: scan all registered static finders
try:
for finder in finders.get_finders(): for finder in finders.get_finders():
for path, storage in finder.list(['themes']): for path, storage in finder.list(['themes']):
# e.g. "themes/midnight.css" if not (path.startswith('themes/') and path.endswith('.css')):
if path.startswith('themes/') and path.endswith('.css'): continue
names.add(os.path.basename(path)[:-4]) # strip ".css" filename = os.path.basename(path)[:-4] # drop .css
except Exception: base = filename.split('.', 1)[0] # drop any fingerprint
pass if base:
bases.append(base)
# B) Prod/collected: scan STATIC_ROOT via staticfiles_storage # Prefer a nice order with Classic first; fall back to alpha for unknowns
try: order = ["classic", "dawn", "forest", "midnight", "mint", "sandstone", "original"]
dirs, files = staticfiles_storage.listdir('themes') # de-dupe while preserving order preference
for f in files: uniq = []
if f.endswith('.css'): for name in bases:
names.add(f[:-4]) if name not in uniq:
except Exception: uniq.append(name)
pass
# C) Safety net: default themes so the selector is never empty
if not names:
names.update({'midnight', 'dawn', 'forest', 'sandstone'})
return {'available_themes': sorted(names)}
uniq.sort(key=lambda n: (order.index(n) if n in order else len(order)+1, n))
return {"available_themes": uniq}
def pending_announcement(request): def pending_announcement(request):
"""
Expose the latest active, current announcement the user has not dismissed.
We'll only use it on the Search page via include.
"""
user = getattr(request, "user", None) user = getattr(request, "user", None)
if not (user and user.is_authenticated): if not (user and user.is_authenticated):
return {"pending_announcement": None} return {"pending_announcement": None}
current = [a for a in Announcement.objects.all() if a.is_current()] current = [a for a in Announcement.objects.all() if a.is_current()]
for a in current: for a in current:
if not AnnouncementDismissal.objects.filter(user=user, announcement=a).exists(): if not AnnouncementDismissal.objects.filter(user=user, announcement=a).exists():