"""Slides plugin main class. Display/service plugin: contributes a blueprint only (no model, no AssetType, no nav). Serves TV-dashboard slideshow images. Demonstrates the minimal plugin shape - a feature that is purely an API surface. """ import json import logging from pathlib import Path from typing import List, Dict, Optional, Type from flask import Flask, Blueprint from shopdb.plugins.base import BasePlugin, PluginMeta from .api import slides_bp from .models import TvSlide logger = logging.getLogger(__name__) class SlidesPlugin(BasePlugin): """Slides plugin - TV dashboard slideshow images.""" def __init__(self): self._manifest = self._load_manifest() def _load_manifest(self) -> Dict: """Load plugin manifest from JSON file.""" manifest_path = Path(__file__).parent / 'manifest.json' if manifest_path.exists(): with open(manifest_path, 'r') as f: return json.load(f) return {} @property def meta(self) -> PluginMeta: """Return plugin metadata.""" return PluginMeta( name=self._manifest.get('name', 'slides'), version=self._manifest.get('version', '1.0.0'), description=self._manifest.get( 'description', 'TV dashboard slideshow images' ), author=self._manifest.get('author', 'ShopDB Team'), dependencies=self._manifest.get('dependencies', []), core_version=self._manifest.get('core_version', '>=0.1.0,<1.0.0'), api_prefix=self._manifest.get('api_prefix', '/api/slides'), ) def get_blueprint(self) -> Optional[Blueprint]: """Return Flask Blueprint with API routes.""" return slides_bp def get_models(self) -> List[Type]: """Slide playlist metadata (image files live on disk).""" return [TvSlide] def get_permissions(self) -> List: """RBAC permission for curating slides (both surfaces). Grantable to a non-admin role so a curator can manage the lobby TV + screensaver without full admin. Admins hold it by default.""" return [ ('slides.manage', 'Manage lobby display and screensaver slides', 'slides'), ] def get_navigation_items(self) -> List[Dict]: """Sidebar entry for the slide manager. Gated on slides.manage so only a curator (or admin, who holds it by default) sees the link.""" return [ { 'name': 'Slides', 'icon': 'image', 'route': '/settings/slides', 'position': 7, 'permission': 'slides.manage', }, ] def init_app(self, app: Flask, db_instance) -> None: """Initialize plugin with Flask app.""" logger.info(f"Slides plugin initialized (v{self.meta.version})")