68 lines
2.5 KiB
Python
68 lines
2.5 KiB
Python
from pathlib import Path
|
|
from django.contrib.staticfiles import finders
|
|
from .models_ann import Announcement, AnnouncementDismissal
|
|
import os
|
|
|
|
def app_version(request):
|
|
version_file = Path(__file__).resolve().parent.parent / "version.txt"
|
|
try:
|
|
return {"APP_VERSION": version_file.read_text(encoding="utf-8").strip()}
|
|
except FileNotFoundError:
|
|
return {"APP_VERSION": "v0.0.0"}
|
|
|
|
# core/context_processors.py
|
|
from pathlib import Path
|
|
from django.contrib.staticfiles import finders
|
|
from django.conf import settings
|
|
import os
|
|
|
|
def available_themes(request):
|
|
"""
|
|
Return theme names by scanning /static/themes/*.css across both
|
|
STATICFILES_DIRS and app static folders. Filter out hashed/backup files
|
|
(anything with an extra dot before .css).
|
|
"""
|
|
seen = set()
|
|
|
|
# 1) Check project-level STATICFILES_DIRS
|
|
for root in getattr(settings, "STATICFILES_DIRS", []):
|
|
dirpath = os.path.join(root, "themes")
|
|
if os.path.isdir(dirpath):
|
|
for fname in os.listdir(dirpath):
|
|
if not fname.endswith(".css"):
|
|
continue
|
|
base = fname[:-4] # strip .css
|
|
# Ignore hashed/backup or hidden files
|
|
if not base or base.startswith("_") or "." in base:
|
|
continue
|
|
seen.add(base)
|
|
|
|
# 2) Check app static folders discovered by staticfiles finders
|
|
for finder in finders.get_finders():
|
|
# list() with the 'themes' prefix limits the walk
|
|
for path, storage in finder.list(["themes"]):
|
|
# Expect paths like 'themes/<name>.css'
|
|
if not (path.startswith("themes/") and path.endswith(".css")):
|
|
continue
|
|
base = os.path.basename(path)[:-4]
|
|
if not base or base.startswith("_") or "." in base:
|
|
continue
|
|
seen.add(base)
|
|
|
|
# Nice ordering: keep 'classic' first, then alphabetical
|
|
names = sorted(seen)
|
|
if "classic" in names:
|
|
names = ["classic"] + [n for n in names if n != "classic"]
|
|
|
|
return {"available_themes": names}
|
|
|
|
def pending_announcement(request):
|
|
user = getattr(request, "user", None)
|
|
if not (user and user.is_authenticated):
|
|
return {"pending_announcement": None}
|
|
|
|
current = [a for a in Announcement.objects.all() if a.is_current()]
|
|
for a in current:
|
|
if not AnnouncementDismissal.objects.filter(user=user, announcement=a).exists():
|
|
return {"pending_announcement": a}
|
|
return {"pending_announcement": None} |