Source code for cloud_server.server
"""Pi Dashboard server module."""
import logging
from pathlib import Path
from python_template_server.constants import ROOT_DIR
from python_template_server.routers import BaseRouter
from python_template_server.template_server import TemplateServer
from cloud_server.db import FilesMetadataDatabaseManager
from cloud_server.models import CloudServerConfig
from cloud_server.routers import FilesRouter
from cloud_server.thumbnail_generator import ThumbnailGenerator
logger = logging.getLogger(__name__)
FILES_ROUTER = FilesRouter(prefix="/files")
[docs]
class CloudServer(TemplateServer):
"""Cloud FastAPI server."""
[docs]
def __init__(self, config: CloudServerConfig | None = None) -> None:
"""Initialize the CloudServer.
:param CloudServerConfig | None config: Optional pre-loaded configuration
"""
self.files_metadata_database_manager = FilesMetadataDatabaseManager()
self.thumbnail_generator = ThumbnailGenerator(thumbnails_directory=self.thumbnails_directory)
self.config: CloudServerConfig
super().__init__(
package_name="cloud-server",
config=config,
)
logger.info("Initializing CloudServer...")
logger.info("Creating server directory: %s", self.server_directory)
self.server_directory.mkdir(parents=True, exist_ok=True)
logger.info("Creating storage directory: %s", self.storage_directory)
self.storage_directory.mkdir(parents=True, exist_ok=True)
logger.info("Configuring databases...")
self.files_metadata_database_manager.configure(db_config=self.config.db)
self.files_metadata_database_manager.synchronize_with_storage(storage_directory=self.storage_directory)
files_metadata = self.files_metadata_database_manager.list_files()
logger.info("Synchronized %d files metadata entries with storage directory.", len(files_metadata))
logger.info("Synchronizing thumbnails with storage directory...")
self.thumbnail_generator.synchronize_with_storage(
storage_directory=self.storage_directory,
files_metadata=files_metadata,
thumbnail_size=self.config.storage_config.thumbnail_size,
)
@property
def server_directory(self) -> Path:
"""Get the server directory path."""
return Path(ROOT_DIR) / "server"
@property
def storage_directory(self) -> Path:
"""Get the storage directory path."""
return self.server_directory / "storage"
@property
def thumbnails_directory(self) -> Path:
"""Get the thumbnails directory path."""
return self.storage_directory / ".thumbnails"
@property
def routers(self) -> list[BaseRouter]:
"""Define the API routers for the server.
:return list[BaseRouter]: List of API routers
"""
FILES_ROUTER.configure_router(
db=self.files_metadata_database_manager,
storage_directory=self.storage_directory,
storage_config=self.config.storage_config,
thumbnail_generator=self.thumbnail_generator,
)
return [FILES_ROUTER]
[docs]
def validate_config(self, config_data: dict) -> CloudServerConfig:
"""Validate configuration data against the CloudServerConfig model.
:param dict config_data: The configuration data to validate
:return CloudServerConfig: The validated configuration model
"""
return CloudServerConfig.model_validate(config_data) # type: ignore[no-any-return]