from cryptography.fernet import Fernet, InvalidToken
from music_assistant_models import config_entries
from music_assistant_models.config_entries import (
- DEFAULT_CORE_CONFIG_ENTRIES,
- DEFAULT_PROVIDER_CONFIG_ENTRIES,
ConfigEntry,
ConfigValueType,
CoreConfig,
PlayerCommandFailed,
UnsupportedFeaturedException,
)
-from music_assistant_models.helpers.global_cache import get_global_cache_value
+from music_assistant_models.helpers import get_global_cache_value
from music_assistant.constants import (
CONF_CORE,
CONF_PROVIDERS,
CONF_SERVER_ID,
CONFIGURABLE_CORE_CONTROLLERS,
+ DEFAULT_CORE_CONFIG_ENTRIES,
+ DEFAULT_PROVIDER_CONFIG_ENTRIES,
ENCRYPT_SUFFIX,
)
from music_assistant.helpers.api import api_command
from collections.abc import Iterable
from typing import TYPE_CHECKING, Any
-from music_assistant_models.enums import CacheCategory, ProviderFeature
+from music_assistant_models.enums import AlbumType, CacheCategory, MediaType, ProviderFeature
from music_assistant_models.errors import (
InvalidDataError,
MediaNotFoundError,
UnsupportedFeaturedException,
)
-from music_assistant_models.media_items import (
- Album,
- AlbumType,
- Artist,
- ItemMapping,
- MediaType,
- Track,
- UniqueList,
-)
+from music_assistant_models.media_items import Album, Artist, ItemMapping, Track, UniqueList
from music_assistant.constants import DB_TABLE_ALBUM_ARTISTS, DB_TABLE_ALBUM_TRACKS, DB_TABLE_ALBUMS
from music_assistant.controllers.media.base import MediaControllerBase
import contextlib
from typing import TYPE_CHECKING, Any
-from music_assistant_models.enums import CacheCategory, ProviderFeature
+from music_assistant_models.enums import AlbumType, CacheCategory, MediaType, ProviderFeature
from music_assistant_models.errors import (
MediaNotFoundError,
ProviderUnavailableError,
UnsupportedFeaturedException,
)
-from music_assistant_models.media_items import (
- Album,
- AlbumType,
- Artist,
- ItemMapping,
- MediaType,
- Track,
- UniqueList,
-)
+from music_assistant_models.media_items import Album, Artist, ItemMapping, Track, UniqueList
from music_assistant.constants import (
DB_TABLE_ALBUM_ARTISTS,
ProviderUnavailableError,
UnsupportedFeaturedException,
)
-from music_assistant_models.helpers.uri import create_uri, parse_uri
from music_assistant_models.media_items import Playlist, PlaylistTrack, Track
from music_assistant.constants import DB_TABLE_PLAYLISTS
from music_assistant.helpers.json import serialize_to_json
+from music_assistant.helpers.uri import create_uri, parse_uri
from music_assistant.models.music_provider import MusicProvider
from .base import MediaControllerBase
ProviderType,
)
from music_assistant_models.errors import MediaNotFoundError, ProviderUnavailableError
-from music_assistant_models.helpers.global_cache import get_global_cache_value
+from music_assistant_models.helpers import get_global_cache_value
from music_assistant_models.media_items import (
Album,
Artist,
MusicAssistantError,
ProviderUnavailableError,
)
-from music_assistant_models.helpers.global_cache import get_global_cache_value
-from music_assistant_models.helpers.uri import parse_uri
+from music_assistant_models.helpers import get_global_cache_value
from music_assistant_models.media_items import (
BrowseFolder,
ItemMapping,
from music_assistant.helpers.api import api_command
from music_assistant.helpers.database import DatabaseConnection
from music_assistant.helpers.datetime import utc_timestamp
+from music_assistant.helpers.uri import parse_uri
from music_assistant.helpers.util import TaskManager
from music_assistant.models.core_controller import CoreController
from aiofiles.os import wrap
from aiohttp import web
-from music_assistant_models.config_entries import (
- CONF_ENTRY_ENABLE_ICY_METADATA,
- ConfigEntry,
- ConfigValueOption,
- ConfigValueType,
-)
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
from music_assistant_models.enums import (
ConfigEntryType,
ContentType,
CONF_BIND_PORT,
CONF_CROSSFADE,
CONF_CROSSFADE_DURATION,
+ CONF_ENTRY_ENABLE_ICY_METADATA,
CONF_HTTP_PROFILE,
CONF_OUTPUT_CHANNELS,
CONF_PUBLISH_IP,
import aiofiles
from aiohttp import ClientTimeout
-from music_assistant_models.enums import MediaType, StreamType, VolumeNormalizationMode
+from music_assistant_models.enums import ContentType, MediaType, StreamType, VolumeNormalizationMode
from music_assistant_models.errors import (
InvalidDataError,
MediaNotFoundError,
MusicAssistantError,
ProviderUnavailableError,
)
-from music_assistant_models.helpers.global_cache import set_global_cache_values
-from music_assistant_models.media_items import AudioFormat, ContentType
+from music_assistant_models.helpers import set_global_cache_values
+from music_assistant_models.streamdetails import AudioFormat
from music_assistant.constants import (
CONF_EQ_BASS,
from collections.abc import AsyncGenerator
from typing import TYPE_CHECKING
+from music_assistant_models.enums import ContentType
from music_assistant_models.errors import AudioError
-from music_assistant_models.helpers.global_cache import get_global_cache_value
-from music_assistant_models.media_items import AudioFormat, ContentType
+from music_assistant_models.helpers import get_global_cache_value
from music_assistant.constants import VERBOSE_LOG_LEVEL
from .process import AsyncProcess
from .util import TimedAsyncGenerator, close_async_generator
+if TYPE_CHECKING:
+ from music_assistant_models.media_items import AudioFormat
+
LOGGER = logging.getLogger("ffmpeg")
MINIMAL_FFMPEG_VERSION = 6
+++ /dev/null
-"""Provides a simple global memory cache."""
-
-from __future__ import annotations
-
-import asyncio
-from typing import Any
-
-# global cache - we use this on a few places (as limited as possible)
-# where we have no other options
-_global_cache_lock = asyncio.Lock()
-_global_cache: dict[str, Any] = {}
-
-
-def get_global_cache_value(key: str, default: Any = None) -> Any:
- """Get a value from the global cache."""
- return _global_cache.get(key, default)
-
-
-async def set_global_cache_values(values: dict[str, Any]) -> Any:
- """Set a value in the global cache (without locking)."""
- async with _global_cache_lock:
- for key, value in values.items():
- _set_global_cache_value(key, value)
-
-
-def _set_global_cache_value(key: str, value: Any) -> Any:
- """Set a value in the global cache (without locking)."""
- _global_cache[key] = value
from music_assistant_models.enums import MediaType
from music_assistant_models.errors import InvalidProviderID, InvalidProviderURI
+from music_assistant_models.helpers import create_uri as create_uri_org
base62_length22_id_pattern = re.compile(r"^[a-zA-Z0-9]{22}$")
+# create alias to original create_uri function
+create_uri = create_uri_org
+
def valid_base62_length22(item_id: str) -> bool:
"""Validate Spotify style ID."""
@lru_cache
def _get_provider_module(domain: str) -> ProviderModuleType:
- return importlib.import_module(f".{domain}", ".providers")
+ return importlib.import_module(f".{domain}", "music_assistant.providers")
# ensure module requirements are met
for requirement in requirements:
from music_assistant_models.enums import EventType, ProviderType
from music_assistant_models.errors import MusicAssistantError, SetupFailedError
from music_assistant_models.event import MassEvent
-from music_assistant_models.helpers.global_cache import set_global_cache_values
+from music_assistant_models.helpers import set_global_cache_values
from music_assistant_models.provider import ProviderManifest
from zeroconf import IPVersion, NonUniqueNameException, ServiceStateChange, Zeroconf
from zeroconf.asyncio import AsyncServiceBrowser, AsyncServiceInfo, AsyncZeroconf
from abc import abstractmethod
from typing import TYPE_CHECKING
-from music_assistant_models.config_entries import (
+from music_assistant_models.errors import UnsupportedFeaturedException
+from zeroconf import ServiceStateChange
+from zeroconf.asyncio import AsyncServiceInfo
+
+from music_assistant.constants import (
BASE_PLAYER_CONFIG_ENTRIES,
CONF_ENTRY_ANNOUNCE_VOLUME,
CONF_ENTRY_ANNOUNCE_VOLUME_MAX,
CONF_ENTRY_ANNOUNCE_VOLUME_MIN,
CONF_ENTRY_ANNOUNCE_VOLUME_STRATEGY,
- ConfigEntry,
- PlayerConfig,
)
-from music_assistant_models.errors import UnsupportedFeaturedException
-from zeroconf import ServiceStateChange
-from zeroconf.asyncio import AsyncServiceInfo
from .provider import Provider
if TYPE_CHECKING:
+ from music_assistant_models.config_entries import ConfigEntry, PlayerConfig
from music_assistant_models.player import Player, PlayerMedia
# ruff: noqa: ARG001, ARG002
from random import randrange
from typing import TYPE_CHECKING
-from music_assistant_models.config_entries import (
- CONF_ENTRY_CROSSFADE,
- CONF_ENTRY_CROSSFADE_DURATION,
- CONF_ENTRY_EQ_BASS,
- CONF_ENTRY_EQ_MID,
- CONF_ENTRY_EQ_TREBLE,
- CONF_ENTRY_FLOW_MODE_ENFORCED,
- CONF_ENTRY_OUTPUT_CHANNELS,
- CONF_ENTRY_SYNC_ADJUST,
- ConfigEntry,
- create_sample_rates_config_entry,
-)
+from music_assistant_models.config_entries import ConfigEntry
from music_assistant_models.enums import (
ConfigEntryType,
ContentType,
from zeroconf import ServiceStateChange
from zeroconf.asyncio import AsyncServiceInfo
-from music_assistant.helpers import (
- convert_airplay_volume,
- get_model_from_am,
- get_primary_ip_address,
+from music_assistant.constants import (
+ CONF_ENTRY_CROSSFADE,
+ CONF_ENTRY_CROSSFADE_DURATION,
+ CONF_ENTRY_EQ_BASS,
+ CONF_ENTRY_EQ_MID,
+ CONF_ENTRY_EQ_TREBLE,
+ CONF_ENTRY_FLOW_MODE_ENFORCED,
+ CONF_ENTRY_OUTPUT_CHANNELS,
+ CONF_ENTRY_SYNC_ADJUST,
+ create_sample_rates_config_entry,
)
from music_assistant.helpers.audio import get_ffmpeg_stream
from music_assistant.helpers.datetime import utc
CONF_READ_AHEAD_BUFFER,
FALLBACK_VOLUME,
)
+from .helpers import convert_airplay_volume, get_model_from_am, get_primary_ip_address
from .player import AirPlayPlayer
if TYPE_CHECKING:
import aiofiles
from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
-from music_assistant_models.enums import ConfigEntryType, ExternalID, ProviderFeature, StreamType
+from music_assistant_models.enums import (
+ AlbumType,
+ ConfigEntryType,
+ ContentType,
+ ExternalID,
+ ImageType,
+ ProviderFeature,
+ StreamType,
+)
from music_assistant_models.errors import MediaNotFoundError, ResourceTemporarilyUnavailable
from music_assistant_models.media_items import (
Album,
- AlbumType,
Artist,
AudioFormat,
- ContentType,
- ImageType,
ItemMapping,
MediaItemImage,
MediaItemType,
import time
from typing import TYPE_CHECKING, TypedDict
-from music_assistant_models.config_entries import (
- CONF_ENTRY_CROSSFADE,
- CONF_ENTRY_ENABLE_ICY_METADATA,
- CONF_ENTRY_ENFORCE_MP3,
- CONF_ENTRY_FLOW_MODE_ENFORCED,
- CONF_ENTRY_HTTP_PROFILE_FORCED_2,
- ConfigEntry,
- ConfigValueType,
-)
from music_assistant_models.enums import PlayerFeature, PlayerState, PlayerType, ProviderFeature
from music_assistant_models.errors import PlayerCommandFailed
from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
from pyblu import Status, SyncStatus
from zeroconf import ServiceStateChange
-from music_assistant.constants import VERBOSE_LOG_LEVEL
+from music_assistant.constants import (
+ CONF_ENTRY_CROSSFADE,
+ CONF_ENTRY_ENABLE_ICY_METADATA,
+ CONF_ENTRY_ENFORCE_MP3,
+ CONF_ENTRY_FLOW_MODE_ENFORCED,
+ CONF_ENTRY_HTTP_PROFILE_FORCED_2,
+ VERBOSE_LOG_LEVEL,
+)
from music_assistant.helpers.util import (
get_port_from_zeroconf,
get_primary_ip_address_from_zeroconf,
from music_assistant.models.player_provider import PlayerProvider
if TYPE_CHECKING:
- from music_assistant_models.config_entries import ProviderConfig
+ from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
from music_assistant_models.provider import ProviderManifest
from zeroconf.asyncio import AsyncServiceInfo
MediaNotFoundError,
ProviderUnavailableError,
)
-from music_assistant_models.helpers.uri import parse_uri
from music_assistant_models.media_items import (
Artist,
AudioFormat,
from music_assistant.constants import MASS_LOGO, RESOURCES_DIR, VARIOUS_ARTISTS_FANART
from music_assistant.helpers.tags import AudioTags, parse_tags
+from music_assistant.helpers.uri import parse_uri
from music_assistant.models.music_provider import MusicProvider
if TYPE_CHECKING:
from uuid import UUID
import pychromecast
-from music_assistant_models.config_entries import (
- BASE_PLAYER_CONFIG_ENTRIES,
- CONF_ENTRY_CROSSFADE_DURATION,
- CONF_ENTRY_CROSSFADE_FLOW_MODE_REQUIRED,
- CONF_ENTRY_ENFORCE_MP3,
- ConfigEntry,
- ConfigValueType,
- create_sample_rates_config_entry,
-)
from music_assistant_models.enums import MediaType, PlayerFeature, PlayerState, PlayerType
from music_assistant_models.errors import PlayerUnavailableError
from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
from pychromecast.socket_client import CONNECTION_STATUS_CONNECTED, CONNECTION_STATUS_DISCONNECTED
from music_assistant.constants import (
+ BASE_PLAYER_CONFIG_ENTRIES,
CONF_ENFORCE_MP3,
+ CONF_ENTRY_CROSSFADE_DURATION,
+ CONF_ENTRY_CROSSFADE_FLOW_MODE_REQUIRED,
+ CONF_ENTRY_ENFORCE_MP3,
CONF_PLAYERS,
MASS_LOGO_ONLINE,
VERBOSE_LOG_LEVEL,
+ create_sample_rates_config_entry,
)
-from music_assistant.helpers import CastStatusListener, ChromecastInfo
from music_assistant.models.player_provider import PlayerProvider
+from .helpers import CastStatusListener, ChromecastInfo
+
if TYPE_CHECKING:
- from music_assistant_models.config_entries import ProviderConfig
+ from music_assistant_models.config_entries import ConfigEntry, ConfigValueType, ProviderConfig
from music_assistant_models.provider import ProviderManifest
from pychromecast.controllers.media import MediaStatus
from pychromecast.controllers.receiver import CastStatus
from async_upnp_client.exceptions import UpnpError, UpnpResponseError
from async_upnp_client.profiles.dlna import DmrDevice, TransportState
from async_upnp_client.search import async_search
-from music_assistant_models.config_entries import (
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
+from music_assistant_models.enums import ConfigEntryType, PlayerFeature, PlayerState, PlayerType
+from music_assistant_models.errors import PlayerUnavailableError
+from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
+
+from music_assistant.constants import (
+ CONF_ENFORCE_MP3,
CONF_ENTRY_CROSSFADE_DURATION,
CONF_ENTRY_CROSSFADE_FLOW_MODE_REQUIRED,
CONF_ENTRY_ENABLE_ICY_METADATA,
CONF_ENTRY_ENFORCE_MP3,
CONF_ENTRY_FLOW_MODE_DEFAULT_ENABLED,
CONF_ENTRY_HTTP_PROFILE,
- ConfigEntry,
- ConfigValueType,
+ CONF_PLAYERS,
+ VERBOSE_LOG_LEVEL,
create_sample_rates_config_entry,
)
-from music_assistant_models.enums import ConfigEntryType, PlayerFeature, PlayerState, PlayerType
-from music_assistant_models.errors import PlayerUnavailableError
-from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
-
-from music_assistant.constants import CONF_ENFORCE_MP3, CONF_PLAYERS, VERBOSE_LOG_LEVEL
-from music_assistant.helpers import DLNANotifyServer
from music_assistant.helpers.didl_lite import create_didl_metadata
from music_assistant.helpers.util import TaskManager
from music_assistant.models.player_provider import PlayerProvider
+from .helpers import DLNANotifyServer
+
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable, Coroutine, Sequence
import aiohttp.client_exceptions
from music_assistant_models.config_entries import ConfigEntry
-from music_assistant_models.enums import ConfigEntryType, ExternalID, ProviderFeature
-from music_assistant_models.media_items import ImageType, MediaItemImage, MediaItemMetadata
+from music_assistant_models.enums import ConfigEntryType, ExternalID, ImageType, ProviderFeature
+from music_assistant_models.media_items import MediaItemImage, MediaItemMetadata
from music_assistant.controllers.cache import use_cache
from music_assistant.helpers.app_vars import app_var
import xmltodict
from aiofiles.os import wrap
from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
-from music_assistant_models.enums import ConfigEntryType, ExternalID, ProviderFeature, StreamType
+from music_assistant_models.enums import (
+ ConfigEntryType,
+ ContentType,
+ ExternalID,
+ ImageType,
+ ProviderFeature,
+ StreamType,
+)
from music_assistant_models.errors import MediaNotFoundError, MusicAssistantError, SetupFailedError
from music_assistant_models.media_items import (
Album,
Artist,
AudioFormat,
BrowseFolder,
- ContentType,
- ImageType,
ItemMapping,
MediaItemImage,
MediaItemType,
from typing import TYPE_CHECKING
from fullykiosk import FullyKiosk
-from music_assistant_models.config_entries import (
- CONF_ENTRY_CROSSFADE,
- CONF_ENTRY_CROSSFADE_DURATION,
- CONF_ENTRY_ENFORCE_MP3_DEFAULT_ENABLED,
- CONF_ENTRY_FLOW_MODE_ENFORCED,
- ConfigEntry,
- ConfigValueType,
-)
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
from music_assistant_models.enums import ConfigEntryType, PlayerFeature, PlayerState, PlayerType
from music_assistant_models.errors import PlayerUnavailableError, SetupFailedError
from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
from music_assistant.constants import (
CONF_ENFORCE_MP3,
+ CONF_ENTRY_CROSSFADE,
+ CONF_ENTRY_CROSSFADE_DURATION,
+ CONF_ENTRY_ENFORCE_MP3_DEFAULT_ENABLED,
+ CONF_ENTRY_FLOW_MODE_ENFORCED,
CONF_IP_ADDRESS,
CONF_PASSWORD,
CONF_PORT,
from typing import TYPE_CHECKING, Any
from hass_client.exceptions import FailedCommand
-from music_assistant_models.config_entries import (
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
+from music_assistant_models.enums import ConfigEntryType, PlayerFeature, PlayerState, PlayerType
+from music_assistant_models.errors import SetupFailedError
+from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
+
+from music_assistant.constants import (
CONF_ENTRY_CROSSFADE_DURATION,
CONF_ENTRY_CROSSFADE_FLOW_MODE_REQUIRED,
CONF_ENTRY_ENABLE_ICY_METADATA,
CONF_ENTRY_ENFORCE_MP3_DEFAULT_ENABLED,
CONF_ENTRY_FLOW_MODE_ENFORCED,
CONF_ENTRY_HTTP_PROFILE,
- ConfigEntry,
- ConfigValueOption,
- ConfigValueType,
)
-from music_assistant_models.enums import ConfigEntryType, PlayerFeature, PlayerState, PlayerType
-from music_assistant_models.errors import SetupFailedError
-from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
-
from music_assistant.helpers.datetime import from_iso_string
from music_assistant.models.player_provider import PlayerProvider
from music_assistant.providers.hass import DOMAIN as HASS_DOMAIN
SonicError,
)
from music_assistant_models.enums import (
+ AlbumType,
ContentType,
ImageType,
MediaType,
from music_assistant_models.errors import LoginFailed, MediaNotFoundError, ProviderPermissionDenied
from music_assistant_models.media_items import (
Album,
- AlbumType,
Artist,
AudioFormat,
ItemMapping,
import shortuuid
from aiohttp import web
from music_assistant_models.config_entries import (
- BASE_PLAYER_CONFIG_ENTRIES,
- CONF_ENTRY_CROSSFADE,
- CONF_ENTRY_CROSSFADE_DURATION,
- CONF_ENTRY_FLOW_MODE_ENFORCED,
- CONF_ENTRY_PLAYER_ICON_GROUP,
ConfigEntry,
ConfigValueOption,
ConfigValueType,
PlayerConfig,
- create_sample_rates_config_entry,
)
from music_assistant_models.enums import (
ConfigEntryType,
from music_assistant_models.player import DeviceInfo, Player, PlayerMedia
from music_assistant.constants import (
+ BASE_PLAYER_CONFIG_ENTRIES,
CONF_CROSSFADE,
CONF_CROSSFADE_DURATION,
CONF_ENABLE_ICY_METADATA,
CONF_ENFORCE_MP3,
+ CONF_ENTRY_CROSSFADE,
+ CONF_ENTRY_CROSSFADE_DURATION,
+ CONF_ENTRY_FLOW_MODE_ENFORCED,
+ CONF_ENTRY_PLAYER_ICON_GROUP,
CONF_FLOW_MODE,
CONF_GROUP_MEMBERS,
CONF_HTTP_PROFILE,
CONF_SAMPLE_RATES,
+ create_sample_rates_config_entry,
)
from music_assistant.controllers.streams import DEFAULT_STREAM_HEADERS
from music_assistant.helpers.ffmpeg import get_ffmpeg_stream
from aiohttp import client_exceptions
from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
-from music_assistant_models.enums import ConfigEntryType, ExternalID, ProviderFeature, StreamType
+from music_assistant_models.enums import (
+ AlbumType,
+ ConfigEntryType,
+ ContentType,
+ ExternalID,
+ ImageType,
+ ProviderFeature,
+ StreamType,
+)
from music_assistant_models.errors import (
InvalidDataError,
LoginFailed,
)
from music_assistant_models.media_items import (
Album,
- AlbumType,
Artist,
AudioFormat,
- ContentType,
- ImageType,
MediaItemImage,
MediaItemType,
MediaType,
from typing import TYPE_CHECKING, cast
from music_assistant_models.config_entries import ConfigEntry
-from music_assistant_models.enums import ConfigEntryType, LinkType, ProviderFeature, StreamType
+from music_assistant_models.enums import (
+ ConfigEntryType,
+ ContentType,
+ ImageType,
+ LinkType,
+ ProviderFeature,
+ StreamType,
+)
from music_assistant_models.errors import MediaNotFoundError
from music_assistant_models.media_items import (
AudioFormat,
BrowseFolder,
- ContentType,
- ImageType,
MediaItemImage,
MediaItemLink,
MediaItemType,
from music_assistant_models.enums import (
ConfigEntryType,
ContentType,
+ ImageType,
LinkType,
MediaType,
ProviderFeature,
from music_assistant_models.errors import LoginFailed, MediaNotFoundError
from music_assistant_models.media_items import (
AudioFormat,
- ImageType,
ItemMapping,
MediaItemImage,
MediaItemLink,
from aioslimproto.models import VisualisationType as SlimVisualisationType
from aioslimproto.server import SlimServer
from music_assistant_models.config_entries import (
- CONF_ENTRY_CROSSFADE,
- CONF_ENTRY_CROSSFADE_DURATION,
- CONF_ENTRY_ENFORCE_MP3,
- CONF_ENTRY_EQ_BASS,
- CONF_ENTRY_EQ_MID,
- CONF_ENTRY_EQ_TREBLE,
- CONF_ENTRY_HTTP_PROFILE_FORCED_2,
- CONF_ENTRY_OUTPUT_CHANNELS,
- CONF_ENTRY_SYNC_ADJUST,
ConfigEntry,
ConfigValueOption,
ConfigValueType,
PlayerConfig,
- create_sample_rates_config_entry,
)
from music_assistant_models.enums import (
ConfigEntryType,
CONF_CROSSFADE,
CONF_CROSSFADE_DURATION,
CONF_ENFORCE_MP3,
+ CONF_ENTRY_CROSSFADE,
+ CONF_ENTRY_CROSSFADE_DURATION,
+ CONF_ENTRY_ENFORCE_MP3,
+ CONF_ENTRY_EQ_BASS,
+ CONF_ENTRY_EQ_MID,
+ CONF_ENTRY_EQ_TREBLE,
+ CONF_ENTRY_HTTP_PROFILE_FORCED_2,
+ CONF_ENTRY_OUTPUT_CHANNELS,
+ CONF_ENTRY_SYNC_ADJUST,
CONF_PORT,
CONF_SYNC_ADJUST,
VERBOSE_LOG_LEVEL,
+ create_sample_rates_config_entry,
)
from music_assistant.helpers.audio import get_ffmpeg_stream, get_player_filter_params
from music_assistant.helpers.util import TaskManager
from typing import TYPE_CHECKING, Final, cast
from bidict import bidict
-from music_assistant_models.config_entries import (
- CONF_ENTRY_CROSSFADE,
- CONF_ENTRY_CROSSFADE_DURATION,
- CONF_ENTRY_FLOW_MODE_ENFORCED,
- ConfigEntry,
- ConfigValueOption,
- ConfigValueType,
- create_sample_rates_config_entry,
-)
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
from music_assistant_models.enums import (
ConfigEntryType,
ContentType,
from zeroconf import NonUniqueNameException
from zeroconf.asyncio import AsyncServiceInfo
+from music_assistant.constants import (
+ CONF_ENTRY_CROSSFADE,
+ CONF_ENTRY_CROSSFADE_DURATION,
+ CONF_ENTRY_FLOW_MODE_ENFORCED,
+ create_sample_rates_config_entry,
+)
from music_assistant.helpers.audio import FFMpeg, get_ffmpeg_stream, get_player_filter_params
from music_assistant.helpers.process import AsyncProcess, check_output
from music_assistant.helpers.util import get_ip_pton
from aiohttp.client_exceptions import ClientError
from aiosonos.api.models import SonosCapability
from aiosonos.utils import get_discovery_info
-from music_assistant_models.config_entries import (
- CONF_ENTRY_CROSSFADE,
- CONF_ENTRY_ENFORCE_MP3,
- CONF_ENTRY_FLOW_MODE_HIDDEN_DISABLED,
- ConfigEntry,
- create_sample_rates_config_entry,
-)
+from music_assistant_models.config_entries import ConfigEntry
from music_assistant_models.enums import ConfigEntryType, ContentType, ProviderFeature
from music_assistant_models.errors import PlayerCommandFailed
from music_assistant_models.player import DeviceInfo, PlayerMedia
from zeroconf import ServiceStateChange
-from music_assistant.constants import MASS_LOGO_ONLINE, VERBOSE_LOG_LEVEL
-from music_assistant.helpers import get_primary_ip_address
+from music_assistant.constants import (
+ CONF_ENTRY_CROSSFADE,
+ CONF_ENTRY_ENFORCE_MP3,
+ CONF_ENTRY_FLOW_MODE_HIDDEN_DISABLED,
+ MASS_LOGO_ONLINE,
+ VERBOSE_LOG_LEVEL,
+ create_sample_rates_config_entry,
+)
from music_assistant.helpers.tags import parse_tags
from music_assistant.models.player_provider import PlayerProvider
from .const import CONF_AIRPLAY_MODE
+from .helpers import get_primary_ip_address
from .player import SonosPlayer
if TYPE_CHECKING:
from dataclasses import dataclass, field
from typing import TYPE_CHECKING
-from music_assistant_models.config_entries import (
- CONF_ENTRY_CROSSFADE,
- CONF_ENTRY_ENFORCE_MP3,
- CONF_ENTRY_FLOW_MODE_HIDDEN_DISABLED,
- CONF_ENTRY_HTTP_PROFILE_FORCED_1,
- ConfigEntry,
- ConfigValueType,
- create_sample_rates_config_entry,
-)
+from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
from music_assistant_models.enums import (
ConfigEntryType,
PlayerFeature,
from soco import events_asyncio, zonegroupstate
from soco.discovery import discover, scan_network
-from music_assistant.constants import CONF_CROSSFADE, CONF_ENFORCE_MP3, VERBOSE_LOG_LEVEL
+from music_assistant.constants import (
+ CONF_CROSSFADE,
+ CONF_ENFORCE_MP3,
+ CONF_ENTRY_CROSSFADE,
+ CONF_ENTRY_ENFORCE_MP3,
+ CONF_ENTRY_FLOW_MODE_HIDDEN_DISABLED,
+ CONF_ENTRY_HTTP_PROFILE_FORCED_1,
+ VERBOSE_LOG_LEVEL,
+ create_sample_rates_config_entry,
+)
from music_assistant.helpers.didl_lite import create_didl_metadata
from music_assistant.models.player_provider import PlayerProvider
from soco.data_structures import DidlAudioBroadcast, DidlPlaylistContainer
from music_assistant.constants import VERBOSE_LOG_LEVEL
-from music_assistant.helpers import SonosUpdateError, soco_error
from music_assistant.helpers.datetime import utc
+from .helpers import SonosUpdateError, soco_error
+
if TYPE_CHECKING:
from soco.events_base import Event as SonosEvent
from soco.events_base import SubscriptionBase
from typing import TYPE_CHECKING
from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
-from music_assistant_models.enums import ConfigEntryType, ProviderFeature, StreamType
+from music_assistant_models.enums import (
+ ConfigEntryType,
+ ContentType,
+ ImageType,
+ ProviderFeature,
+ StreamType,
+)
from music_assistant_models.errors import InvalidDataError, LoginFailed
from music_assistant_models.media_items import (
Artist,
AudioFormat,
- ContentType,
- ImageType,
MediaItemImage,
MediaType,
Playlist,
from urllib.parse import urlencode
from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
-from music_assistant_models.enums import ConfigEntryType, ExternalID, ProviderFeature, StreamType
+from music_assistant_models.enums import (
+ AlbumType,
+ ConfigEntryType,
+ ContentType,
+ ExternalID,
+ ImageType,
+ ProviderFeature,
+ StreamType,
+)
from music_assistant_models.errors import (
AudioError,
LoginFailed,
)
from music_assistant_models.media_items import (
Album,
- AlbumType,
Artist,
AudioFormat,
- ContentType,
- ImageType,
MediaItemImage,
MediaItemType,
MediaType,
import aiohttp.client_exceptions
from music_assistant_models.config_entries import ConfigEntry
-from music_assistant_models.enums import ConfigEntryType, ExternalID, ProviderFeature
-from music_assistant_models.media_items import (
- Album,
+from music_assistant_models.enums import (
AlbumType,
- Artist,
+ ConfigEntryType,
+ ExternalID,
ImageType,
LinkType,
+ ProviderFeature,
+)
+from music_assistant_models.media_items import (
+ Album,
+ Artist,
MediaItemImage,
MediaItemLink,
MediaItemMetadata,
AlbumType,
CacheCategory,
ConfigEntryType,
+ ContentType,
ExternalID,
ImageType,
MediaType,
Album,
Artist,
AudioFormat,
- ContentType,
ItemMapping,
MediaItemImage,
MediaItemType,
from typing import TYPE_CHECKING
from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
-from music_assistant_models.enums import ConfigEntryType, ProviderFeature, StreamType
+from music_assistant_models.enums import (
+ ConfigEntryType,
+ ContentType,
+ ImageType,
+ ProviderFeature,
+ StreamType,
+)
from music_assistant_models.errors import InvalidDataError, LoginFailed, MediaNotFoundError
from music_assistant_models.media_items import (
AudioFormat,
- ContentType,
- ImageType,
MediaItemImage,
MediaType,
ProviderMapping,
import yt_dlp
from music_assistant_models.config_entries import ConfigEntry, ConfigValueType
-from music_assistant_models.enums import ConfigEntryType, ProviderFeature, StreamType
+from music_assistant_models.enums import (
+ AlbumType,
+ ConfigEntryType,
+ ContentType,
+ ImageType,
+ ProviderFeature,
+ StreamType,
+)
from music_assistant_models.errors import (
InvalidDataError,
LoginFailed,
)
from music_assistant_models.media_items import (
Album,
- AlbumType,
Artist,
AudioFormat,
- ContentType,
- ImageType,
ItemMapping,
MediaItemImage,
MediaItemType,
from ytmusicapi.constants import SUPPORTED_LANGUAGES
from ytmusicapi.exceptions import YTMusicServerError
-from music_assistant.helpers import (
+from music_assistant.helpers.auth import AuthenticationHelper
+from music_assistant.models.music_provider import MusicProvider
+
+from .helpers import (
add_remove_playlist_tracks,
get_album,
get_artist,
refresh_oauth_token,
search,
)
-from music_assistant.helpers.auth import AuthenticationHelper
-from music_assistant.models.music_provider import MusicProvider
if TYPE_CHECKING:
from music_assistant_models.config_entries import ProviderConfig
pip install --upgrade uv
uv pip install -e "."
uv pip install -e ".[test]"
+uv pip install -r requirements_all.txt
pre-commit install