feat: asset-based image/video sources, notification sounds, UI improvements
Lint & Test / test (push) Has been cancelled
Lint & Test / test (push) Has been cancelled
- Replace URL-based image_source/url fields with image_asset_id/video_asset_id on StaticImagePictureSource and VideoCaptureSource (clean break, no migration) - Resolve asset IDs to file paths at runtime via AssetStore.get_file_path() - Add EntitySelect asset pickers for image/video in stream editor modal - Add notification sound configuration (global sound + per-app overrides) - Unify per-app color and sound overrides into single "Per-App Overrides" section - Persist notification history between server restarts - Add asset management system (upload, edit, delete, soft-delete) - Replace emoji buttons with SVG icons throughout UI - Various backend improvements: SQLite stores, auth, backup, MQTT, webhooks
This commit is contained in:
@@ -15,7 +15,7 @@ class ServerConfig(BaseSettings):
|
||||
host: str = "0.0.0.0"
|
||||
port: int = 8080
|
||||
log_level: str = "INFO"
|
||||
cors_origins: List[str] = ["*"]
|
||||
cors_origins: List[str] = ["http://localhost:8080"]
|
||||
|
||||
|
||||
class AuthConfig(BaseSettings):
|
||||
@@ -24,6 +24,13 @@ class AuthConfig(BaseSettings):
|
||||
api_keys: dict[str, str] = {} # label: key mapping (empty = auth disabled)
|
||||
|
||||
|
||||
class AssetsConfig(BaseSettings):
|
||||
"""Assets configuration."""
|
||||
|
||||
max_file_size_mb: int = 50 # Max upload size in MB
|
||||
assets_dir: str = "data/assets" # Directory for uploaded asset files
|
||||
|
||||
|
||||
class StorageConfig(BaseSettings):
|
||||
"""Storage configuration."""
|
||||
|
||||
@@ -65,16 +72,21 @@ class Config(BaseSettings):
|
||||
server: ServerConfig = Field(default_factory=ServerConfig)
|
||||
auth: AuthConfig = Field(default_factory=AuthConfig)
|
||||
storage: StorageConfig = Field(default_factory=StorageConfig)
|
||||
assets: AssetsConfig = Field(default_factory=AssetsConfig)
|
||||
mqtt: MQTTConfig = Field(default_factory=MQTTConfig)
|
||||
logging: LoggingConfig = Field(default_factory=LoggingConfig)
|
||||
|
||||
def model_post_init(self, __context: object) -> None:
|
||||
"""Override storage paths when demo mode is active."""
|
||||
"""Override storage and assets paths when demo mode is active."""
|
||||
if self.demo:
|
||||
for field_name in self.storage.model_fields:
|
||||
for field_name in StorageConfig.model_fields:
|
||||
value = getattr(self.storage, field_name)
|
||||
if isinstance(value, str) and value.startswith("data/"):
|
||||
setattr(self.storage, field_name, value.replace("data/", "data/demo/", 1))
|
||||
for field_name in AssetsConfig.model_fields:
|
||||
value = getattr(self.assets, field_name)
|
||||
if isinstance(value, str) and value.startswith("data/"):
|
||||
setattr(self.assets, field_name, value.replace("data/", "data/demo/", 1))
|
||||
|
||||
@classmethod
|
||||
def from_yaml(cls, config_path: str | Path) -> "Config":
|
||||
|
||||
Reference in New Issue
Block a user