from pathlib import Path from .models_ann import Announcement, AnnouncementDismissal from django.contrib.staticfiles import finders import os def app_version(request): version_file = Path(__file__).resolve().parent.parent / "version.txt" try: with open(version_file, "r") as f: version = f.read().strip() except FileNotFoundError: version = "v0.0.0" return {"APP_VERSION": version} def available_themes(request): """Returns ['midnight','dawn','forest','sandstone', ...] by scanning /static/themes/*.css""" names = [] # Find the absolute path for the 'themes' directory via staticfiles finders # We look for any 'themes' folder that exists and aggregate CSS files. for finder in finders.get_finders(): for path, storage in finder.list(['themes']): if path.startswith('themes/') and path.endswith('.css'): base = os.path.basename(path)[:-4] # strip .css names.append(base) # stable order names = sorted(set(names)) return {'available_themes': names} 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) 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}