refactor: Clean up imports in currencies and users routes fix: Update theme settings saving logic and clean up test imports
111 lines
3.2 KiB
Python
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)
|