Files
calminer/routes/settings.py
zwitschi 54137b88d7
Some checks failed
Run Tests / e2e tests (push) Failing after 50s
Run Tests / lint tests (push) Failing after 1m53s
Run Tests / unit tests (push) Failing after 2m25s
feat: Enhance Python environment setup with system Python option and improve dependency installation
refactor: Clean up imports in currencies and users routes
fix: Update theme settings saving logic and clean up test imports
2025-10-27 18:39:20 +01:00

111 lines
3.2 KiB
Python

from typing import Dict, List
from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, Field, model_validator
from sqlalchemy.orm import Session
from routes.dependencies import get_db
from services.settings import (
CSS_COLOR_DEFAULTS,
get_css_color_settings,
list_css_env_override_rows,
read_css_color_env_overrides,
update_css_color_settings,
get_theme_settings,
save_theme_settings,
)
router = APIRouter(prefix="/api/settings", tags=["Settings"])
class CSSSettingsPayload(BaseModel):
variables: Dict[str, str] = Field(default_factory=dict)
@model_validator(mode="after")
def _validate_allowed_keys(self) -> "CSSSettingsPayload":
invalid = set(self.variables.keys()) - set(CSS_COLOR_DEFAULTS.keys())
if invalid:
invalid_keys = ", ".join(sorted(invalid))
raise ValueError(
f"Unsupported CSS variables: {invalid_keys}."
" Accepted keys align with the default theme variables."
)
return self
class EnvOverride(BaseModel):
css_key: str
env_var: str
value: str
class CSSSettingsResponse(BaseModel):
variables: Dict[str, str]
env_overrides: Dict[str, str] = Field(default_factory=dict)
env_sources: List[EnvOverride] = Field(default_factory=list)
@router.get("/css", response_model=CSSSettingsResponse)
def read_css_settings(db: Session = Depends(get_db)) -> CSSSettingsResponse:
try:
values = get_css_color_settings(db)
env_overrides = read_css_color_env_overrides()
env_sources = [
EnvOverride(**row) for row in list_css_env_override_rows()
]
except ValueError as exc:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(exc),
) from exc
return CSSSettingsResponse(
variables=values,
env_overrides=env_overrides,
env_sources=env_sources,
)
@router.put(
"/css", response_model=CSSSettingsResponse, status_code=status.HTTP_200_OK
)
def update_css_settings(
payload: CSSSettingsPayload, db: Session = Depends(get_db)
) -> CSSSettingsResponse:
try:
values = update_css_color_settings(db, payload.variables)
env_overrides = read_css_color_env_overrides()
env_sources = [
EnvOverride(**row) for row in list_css_env_override_rows()
]
except ValueError as exc:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
detail=str(exc),
) from exc
return CSSSettingsResponse(
variables=values,
env_overrides=env_overrides,
env_sources=env_sources,
)
class ThemeSettings(BaseModel):
theme_name: str
primary_color: str
secondary_color: str
accent_color: str
background_color: str
text_color: str
@router.post("/theme")
async def update_theme(theme_data: ThemeSettings, db: Session = Depends(get_db)):
data_dict = theme_data.model_dump()
save_theme_settings(db, data_dict)
return {"message": "Theme updated", "theme": data_dict}
@router.get("/theme")
async def get_theme(db: Session = Depends(get_db)):
return get_theme_settings(db)