multi_value=True,
)
-CONF_LIBRARY_IMPORT_OPTIONS = [
- ConfigValueOption("Import into the library only", "import_only"),
- ConfigValueOption("Import into the library, and mark as favorite", "import_as_favorite"),
- ConfigValueOption("Do not import into the library", "no_import"),
-]
-CONF_ENTRY_LIBRARY_IMPORT_ARTISTS = ConfigEntry(
- key="library_import_artists",
- type=ConfigEntryType.STRING,
- label="Import Artists from this provider into Music Assistant",
- description="Whether to import (favourite/library) artists from this "
- "provider into the Music Assistant Library.",
- options=CONF_LIBRARY_IMPORT_OPTIONS,
- default_value="import_as_favorite",
+CONF_ENTRY_LIBRARY_SYNC_ARTISTS = ConfigEntry(
+ key="library_sync_artists",
+ type=ConfigEntryType.BOOLEAN,
+ label="Sync Library Artists from this provider to Music Assistant",
+ description="Whether to synchronize (favourited/in-library) Artists from this "
+ "provider to the Music Assistant Library.",
+ default_value=True,
category="sync_options",
)
-CONF_ENTRY_LIBRARY_IMPORT_ALBUMS = ConfigEntry(
- key="library_import_albums",
- type=ConfigEntryType.STRING,
- label="Import Albums from this provider into Music Assistant",
- description="Whether to import (favourite/library) albums from this "
- "provider into the Music Assistant Library. \n\n"
+CONF_ENTRY_LIBRARY_SYNC_ALBUMS = ConfigEntry(
+ key="library_sync_albums",
+ type=ConfigEntryType.BOOLEAN,
+ label="Sync Library Albums from this provider to Music Assistant",
+ description="Whether to import (favourited/in-library) Albums from this "
+ "provider to the Music Assistant Library. \n\n"
"Please note that by adding an Album into the Music Assistant library, "
- "the album artists will always be imported as well (not as favorites though).",
- options=CONF_LIBRARY_IMPORT_OPTIONS,
- default_value="import_as_favorite",
+ "the Album Artists will always be imported as well.",
+ default_value=True,
category="sync_options",
)
-CONF_ENTRY_LIBRARY_IMPORT_TRACKS = ConfigEntry(
- key="library_import_tracks",
- type=ConfigEntryType.STRING,
- label="Import Tracks from this provider into Music Assistant",
- description="Whether to import (favourite/library) tracks from this "
- "provider into the Music Assistant Library. \n\n"
+CONF_ENTRY_LIBRARY_SYNC_TRACKS = ConfigEntry(
+ key="library_sync_tracks",
+ type=ConfigEntryType.BOOLEAN,
+ label="Sync Library Tracks from this provider to Music Assistant",
+ description="Whether to import (favourited/in-library) Tracks from this "
+ "provider to the Music Assistant Library. \n\n"
"Please note that by adding a Track into the Music Assistant library, "
- "the track artists and album will always be imported as well (not as favorites though).",
- options=CONF_LIBRARY_IMPORT_OPTIONS,
- default_value="import_as_favorite",
+ "the Track's Artists and Album will always be imported as well.",
+ default_value=True,
category="sync_options",
)
-CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS = ConfigEntry(
- key="library_import_playlists",
- type=ConfigEntryType.STRING,
- label="Import Playlists from this provider into Music Assistant",
- description="Whether to import (favourite/library) playlists from this "
- "provider into the Music Assistant Library.",
- options=CONF_LIBRARY_IMPORT_OPTIONS,
- default_value="import_as_favorite",
+CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS = ConfigEntry(
+ key="library_sync_playlists",
+ type=ConfigEntryType.BOOLEAN,
+ label="Sync Library Playlists from this provider to Music Assistant",
+ description="Whether to import (favourited/in-library) Playlists from this "
+ "provider to the Music Assistant Library.",
+ default_value=True,
category="sync_options",
)
-CONF_ENTRY_LIBRARY_IMPORT_PODCASTS = ConfigEntry(
- key="library_import_podcasts",
- type=ConfigEntryType.STRING,
- label="Import Podcasts from this provider into Music Assistant",
- description="Whether to import (favourite/library) podcasts from this "
- "provider into the Music Assistant Library.",
- options=CONF_LIBRARY_IMPORT_OPTIONS,
- default_value="import_as_favorite",
+CONF_ENTRY_LIBRARY_SYNC_PODCASTS = ConfigEntry(
+ key="library_sync_podcasts",
+ type=ConfigEntryType.BOOLEAN,
+ label="Sync Library Podcasts from this provider to Music Assistant",
+ description="Whether to import (favourited/in-library) Podcasts from this "
+ "provider to the Music Assistant Library.",
+ default_value=True,
category="sync_options",
)
-CONF_ENTRY_LIBRARY_IMPORT_AUDIOBOOKS = ConfigEntry(
- key="library_import_audiobooks",
- type=ConfigEntryType.STRING,
- label="Import Audiobooks from this provider into Music Assistant",
- description="Whether to import (favourite/library) audiobooks from this "
- "provider into the Music Assistant Library.",
- options=CONF_LIBRARY_IMPORT_OPTIONS,
- default_value="import_as_favorite",
+CONF_ENTRY_LIBRARY_SYNC_AUDIOBOOKS = ConfigEntry(
+ key="library_sync_audiobooks",
+ type=ConfigEntryType.BOOLEAN,
+ label="Sync Library Audiobooks from this provider to Music Assistant",
+ description="Whether to import (favourited/in-library) Audiobooks from this "
+ "provider to the Music Assistant Library.",
+ default_value=True,
category="sync_options",
)
-CONF_ENTRY_LIBRARY_IMPORT_RADIOS = ConfigEntry(
- key="library_import_radios",
- type=ConfigEntryType.STRING,
- label="Import Radios from this provider into Music Assistant",
- description="Whether to import (favourite/library) radios from this "
- "provider into the Music Assistant Library.",
- options=CONF_LIBRARY_IMPORT_OPTIONS,
- default_value="import_as_favorite",
+CONF_ENTRY_LIBRARY_SYNC_RADIOS = ConfigEntry(
+ key="library_sync_radios",
+ type=ConfigEntryType.BOOLEAN,
+ label="Sync Library Radios from this provider to Music Assistant",
+ description="Whether to import (favourited/in-library) Radio stations from this "
+ "provider to the Music Assistant Library.",
+ default_value=True,
category="sync_options",
)
-CONF_ENTRY_LIBRARY_IMPORT_ALBUM_TRACKS = ConfigEntry(
- key="library_import_album_tracks",
+CONF_ENTRY_LIBRARY_SYNC_ALBUM_TRACKS = ConfigEntry(
+ key="library_sync_album_tracks",
type=ConfigEntryType.BOOLEAN,
label="Import album tracks",
- description="By default, when importing albums into the library, "
+ description="By default, when importing Albums into the library, "
"only the Album itself will be imported into the Music Assistant Library, "
"allowing you to manually browse and select which tracks you want to import. \n\n"
"If you want to override this default behavior, "
"you can use this configuration option.\n\n"
- "Please note that some streaming providers may already define this behavior unsolicited, "
+ "Please note that some (streaming) providers may already define this behavior unsolicited, "
"by automatically adding all tracks from the album to their library/favorites.",
default_value=False,
category="sync_options",
)
-CONF_ENTRY_LIBRARY_IMPORT_PLAYLIST_TRACKS = ConfigEntry(
- key="library_import_playlist_tracks",
+CONF_ENTRY_LIBRARY_SYNC_PLAYLIST_TRACKS = ConfigEntry(
+ key="library_sync_playlist_tracks",
type=ConfigEntryType.STRING,
label="Import playlist tracks",
- description="By default, when importing playlists into the library, "
+ description="By default, when importing Playlists into the library, "
"only the Playlist itself will be imported into the Music Assistant Library, "
- "allowing you to browse and play the playlist and optionally add any individual "
- "tracks of the playlist to the Music Assistant Library manually. \n\n"
+ "allowing you to browse and play the Playlist and optionally add any individual "
+ "tracks of the Playlist to the Music Assistant Library manually. \n\n"
"Use this configuration option to override this default behavior, "
- "by specifying the playlists for which you'd like to import all tracks.\n"
+ "by specifying the Playlists for which you'd like to import all tracks.\n"
"You can either enter the Playlist name (case sensitive) or the Playlist URI.",
default_value=[],
category="sync_options",
multi_value=True,
)
-CONF_ENTRY_LIBRARY_EXPORT_ADD = ConfigEntry(
- key="library_export_add",
- type=ConfigEntryType.STRING,
- label="Sync back library additions",
- description="Specify the behavior if an item is (manually) added to the "
- "Music Assistant Library (or favorites). \n"
- "Should we synchronise that action back to the provider?\n\n"
- "You can choose to add items to the provider's library as soon as you "
- "add it to the Music Assistant Library or only do that when you mark the item as "
- "favorite. \nIf you do not want to sync back to the provider at all, you can choose "
- "the 'Don't sync back to the provider' option.",
- default_value="export_favorite",
- category="sync_options",
- options=[
- ConfigValueOption("When an item is added to the library", "export_library"),
- ConfigValueOption("When an item is marked as favorite", "export_favorite"),
- ConfigValueOption("Don't sync back to the provider", "no_export"),
- ],
-)
-CONF_ENTRY_LIBRARY_EXPORT_REMOVE = ConfigEntry(
- key="library_export_remove",
- type=ConfigEntryType.STRING,
- label="Sync back library removals",
- description="Specify the behavior if an item is (manually) removed from the "
- "Music Assistant Library (or favorites). \n"
+CONF_ENTRY_LIBRARY_SYNC_BACK = ConfigEntry(
+ key="library_sync_back",
+ type=ConfigEntryType.BOOLEAN,
+ label="Sync back library additions/removals (2-way sync)",
+ description="Specify the behavior if an item is manually added to "
+ "(or removed from) the Music Assistant Library. \n"
"Should we synchronise that action back to the provider?\n\n"
- "You can choose to remove items from the provider's library as soon as you (manually) "
- "remove it from the Music Assistant Library or only do that when you unmark the item as "
- "favorite. \nIf you do not want to sync back to the provider at all, you can choose "
- "the 'Don't sync back to the provider' option.\n\n"
- "Please note that if you you don't sync removals back to the provider and you have enabled "
- "automatic sync/import for this provider, the item may reappear in the library "
+ "Please note that if you you don't sync back to the provider and you have enabled "
+ "automatic sync/import for this provider, a removed item may reappear in the library "
"the next time a sync is performed.",
- default_value="export_favorite",
+ default_value=True,
category="sync_options",
- options=[
- ConfigValueOption("When an item is removed from the library", "export_library"),
- ConfigValueOption("When an item is unmarked as favorite", "export_favorite"),
- ConfigValueOption("Don't sync back to the provider", "no_export"),
- ],
)
+
CONF_PROVIDER_SYNC_INTERVAL_OPTIONS = [
ConfigValueOption("Disable automatic sync for this mediatype", 0),
ConfigValueOption("Every 30 minutes", 30),
options=CONF_PROVIDER_SYNC_INTERVAL_OPTIONS,
default_value=720,
category="sync_options",
- depends_on=CONF_ENTRY_LIBRARY_IMPORT_ARTISTS.key,
+ depends_on=CONF_ENTRY_LIBRARY_SYNC_ARTISTS.key,
depends_on_value_not="no_import",
required=True,
)
options=CONF_PROVIDER_SYNC_INTERVAL_OPTIONS,
default_value=720,
category="sync_options",
- depends_on=CONF_ENTRY_LIBRARY_IMPORT_ALBUMS.key,
+ depends_on=CONF_ENTRY_LIBRARY_SYNC_ALBUMS.key,
depends_on_value_not="no_import",
required=True,
)
options=CONF_PROVIDER_SYNC_INTERVAL_OPTIONS,
default_value=720,
category="sync_options",
- depends_on=CONF_ENTRY_LIBRARY_IMPORT_TRACKS.key,
+ depends_on=CONF_ENTRY_LIBRARY_SYNC_TRACKS.key,
depends_on_value_not="no_import",
required=True,
)
options=CONF_PROVIDER_SYNC_INTERVAL_OPTIONS,
default_value=720,
category="sync_options",
- depends_on=CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS.key,
+ depends_on=CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS.key,
depends_on_value_not="no_import",
required=True,
)
options=CONF_PROVIDER_SYNC_INTERVAL_OPTIONS,
default_value=720,
category="sync_options",
- depends_on=CONF_ENTRY_LIBRARY_IMPORT_PODCASTS.key,
+ depends_on=CONF_ENTRY_LIBRARY_SYNC_PODCASTS.key,
depends_on_value_not="no_import",
required=True,
)
options=CONF_PROVIDER_SYNC_INTERVAL_OPTIONS,
default_value=720,
category="sync_options",
- depends_on=CONF_ENTRY_LIBRARY_IMPORT_AUDIOBOOKS.key,
+ depends_on=CONF_ENTRY_LIBRARY_SYNC_AUDIOBOOKS.key,
depends_on_value_not="no_import",
required=True,
)
options=CONF_PROVIDER_SYNC_INTERVAL_OPTIONS,
default_value=720,
category="sync_options",
- depends_on=CONF_ENTRY_LIBRARY_IMPORT_RADIOS.key,
+ depends_on=CONF_ENTRY_LIBRARY_SYNC_RADIOS.key,
depends_on_value_not="no_import",
required=True,
)
CONF_DEPRECATED_EQ_BASS,
CONF_DEPRECATED_EQ_MID,
CONF_DEPRECATED_EQ_TREBLE,
- CONF_ENTRY_LIBRARY_EXPORT_ADD,
- CONF_ENTRY_LIBRARY_EXPORT_REMOVE,
- CONF_ENTRY_LIBRARY_IMPORT_ALBUM_TRACKS,
- CONF_ENTRY_LIBRARY_IMPORT_ALBUMS,
- CONF_ENTRY_LIBRARY_IMPORT_ARTISTS,
- CONF_ENTRY_LIBRARY_IMPORT_AUDIOBOOKS,
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLIST_TRACKS,
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS,
- CONF_ENTRY_LIBRARY_IMPORT_PODCASTS,
- CONF_ENTRY_LIBRARY_IMPORT_RADIOS,
- CONF_ENTRY_LIBRARY_IMPORT_TRACKS,
+ CONF_ENTRY_LIBRARY_SYNC_ALBUM_TRACKS,
+ CONF_ENTRY_LIBRARY_SYNC_ALBUMS,
+ CONF_ENTRY_LIBRARY_SYNC_ARTISTS,
+ CONF_ENTRY_LIBRARY_SYNC_AUDIOBOOKS,
+ CONF_ENTRY_LIBRARY_SYNC_BACK,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLIST_TRACKS,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS,
+ CONF_ENTRY_LIBRARY_SYNC_PODCASTS,
+ CONF_ENTRY_LIBRARY_SYNC_RADIOS,
+ CONF_ENTRY_LIBRARY_SYNC_TRACKS,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_ALBUMS,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_ARTISTS,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_AUDIOBOOKS,
if manifest.type == ProviderType.MUSIC:
# library sync settings
if ProviderFeature.LIBRARY_ARTISTS in supported_features:
- extra_entries.append(CONF_ENTRY_LIBRARY_IMPORT_ARTISTS)
+ extra_entries.append(CONF_ENTRY_LIBRARY_SYNC_ARTISTS)
if ProviderFeature.LIBRARY_ALBUMS in supported_features:
- extra_entries.append(CONF_ENTRY_LIBRARY_IMPORT_ALBUMS)
+ extra_entries.append(CONF_ENTRY_LIBRARY_SYNC_ALBUMS)
if provider and provider.is_streaming_provider:
- extra_entries.append(CONF_ENTRY_LIBRARY_IMPORT_ALBUM_TRACKS)
+ extra_entries.append(CONF_ENTRY_LIBRARY_SYNC_ALBUM_TRACKS)
if ProviderFeature.LIBRARY_TRACKS in supported_features:
- extra_entries.append(CONF_ENTRY_LIBRARY_IMPORT_TRACKS)
+ extra_entries.append(CONF_ENTRY_LIBRARY_SYNC_TRACKS)
if ProviderFeature.LIBRARY_PLAYLISTS in supported_features:
- extra_entries.append(CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS)
+ extra_entries.append(CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS)
if provider and provider.is_streaming_provider:
- extra_entries.append(CONF_ENTRY_LIBRARY_IMPORT_PLAYLIST_TRACKS)
+ extra_entries.append(CONF_ENTRY_LIBRARY_SYNC_PLAYLIST_TRACKS)
if ProviderFeature.LIBRARY_AUDIOBOOKS in supported_features:
- extra_entries.append(CONF_ENTRY_LIBRARY_IMPORT_AUDIOBOOKS)
+ extra_entries.append(CONF_ENTRY_LIBRARY_SYNC_AUDIOBOOKS)
if ProviderFeature.LIBRARY_PODCASTS in supported_features:
- extra_entries.append(CONF_ENTRY_LIBRARY_IMPORT_PODCASTS)
+ extra_entries.append(CONF_ENTRY_LIBRARY_SYNC_PODCASTS)
if ProviderFeature.LIBRARY_RADIOS in supported_features:
- extra_entries.append(CONF_ENTRY_LIBRARY_IMPORT_RADIOS)
+ extra_entries.append(CONF_ENTRY_LIBRARY_SYNC_RADIOS)
# sync interval settings
if ProviderFeature.LIBRARY_ARTISTS in supported_features:
extra_entries.append(CONF_ENTRY_PROVIDER_SYNC_INTERVAL_ARTISTS)
ProviderFeature.LIBRARY_RADIOS_EDIT,
}
):
- extra_entries.append(CONF_ENTRY_LIBRARY_EXPORT_ADD)
- extra_entries.append(CONF_ENTRY_LIBRARY_EXPORT_REMOVE)
+ extra_entries.append(CONF_ENTRY_LIBRARY_SYNC_BACK)
return [
*DEFAULT_PROVIDER_CONFIG_ENTRIES,
extra_query_parts=[f"WHERE album_tracks.album_id = {item_id}"],
)
- async def add_item_mapping_as_album_to_library(
- self, item: ItemMapping, import_as_favorite: bool = False
- ) -> Album:
+ async def add_item_mapping_as_album_to_library(self, item: ItemMapping) -> Album:
"""
Add an ItemMapping as an Album to the library.
from music_assistant_models.unique_list import UniqueList
from music_assistant.constants import (
- CONF_ENTRY_LIBRARY_EXPORT_ADD,
- CONF_ENTRY_LIBRARY_EXPORT_REMOVE,
DB_TABLE_ALBUM_ARTISTS,
DB_TABLE_ALBUM_TRACKS,
DB_TABLE_ALBUMS,
if not provider.library_supported(media_type):
continue
# handle mediatype specific sync config
- conf_key = f"library_import_{media_type}s"
+ conf_key = f"library_sync_{media_type}s"
sync_conf = await self.mass.config.get_provider_config_value(
provider.instance_id, conf_key
)
- if sync_conf == "no_import":
+ if not sync_conf:
continue
- import_as_favorite = sync_conf == "import_as_favorite"
- self._start_provider_sync(provider, media_type, import_as_favorite)
+ self._start_provider_sync(provider, media_type)
@api_command("music/synctasks")
def get_running_sync_tasks(self) -> list[SyncTask]:
provider = self.mass.get_provider(prov_mapping.provider_instance)
if not provider.library_edit_supported(item.media_type):
continue
- if prov_mapping.in_library:
+ if not provider.library_sync_back_enabled(full_item.media_type):
continue
- conf_export_library = provider.config.get_value(
- CONF_ENTRY_LIBRARY_EXPORT_ADD.key, CONF_ENTRY_LIBRARY_EXPORT_ADD.default_value
- )
- if conf_export_library != "export_favorite":
+ if not prov_mapping.in_library:
+ # add to provider library first
+ prov_item = deepcopy(full_item)
+ prov_item.provider = prov_mapping.provider_instance
+ prov_item.item_id = prov_mapping.item_id
+ await provider.library_add(prov_item)
+ provider_mappings_updated = True
+ prov_mapping.in_library = True
+ # set favorite at provider
+ if not provider.library_favorites_edit_supported(full_item.media_type):
continue
- prov_item = deepcopy(full_item)
- prov_item.provider = prov_mapping.provider_instance
- prov_item.item_id = prov_mapping.item_id
- self.mass.create_task(provider.library_add(prov_item))
- provider_mappings_updated = True
+ await provider.set_favorite(prov_mapping.item_id, full_item.media_type, True)
+
if provider_mappings_updated:
await ctrl.set_provider_mappings(full_item.item_id, full_item.provider_mappings)
if not prov_mapping.in_library:
continue
provider = self.mass.get_provider(prov_mapping.provider_instance)
- if not provider.library_edit_supported(full_item.media_type):
+ if not provider.library_favorites_edit_supported(full_item.media_type):
continue
- conf_export_library = provider.config.get_value(
- CONF_ENTRY_LIBRARY_EXPORT_REMOVE.key, CONF_ENTRY_LIBRARY_EXPORT_REMOVE.default_value
- )
- if conf_export_library != "export_favorite":
+ if not provider.library_sync_back_enabled(full_item.media_type):
continue
- self.mass.create_task(provider.library_remove(prov_mapping.item_id, media_type))
+ self.mass.create_task(provider.set_favorite(prov_mapping.item_id, media_type, False))
prov_mapping.in_library = False
provider_mappings_updated = True
if provider_mappings_updated:
provider = self.mass.get_provider(prov_mapping.provider_instance)
if not provider.library_edit_supported(full_item.media_type):
continue
- conf_export_library = provider.config.get_value(
- CONF_ENTRY_LIBRARY_EXPORT_REMOVE.key, CONF_ENTRY_LIBRARY_EXPORT_REMOVE.default_value
- )
- if conf_export_library != "export_library":
+ if not provider.library_sync_back_enabled(full_item.media_type):
continue
+ prov_mapping.in_library = False
self.mass.create_task(provider.library_remove(prov_mapping.item_id, media_type))
# remove from library
await ctrl.remove_item_from_library(library_item_id, recursive)
provider = self.mass.get_provider(prov_mapping.provider_instance)
if not provider.library_edit_supported(full_item.media_type):
continue
- conf_export_library = provider.config.get_value(
- CONF_ENTRY_LIBRARY_EXPORT_ADD.key, CONF_ENTRY_LIBRARY_EXPORT_ADD.default_value
- )
- if conf_export_library != "export_library":
+ if not provider.library_sync_back_enabled(full_item.media_type):
continue
prov_item = deepcopy(full_item) if full_item.provider == "library" else full_item
prov_item.provider = prov_mapping.provider_instance
)
return []
- def _start_provider_sync(
- self, provider: MusicProvider, media_type: MediaType, import_as_favorite: bool
- ) -> None:
+ def _start_provider_sync(self, provider: MusicProvider, media_type: MediaType) -> None:
"""Start sync task on provider and track progress."""
# check if we're not already running a sync task for this provider/mediatype
for sync_task in self.in_progress_syncs:
# Wrap the provider sync into a lock to prevent
# race conditions when multiple providers are syncing at the same time.
async with self._sync_lock:
- await provider.sync_library(media_type, import_as_favorite)
+ await provider.sync_library(media_type)
# we keep track of running sync tasks
task = self.mass.create_task(run_sync())
# cancel any existing timers
self.mass.cancel_timer(job_key)
# handle mediatype specific sync config
- conf_key = f"library_import_{media_type}s"
+ conf_key = f"library_sync_{media_type}s"
sync_conf = await self.mass.config.get_provider_config_value(provider.instance_id, conf_key)
- if sync_conf == "no_import":
+ if not sync_conf:
return
conf_key = f"provider_sync_interval_{media_type.value}s"
sync_interval = cast(
# sync disabled for this media type
return
sync_interval = sync_interval * 60 # config interval is in minutes - convert to seconds
- import_as_favorite = sync_conf == "import_as_favorite"
if is_initial:
# schedule the first sync run
self._start_provider_sync,
provider,
media_type,
- import_as_favorite,
task_id=job_key,
)
)
from music_assistant.constants import (
- CONF_ENTRY_LIBRARY_IMPORT_ALBUM_TRACKS,
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLIST_TRACKS,
+ CONF_ENTRY_LIBRARY_SYNC_ALBUM_TRACKS,
+ CONF_ENTRY_LIBRARY_SYNC_BACK,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLIST_TRACKS,
)
from .provider import Provider
)
return True
+ async def set_favorite(self, prov_item_id: str, media_type: MediaType, favorite: bool) -> None:
+ """
+ Set favorite status for item in provider's library.
+
+ Only called if provider supports ProviderFeature.FAVORITE_*_EDIT.
+
+ Note that this should only be implemented by a provider implementation if
+ the provider differentiates between 'in library' and 'favorited' items.
+ """
+ if (
+ media_type == MediaType.ARTIST
+ and ProviderFeature.FAVORITE_ARTISTS_EDIT in self.supported_features
+ ):
+ raise NotImplementedError
+ if (
+ media_type == MediaType.ALBUM
+ and ProviderFeature.FAVORITE_ALBUMS_EDIT in self.supported_features
+ ):
+ raise NotImplementedError
+ if (
+ media_type == MediaType.TRACK
+ and ProviderFeature.FAVORITE_TRACKS_EDIT in self.supported_features
+ ):
+ raise NotImplementedError
+ if (
+ media_type == MediaType.PLAYLIST
+ and ProviderFeature.FAVORITE_PLAYLISTS_EDIT in self.supported_features
+ ):
+ raise NotImplementedError
+ if (
+ media_type == MediaType.RADIO
+ and ProviderFeature.FAVORITE_RADIOS_EDIT in self.supported_features
+ ):
+ raise NotImplementedError
+ if (
+ media_type == MediaType.AUDIOBOOK
+ and ProviderFeature.FAVORITE_AUDIOBOOKS_EDIT in self.supported_features
+ ):
+ raise NotImplementedError
+ if (
+ media_type == MediaType.PODCAST
+ and ProviderFeature.FAVORITE_PODCASTS_EDIT in self.supported_features
+ ):
+ raise NotImplementedError
+
async def add_playlist_tracks(self, prov_playlist_id: str, prov_track_ids: list[str]) -> None:
"""Add track(s) to playlist.
raise NotImplementedError
return []
- async def sync_library(self, media_type: MediaType, import_as_favorite: bool) -> None:
+ async def sync_library(self, media_type: MediaType) -> None:
"""Run library sync for this provider."""
# this reference implementation may be overridden
# with a provider specific approach if needed
raise UnsupportedFeaturedException("Library sync not supported for this media type")
if media_type == MediaType.ARTIST:
- cur_db_ids = await self._sync_library_artists(import_as_favorite)
+ cur_db_ids = await self._sync_library_artists()
elif media_type == MediaType.ALBUM:
- cur_db_ids = await self._sync_library_albums(import_as_favorite)
+ cur_db_ids = await self._sync_library_albums()
elif media_type == MediaType.TRACK:
- cur_db_ids = await self._sync_library_tracks(import_as_favorite)
+ cur_db_ids = await self._sync_library_tracks()
elif media_type == MediaType.PLAYLIST:
- cur_db_ids = await self._sync_library_playlists(import_as_favorite)
+ cur_db_ids = await self._sync_library_playlists()
elif media_type == MediaType.PODCAST:
- cur_db_ids = await self._sync_library_podcasts(import_as_favorite)
+ cur_db_ids = await self._sync_library_podcasts()
elif media_type == MediaType.RADIO:
- cur_db_ids = await self._sync_library_radios(import_as_favorite)
+ cur_db_ids = await self._sync_library_radios()
elif media_type == MediaType.AUDIOBOOK:
- cur_db_ids = await self._sync_library_audiobooks(import_as_favorite)
+ cur_db_ids = await self._sync_library_audiobooks()
else:
# this should not happen but catch it anyways
raise UnsupportedFeaturedException(f"Unexpected media type to sync: {media_type}")
category=CACHE_CATEGORY_PREV_LIBRARY_IDS,
)
- async def _sync_library_artists(self, import_as_favorite: bool) -> set[int]:
+ async def _sync_library_artists(self) -> set[int]:
"""Sync Library Artists to Music Assistant library."""
self.logger.debug("Start sync of Artists to Music Assistant library.")
cur_db_ids: set[int] = set()
try:
if not library_item:
# add item to the library
- if import_as_favorite:
- prov_item.favorite = True
library_item = await self.mass.music.artists.add_item_to_library(prov_item)
- elif not library_item.favorite and import_as_favorite:
+ elif not library_item.favorite and prov_item.favorite:
# existing library item not favorite but should be
await self.mass.music.artists.set_favorite(library_item.item_id, True)
elif not self._check_provider_mappings(library_item, prov_item, True):
)
return cur_db_ids
- async def _sync_library_albums(self, import_as_favorite: bool) -> set[int]:
+ async def _sync_library_albums(self) -> set[int]:
"""Sync Library Albums to Music Assistant library."""
self.logger.debug("Start sync of Albums to Music Assistant library.")
cur_db_ids: set[int] = set()
conf_sync_album_tracks = self.config.get_value(
- CONF_ENTRY_LIBRARY_IMPORT_ALBUM_TRACKS.key,
- CONF_ENTRY_LIBRARY_IMPORT_ALBUM_TRACKS.default_value,
+ CONF_ENTRY_LIBRARY_SYNC_ALBUM_TRACKS.key,
+ CONF_ENTRY_LIBRARY_SYNC_ALBUM_TRACKS.default_value,
)
sync_album_tracks = bool(conf_sync_album_tracks)
async for prov_item in self.get_library_albums():
try:
if not library_item:
# add item to the library
- if import_as_favorite:
- prov_item.favorite = True
library_item = await self.mass.music.albums.add_item_to_library(prov_item)
- elif not library_item.favorite and import_as_favorite:
+ elif not library_item.favorite and prov_item.favorite:
# existing library item not favorite but should be
await self.mass.music.albums.set_favorite(library_item.item_id, True)
elif not self._check_provider_mappings(library_item, prov_item, True):
str(err),
)
- async def _sync_library_audiobooks(self, import_as_favorite: bool) -> set[int]:
+ async def _sync_library_audiobooks(self) -> set[int]:
"""Sync Library Audiobooks to Music Assistant library."""
self.logger.debug("Start sync of Audiobooks to Music Assistant library.")
cur_db_ids: set[int] = set()
try:
if not library_item:
# add item to the library
- if import_as_favorite:
- prov_item.favorite = True
library_item = await self.mass.music.audiobooks.add_item_to_library(prov_item)
- elif not library_item.favorite and import_as_favorite:
+ elif not library_item.favorite and prov_item.favorite:
# existing library item not favorite but should be
await self.mass.music.audiobooks.set_favorite(library_item.item_id, True)
elif not self._check_provider_mappings(library_item, prov_item, True):
)
return cur_db_ids
- async def _sync_library_playlists(self, import_as_favorite: bool) -> set[int]:
+ async def _sync_library_playlists(self) -> set[int]:
"""Sync Library Playlists to Music Assistant library."""
self.logger.debug("Start sync of Playlists to Music Assistant library.")
conf_sync_playlist_tracks = self.config.get_value(
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLIST_TRACKS.key,
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLIST_TRACKS.default_value,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLIST_TRACKS.key,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLIST_TRACKS.default_value,
)
conf_sync_playlist_tracks = cast("list[str]", conf_sync_playlist_tracks)
cur_db_ids: set[int] = set()
try:
if not library_item:
# add item to the library
- if import_as_favorite:
- prov_item.favorite = True
library_item = await self.mass.music.playlists.add_item_to_library(prov_item)
- elif not library_item.favorite and import_as_favorite:
+ elif not library_item.favorite and prov_item.favorite:
# existing library item not favorite but should be
await self.mass.music.playlists.set_favorite(library_item.item_id, True)
elif not self._check_provider_mappings(library_item, prov_item, True):
str(err),
)
- async def _sync_library_tracks(self, import_as_favorite: bool) -> set[int]:
+ async def _sync_library_tracks(self) -> set[int]:
"""Sync Library Tracks to Music Assistant library."""
self.logger.debug("Start sync of Tracks to Music Assistant library.")
cur_db_ids: set[int] = set()
continue
if not library_item:
# add item to the library
- if import_as_favorite:
- prov_item.favorite = True
library_item = await self.mass.music.tracks.add_item_to_library(prov_item)
elif library_item.available != prov_item.available:
# existing library item but availability changed
library_item = await self.mass.music.tracks.update_item_in_library(
library_item.item_id, prov_item
)
- elif not library_item.favorite and import_as_favorite:
+ elif not library_item.favorite and prov_item.favorite:
# existing library item not favorite but should be
await self.mass.music.tracks.set_favorite(library_item.item_id, True)
elif not self._check_provider_mappings(library_item, prov_item, True):
)
return cur_db_ids
- async def _sync_library_podcasts(self, import_as_favorite: bool) -> set[int]:
+ async def _sync_library_podcasts(self) -> set[int]:
"""Sync Library Podcasts to Music Assistant library."""
self.logger.debug("Start sync of Podcasts to Music Assistant library.")
cur_db_ids: set[int] = set()
try:
if not library_item:
# add item to the library
- if import_as_favorite:
- prov_item.favorite = True
library_item = await self.mass.music.podcasts.add_item_to_library(prov_item)
elif library_item.available != prov_item.available:
# existing library item but availability changed
library_item = await self.mass.music.podcasts.update_item_in_library(
library_item.item_id, prov_item
)
- elif not library_item.favorite and import_as_favorite:
+ elif not library_item.favorite and prov_item.favorite:
# existing library item not favorite but should be
await self.mass.music.podcasts.set_favorite(library_item.item_id, True)
elif not self._check_provider_mappings(library_item, prov_item, True):
)
return cur_db_ids
- async def _sync_library_radios(self, import_as_favorite: bool) -> set[int]:
+ async def _sync_library_radios(self) -> set[int]:
"""Sync Library Radios to Music Assistant library."""
self.logger.debug("Start sync of Radios to Music Assistant library.")
cur_db_ids: set[int] = set()
try:
if not library_item:
# add item to the library
- if import_as_favorite:
- prov_item.favorite = True
library_item = await self.mass.music.radio.add_item_to_library(prov_item)
- elif not library_item.favorite and import_as_favorite:
+ elif not library_item.favorite and prov_item.favorite:
# existing library item not favorite but should be
await self.mass.music.radio.set_favorite(library_item.item_id, True)
elif not self._check_provider_mappings(library_item, prov_item, True):
return ProviderFeature.LIBRARY_PODCASTS_EDIT in self.supported_features
return False
+ def library_sync_back_enabled(self, media_type: MediaType) -> bool:
+ """Return if Library sync back is enabled for given MediaType on this provider."""
+ conf_value = self.config.get_value(
+ CONF_ENTRY_LIBRARY_SYNC_BACK.key, CONF_ENTRY_LIBRARY_SYNC_BACK.default_value
+ )
+ return bool(conf_value)
+
+ def library_favorites_edit_supported(self, media_type: MediaType) -> bool:
+ """Return if favorites add/remove is supported for given MediaType on this provider."""
+ if media_type == MediaType.ARTIST:
+ return ProviderFeature.FAVORITE_ARTISTS_EDIT in self.supported_features
+ if media_type == MediaType.ALBUM:
+ return ProviderFeature.FAVORITE_ALBUMS_EDIT in self.supported_features
+ if media_type == MediaType.TRACK:
+ return ProviderFeature.FAVORITE_TRACKS_EDIT in self.supported_features
+ if media_type == MediaType.PLAYLIST:
+ return ProviderFeature.FAVORITE_PLAYLISTS_EDIT in self.supported_features
+ if media_type == MediaType.RADIO:
+ return ProviderFeature.FAVORITE_RADIOS_EDIT in self.supported_features
+ if media_type == MediaType.AUDIOBOOK:
+ return ProviderFeature.FAVORITE_AUDIOBOOKS_EDIT in self.supported_features
+ if media_type == MediaType.PODCAST:
+ return ProviderFeature.FAVORITE_PODCASTS_EDIT in self.supported_features
+ return False
+
async def iter_playlist_tracks(
self,
prov_playlist_id: str,
# This is only called if you reported the RECOMMENDATIONS feature in the supported_features.
return []
- async def sync_library(self, media_type: MediaType, import_as_favorite: bool) -> None:
+ async def sync_library(self, media_type: MediaType) -> None:
"""Run library sync for this provider."""
# Run a full sync of the library for the given media type.
# This is called by the music controller to sync items from your provider to the library.
return False
@handle_refresh_token
- async def sync_library(self, media_type: MediaType, import_as_favorite: bool) -> None:
+ async def sync_library(self, media_type: MediaType) -> None:
"""Obtain audiobook library ids and podcast library ids."""
libraries = await self._client.get_all_libraries()
if len(libraries) == 0:
and media_type == MediaType.PODCAST
):
self.libraries.podcasts[library.id_] = LibraryHelper(name=library.name)
- await super().sync_library(media_type, import_as_favorite)
+ await super().sync_library(media_type)
await self._cache_set_helper_libraries()
# update playlog
BUILTIN_PLAYLISTS,
BUILTIN_PLAYLISTS_ENTRIES,
COLLAGE_IMAGE_PLAYLISTS,
- CONF_ENTRY_LIBRARY_EXPORT_ADD_HIDDEN,
- CONF_ENTRY_LIBRARY_EXPORT_REMOVE_HIDDEN,
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS_HIDDEN,
- CONF_ENTRY_LIBRARY_IMPORT_RADIOS_HIDDEN,
- CONF_ENTRY_LIBRARY_IMPORT_TRACKS_HIDDEN,
+ CONF_ENTRY_LIBRARY_SYNC_BACK_HIDDEN,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS_HIDDEN,
+ CONF_ENTRY_LIBRARY_SYNC_RADIOS_HIDDEN,
+ CONF_ENTRY_LIBRARY_SYNC_TRACKS_HIDDEN,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_PLAYLISTS_MOD,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_RADIOS_HIDDEN,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_TRACKS_HIDDEN,
return (
*BUILTIN_PLAYLISTS_ENTRIES,
# hide some of the default (dynamic) entries for library management
- CONF_ENTRY_LIBRARY_IMPORT_TRACKS_HIDDEN,
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS_HIDDEN,
- CONF_ENTRY_LIBRARY_IMPORT_RADIOS_HIDDEN,
+ CONF_ENTRY_LIBRARY_SYNC_TRACKS_HIDDEN,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS_HIDDEN,
+ CONF_ENTRY_LIBRARY_SYNC_RADIOS_HIDDEN,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_TRACKS_HIDDEN,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_RADIOS_HIDDEN,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_PLAYLISTS_MOD,
- CONF_ENTRY_LIBRARY_EXPORT_ADD_HIDDEN,
- CONF_ENTRY_LIBRARY_EXPORT_REMOVE_HIDDEN,
+ CONF_ENTRY_LIBRARY_SYNC_BACK_HIDDEN,
)
from music_assistant_models.media_items import MediaItemImage
from music_assistant.constants import (
- CONF_ENTRY_LIBRARY_EXPORT_ADD,
- CONF_ENTRY_LIBRARY_EXPORT_REMOVE,
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS,
- CONF_ENTRY_LIBRARY_IMPORT_RADIOS,
- CONF_ENTRY_LIBRARY_IMPORT_TRACKS,
+ CONF_ENTRY_LIBRARY_SYNC_BACK,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS,
+ CONF_ENTRY_LIBRARY_SYNC_RADIOS,
+ CONF_ENTRY_LIBRARY_SYNC_TRACKS,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_PLAYLISTS,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_RADIOS,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_TRACKS,
remotely_accessible=False,
)
-CONF_ENTRY_LIBRARY_IMPORT_TRACKS_HIDDEN = ConfigEntry.from_dict(
+CONF_ENTRY_LIBRARY_SYNC_TRACKS_HIDDEN = ConfigEntry.from_dict(
{
- **CONF_ENTRY_LIBRARY_IMPORT_TRACKS.to_dict(),
+ **CONF_ENTRY_LIBRARY_SYNC_TRACKS.to_dict(),
"hidden": True,
- "default_value": "import_only",
+ "default_value": True,
}
)
-CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS_HIDDEN = ConfigEntry.from_dict(
+CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS_HIDDEN = ConfigEntry.from_dict(
{
- **CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS.to_dict(),
+ **CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS.to_dict(),
"hidden": True,
- "default_value": "import_only",
+ "default_value": True,
}
)
-CONF_ENTRY_LIBRARY_IMPORT_TRACKS_HIDDEN = ConfigEntry.from_dict(
+CONF_ENTRY_LIBRARY_SYNC_TRACKS_HIDDEN = ConfigEntry.from_dict(
{
- **CONF_ENTRY_LIBRARY_IMPORT_TRACKS.to_dict(),
+ **CONF_ENTRY_LIBRARY_SYNC_TRACKS.to_dict(),
"hidden": True,
- "default_value": "import_only",
+ "default_value": True,
}
)
-CONF_ENTRY_LIBRARY_IMPORT_RADIOS_HIDDEN = ConfigEntry.from_dict(
+CONF_ENTRY_LIBRARY_SYNC_RADIOS_HIDDEN = ConfigEntry.from_dict(
{
- **CONF_ENTRY_LIBRARY_IMPORT_RADIOS.to_dict(),
+ **CONF_ENTRY_LIBRARY_SYNC_RADIOS.to_dict(),
"hidden": True,
- "default_value": "import_only",
+ "default_value": True,
}
)
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_PLAYLISTS_MOD = ConfigEntry.from_dict(
"default_value": 180,
}
)
-CONF_ENTRY_LIBRARY_EXPORT_ADD_HIDDEN = ConfigEntry.from_dict(
+CONF_ENTRY_LIBRARY_SYNC_BACK_HIDDEN = ConfigEntry.from_dict(
{
- **CONF_ENTRY_LIBRARY_EXPORT_ADD.to_dict(),
+ **CONF_ENTRY_LIBRARY_SYNC_BACK.to_dict(),
"hidden": True,
- "default_value": "export_library",
- }
-)
-CONF_ENTRY_LIBRARY_EXPORT_REMOVE_HIDDEN = ConfigEntry.from_dict(
- {
- **CONF_ENTRY_LIBRARY_EXPORT_REMOVE.to_dict(),
- "hidden": True,
- "default_value": "export_library",
+ "default_value": True,
}
)
CONF_ENTRY_CONTENT_TYPE,
CONF_ENTRY_CONTENT_TYPE_READ_ONLY,
CONF_ENTRY_IGNORE_ALBUM_PLAYLISTS,
- CONF_ENTRY_LIBRARY_IMPORT_AUDIOBOOKS,
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS,
- CONF_ENTRY_LIBRARY_IMPORT_PODCASTS,
- CONF_ENTRY_LIBRARY_IMPORT_TRACKS,
+ CONF_ENTRY_LIBRARY_SYNC_AUDIOBOOKS,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS,
+ CONF_ENTRY_LIBRARY_SYNC_PODCASTS,
+ CONF_ENTRY_LIBRARY_SYNC_TRACKS,
CONF_ENTRY_MISSING_ALBUM_ARTIST,
CONF_ENTRY_PATH,
IMAGE_EXTENSIONS,
CONF_ENTRY_PATH,
CONF_ENTRY_MISSING_ALBUM_ARTIST,
CONF_ENTRY_IGNORE_ALBUM_PLAYLISTS,
- CONF_ENTRY_LIBRARY_IMPORT_TRACKS,
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS,
- CONF_ENTRY_LIBRARY_IMPORT_PODCASTS,
- CONF_ENTRY_LIBRARY_IMPORT_AUDIOBOOKS,
+ CONF_ENTRY_LIBRARY_SYNC_TRACKS,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS,
+ CONF_ENTRY_LIBRARY_SYNC_PODCASTS,
+ CONF_ENTRY_LIBRARY_SYNC_AUDIOBOOKS,
]
if instance_id is None or values is None:
return (CONF_ENTRY_CONTENT_TYPE, *base_entries)
)
return items
- async def sync_library(self, media_type: MediaType, import_as_favorite: bool) -> None:
+ async def sync_library(self, media_type: MediaType) -> None:
"""Run library sync for this provider."""
assert self.mass.music.database
start_time = time.time()
try:
for item in listdir(self.base_path):
prev_checksum = file_checksums.get(item.relative_path)
- if self._process_item(item, prev_checksum, import_as_favorite):
+ if self._process_item(item, prev_checksum):
cur_filenames.add(item.relative_path)
finally:
self.sync_running = False
# process orphaned albums and artists
await self._process_orphaned_albums_and_artists()
- def _process_item(
- self, item: FileSystemItem, prev_checksum: str | None, import_as_favorite: bool
- ) -> bool:
+ def _process_item(self, item: FileSystemItem, prev_checksum: str | None) -> bool:
"""Process a single item. NOT async friendly."""
try:
self.logger.log(VERBOSE_LOG_LEVEL, "Processing: %s", item.relative_path)
# add/update track to db
# note that filesystem items are always overwriting existing info
# when they are detected as changed
- track.favorite = import_as_favorite
+ track.favorite = False # TODO: implement favorite status based on rating ?
await self.mass.music.tracks.add_item_to_library(
track, overwrite_existing=prev_checksum is not None
)
# add/update audiobook to db
# note that filesystem items are always overwriting existing info
# when they are detected as changed
- audiobook.favorite = import_as_favorite
await self.mass.music.audiobooks.add_item_to_library(
audiobook, overwrite_existing=prev_checksum is not None
)
# add/update episode to db
# note that filesystem items are always overwriting existing info
# when they are detected as changed
- episode.favorite = import_as_favorite
await self.mass.music.podcasts.add_item_to_library(
episode.podcast, overwrite_existing=prev_checksum is not None
)
async def process_playlist() -> None:
playlist = await self.get_playlist(item.relative_path)
- # add/update] playlist to db
- playlist.favorite = import_as_favorite
+ # add/update playlist to db
await self.mass.music.playlists.add_item_to_library(
playlist,
overwrite_existing=prev_checksum is not None,
from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption
from music_assistant_models.enums import ConfigEntryType, ProviderFeature
-from music_assistant.constants import CONF_LIBRARY_IMPORT_OPTIONS
-
CONF_MISSING_ALBUM_ARTIST_ACTION = "missing_album_artist_action"
CONF_CONTENT_TYPE = "content_type"
{**CONF_ENTRY_CONTENT_TYPE.to_dict(), "read_only": True}
)
-CONF_ENTRY_LIBRARY_IMPORT_TRACKS = ConfigEntry(
- key="library_import_tracks",
- type=ConfigEntryType.STRING,
+CONF_ENTRY_LIBRARY_SYNC_TRACKS = ConfigEntry(
+ key="library_sync_tracks",
+ type=ConfigEntryType.BOOLEAN,
label="Import tracks/files into the Music Assistant library",
description="Define how/if you want to import tracks/files from the filesystem "
"into the Music Assistant Library. \nWhen not importing into the library, "
"they can still be manually browsed using the Browse feature. \n\n"
"Please note that by adding a Track into the Music Assistant library, "
- "the track artists and album will always be imported as well (not as favorites though).",
- options=CONF_LIBRARY_IMPORT_OPTIONS,
- default_value="import_only",
+ "the track artists and album will always be imported as well.",
+ default_value=True,
category="sync_options",
depends_on=CONF_CONTENT_TYPE,
depends_on_value="music",
)
-CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS = ConfigEntry(
- key="library_import_playlists",
- type=ConfigEntryType.STRING,
+CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS = ConfigEntry(
+ key="library_sync_playlists",
+ type=ConfigEntryType.BOOLEAN,
label="Import playlists (m3u files) into the Music Assistant library",
description="Define how/if you want to import playlists (m3u files) from the filesystem "
"into the Music Assistant Library. \nWhen not importing into the library, "
"they can still be manually browsed using the Browse feature.",
- options=CONF_LIBRARY_IMPORT_OPTIONS,
- default_value="import_only",
+ default_value=True,
category="sync_options",
depends_on=CONF_CONTENT_TYPE,
depends_on_value="music",
)
-CONF_ENTRY_LIBRARY_IMPORT_PODCASTS = ConfigEntry(
- key="library_import_podcasts",
- type=ConfigEntryType.STRING,
+CONF_ENTRY_LIBRARY_SYNC_PODCASTS = ConfigEntry(
+ key="library_sync_podcasts",
+ type=ConfigEntryType.BOOLEAN,
label="Import Podcasts(files) into the Music Assistant library",
description="Define how/if you want to import Podcasts(files) from the filesystem "
"into the Music Assistant Library. \nWhen not importing into the library, "
"they can still be manually browsed using the Browse feature.",
- options=CONF_LIBRARY_IMPORT_OPTIONS,
- default_value="import_only",
+ default_value=True,
category="sync_options",
depends_on=CONF_CONTENT_TYPE,
depends_on_value="podcasts",
)
-CONF_ENTRY_LIBRARY_IMPORT_AUDIOBOOKS = ConfigEntry(
- key="library_import_audiobooks",
- type=ConfigEntryType.STRING,
+CONF_ENTRY_LIBRARY_SYNC_AUDIOBOOKS = ConfigEntry(
+ key="library_sync_audiobooks",
+ type=ConfigEntryType.BOOLEAN,
label="Import Audiobooks(files) into the Music Assistant library",
description="Define how/if you want to import Audiobooks(files) from the filesystem "
"into the Music Assistant Library. \nWhen not importing into the library, "
"they can still be manually browsed using the Browse feature.",
- options=CONF_LIBRARY_IMPORT_OPTIONS,
- default_value="import_only",
+ default_value=True,
category="sync_options",
depends_on=CONF_CONTENT_TYPE,
depends_on_value="audiobooks",
CONF_ENTRY_CONTENT_TYPE,
CONF_ENTRY_CONTENT_TYPE_READ_ONLY,
CONF_ENTRY_IGNORE_ALBUM_PLAYLISTS,
- CONF_ENTRY_LIBRARY_IMPORT_AUDIOBOOKS,
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS,
- CONF_ENTRY_LIBRARY_IMPORT_PODCASTS,
- CONF_ENTRY_LIBRARY_IMPORT_TRACKS,
+ CONF_ENTRY_LIBRARY_SYNC_AUDIOBOOKS,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS,
+ CONF_ENTRY_LIBRARY_SYNC_PODCASTS,
+ CONF_ENTRY_LIBRARY_SYNC_TRACKS,
CONF_ENTRY_MISSING_ALBUM_ARTIST,
)
),
CONF_ENTRY_MISSING_ALBUM_ARTIST,
CONF_ENTRY_IGNORE_ALBUM_PLAYLISTS,
- CONF_ENTRY_LIBRARY_IMPORT_TRACKS,
- CONF_ENTRY_LIBRARY_IMPORT_PLAYLISTS,
- CONF_ENTRY_LIBRARY_IMPORT_PODCASTS,
- CONF_ENTRY_LIBRARY_IMPORT_AUDIOBOOKS,
+ CONF_ENTRY_LIBRARY_SYNC_TRACKS,
+ CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS,
+ CONF_ENTRY_LIBRARY_SYNC_PODCASTS,
+ CONF_ENTRY_LIBRARY_SYNC_AUDIOBOOKS,
)
if instance_id is None or values is None:
from radios import FilterBy, Order, RadioBrowser, RadioBrowserError, Station
from music_assistant.constants import (
- CONF_ENTRY_LIBRARY_EXPORT_ADD,
- CONF_ENTRY_LIBRARY_EXPORT_REMOVE,
- CONF_ENTRY_LIBRARY_IMPORT_RADIOS,
+ CONF_ENTRY_LIBRARY_SYNC_BACK,
+ CONF_ENTRY_LIBRARY_SYNC_RADIOS,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_RADIOS,
)
from music_assistant.controllers.cache import use_cache
CONF_STORED_RADIOS = "stored_radios"
-CONF_ENTRY_LIBRARY_IMPORT_RADIOS_HIDDEN = ConfigEntry.from_dict(
+CONF_ENTRY_LIBRARY_SYNC_RADIOS_HIDDEN = ConfigEntry.from_dict(
{
- **CONF_ENTRY_LIBRARY_IMPORT_RADIOS.to_dict(),
+ **CONF_ENTRY_LIBRARY_SYNC_RADIOS.to_dict(),
"hidden": True,
"default_value": "import_only",
}
"default_value": 180,
}
)
-CONF_ENTRY_LIBRARY_EXPORT_ADD_HIDDEN = ConfigEntry.from_dict(
+CONF_ENTRY_LIBRARY_SYNC_BACK_HIDDEN = ConfigEntry.from_dict(
{
- **CONF_ENTRY_LIBRARY_EXPORT_ADD.to_dict(),
+ **CONF_ENTRY_LIBRARY_SYNC_BACK.to_dict(),
"hidden": True,
- "default_value": "export_library",
- }
-)
-CONF_ENTRY_LIBRARY_EXPORT_REMOVE_HIDDEN = ConfigEntry.from_dict(
- {
- **CONF_ENTRY_LIBRARY_EXPORT_REMOVE.to_dict(),
- "hidden": True,
- "default_value": "export_library",
+ "default_value": True,
}
)
hidden=True,
),
# hide some of the default (dynamic) entries for library management
- CONF_ENTRY_LIBRARY_IMPORT_RADIOS_HIDDEN,
+ CONF_ENTRY_LIBRARY_SYNC_RADIOS_HIDDEN,
CONF_ENTRY_PROVIDER_SYNC_INTERVAL_RADIOS_HIDDEN,
- CONF_ENTRY_LIBRARY_EXPORT_ADD_HIDDEN,
- CONF_ENTRY_LIBRARY_EXPORT_REMOVE_HIDDEN,
+ CONF_ENTRY_LIBRARY_SYNC_BACK_HIDDEN,
)
"ifaddr==0.2.0",
"mashumaro==3.16",
"music-assistant-frontend==2.16.5",
- "music-assistant-models==1.1.61",
+ "music-assistant-models==1.1.62",
"mutagen==1.47.0",
"orjson==3.11.3",
"pillow==11.3.0",
lyricsgenius==3.7.2
mashumaro==3.16
music-assistant-frontend==2.16.5
-music-assistant-models==1.1.61
+music-assistant-models==1.1.62
mutagen==1.47.0
numpy==2.2.6
orjson==3.11.3