Refactor project into two standalone components

Split monorepo into separate units for future independent repositories:
- media-server/: Standalone FastAPI server with own README, requirements,
  config example, and CLAUDE.md
- haos-integration/: HACS-ready Home Assistant integration with hacs.json,
  own README, and CLAUDE.md

Both components now have their own .gitignore files and can be easily
extracted into separate repositories.

Also adds custom icon support for scripts configuration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-04 14:36:23 +03:00
parent 5519e449cd
commit e26df64e4b
44 changed files with 367 additions and 105 deletions

View File

@@ -0,0 +1,96 @@
"""Abstract base class for media controllers."""
from abc import ABC, abstractmethod
from ..models import MediaStatus
class MediaController(ABC):
"""Abstract base class for platform-specific media controllers."""
@abstractmethod
async def get_status(self) -> MediaStatus:
"""Get the current media playback status.
Returns:
MediaStatus with current playback info
"""
pass
@abstractmethod
async def play(self) -> bool:
"""Resume or start playback.
Returns:
True if successful, False otherwise
"""
pass
@abstractmethod
async def pause(self) -> bool:
"""Pause playback.
Returns:
True if successful, False otherwise
"""
pass
@abstractmethod
async def stop(self) -> bool:
"""Stop playback.
Returns:
True if successful, False otherwise
"""
pass
@abstractmethod
async def next_track(self) -> bool:
"""Skip to the next track.
Returns:
True if successful, False otherwise
"""
pass
@abstractmethod
async def previous_track(self) -> bool:
"""Go to the previous track.
Returns:
True if successful, False otherwise
"""
pass
@abstractmethod
async def set_volume(self, volume: int) -> bool:
"""Set the system volume.
Args:
volume: Volume level (0-100)
Returns:
True if successful, False otherwise
"""
pass
@abstractmethod
async def toggle_mute(self) -> bool:
"""Toggle the mute state.
Returns:
The new mute state (True = muted)
"""
pass
@abstractmethod
async def seek(self, position: float) -> bool:
"""Seek to a position in the current track.
Args:
position: Position in seconds
Returns:
True if successful, False otherwise
"""
pass