from django.contrib.staticfiles import finders import os def available_themes(request): """ Return clean theme names by scanning /static/themes/*.css. Works whether finder paths are 'themes/xxx.css' or '.../themes/xxx.css' and collapses fingerprinted files (e.g., midnight.400a2f.css -> midnight). """ bases = set() for finder in finders.get_finders(): # 1) Try listing the 'themes' directory directly (some storages support this) try: for path, storage in finder.list(['themes']): if path.endswith('.css'): filename = os.path.basename(path)[:-4] # drop .css base = filename.split('.', 1)[0] # drop fingerprint if base: bases.add(base) except Exception: pass # 2) Fallback: list everything and filter anything under /themes/ try: for path, storage in finder.list([]): if path.endswith('.css') and ('/themes/' in path or path.startswith('themes/')): filename = os.path.basename(path)[:-4] base = filename.split('.', 1)[0] if base: bases.add(base) except Exception: pass # If scan found nothing (e.g., dev env quirk), propose common themes if not bases: candidates = ["classic", "dawn", "forest", "midnight", "mint", "sandstone"] for name in candidates: if finders.find(f"themes/{name}.css"): bases.add(name) # Order: preferred list first, then alphabetical for anything else preferred = ["classic", "dawn", "forest", "midnight", "mint", "sandstone", "original"] names = sorted(bases, key=lambda n: (preferred.index(n) if n in preferred else len(preferred)+1, n)) return {"available_themes": names}