From: Marcel van der Veldt Date: Thu, 6 Feb 2025 11:32:23 +0000 (+0100) Subject: Fix Podcast and Audiobook support on SMB Filesystem provider (#1944) X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=a089610cd77f11409d77a41e377ad7dab70a336d;p=music-assistant-server.git Fix Podcast and Audiobook support on SMB Filesystem provider (#1944) * Chore: Start full sync after reset of library db * Fix Podcast and Audiobook support on SMB Filesystem provider --- diff --git a/music_assistant/controllers/music.py b/music_assistant/controllers/music.py index 321c8a8c..ca4b851c 100644 --- a/music_assistant/controllers/music.py +++ b/music_assistant/controllers/music.py @@ -1261,6 +1261,8 @@ class MusicController(CoreController): db_path = os.path.join(self.mass.storage_path, "library.db") await asyncio.to_thread(os.remove, db_path) await self._setup_database() + # initiate full sync + self.start_sync() async def __create_database_tables(self) -> None: """Create database tables.""" diff --git a/music_assistant/providers/filesystem_local/__init__.py b/music_assistant/providers/filesystem_local/__init__.py index d61f28bb..9fc581ad 100644 --- a/music_assistant/providers/filesystem_local/__init__.py +++ b/music_assistant/providers/filesystem_local/__init__.py @@ -106,15 +106,8 @@ async def setup( mass: MusicAssistant, manifest: ProviderManifest, config: ProviderConfig ) -> ProviderInstanceType: """Initialize provider(instance) with given configuration.""" - conf_path = config.get_value(CONF_PATH) - if not await isdir(conf_path): - msg = f"Music Directory {conf_path} does not exist" - raise SetupFailedError(msg) - prov = LocalFileSystemProvider(mass, manifest, config) - prov.base_path = str(config.get_value(CONF_PATH)) - await prov.check_write_access() - prov.media_content_type = cast(str, config.get_value(CONF_ENTRY_CONTENT_TYPE.key)) - return prov + base_path = cast(str, config.get_value(CONF_PATH)) + return LocalFileSystemProvider(mass, manifest, config, base_path) async def get_config_entries( @@ -137,17 +130,7 @@ async def get_config_entries( CONF_ENTRY_PATH, CONF_ENTRY_MISSING_ALBUM_ARTIST, ) - media_type = values.get(CONF_ENTRY_CONTENT_TYPE.key) - if media_type == "music": - return ( - CONF_ENTRY_PATH, - CONF_ENTRY_CONTENT_TYPE_READ_ONLY, - CONF_ENTRY_MISSING_ALBUM_ARTIST, - ) - return ( - CONF_ENTRY_PATH, - CONF_ENTRY_CONTENT_TYPE_READ_ONLY, - ) + return (CONF_ENTRY_PATH, CONF_ENTRY_CONTENT_TYPE_READ_ONLY, CONF_ENTRY_MISSING_ALBUM_ARTIST) class LocalFileSystemProvider(MusicProvider): @@ -159,10 +142,19 @@ class LocalFileSystemProvider(MusicProvider): Supports m3u files for playlists. """ - base_path: str - write_access: bool = False - sync_running: bool = False - media_content_type: str = "music" + def __init__( + self, + mass: MusicAssistant, + manifest: ProviderManifest, + config: ProviderConfig, + base_path: str, + ) -> None: + """Initialize MusicProvider.""" + super().__init__(mass, manifest, config) + self.base_path: str = base_path + self.write_access: bool = False + self.sync_running: bool = False + self.media_content_type = cast(str, config.get_value(CONF_ENTRY_CONTENT_TYPE.key)) @property def supported_features(self) -> set[ProviderFeature]: @@ -200,6 +192,13 @@ class LocalFileSystemProvider(MusicProvider): postfix = self.base_path.split(os.sep)[-1] return f"{self.manifest.name} {postfix}" + async def handle_async_init(self) -> None: + """Handle async initialization of the provider.""" + if not await isdir(self.base_path): + msg = f"Music Directory {self.base_path} does not exist" + raise SetupFailedError(msg) + await self.check_write_access() + async def search( self, search_query: str, diff --git a/music_assistant/providers/filesystem_smb/__init__.py b/music_assistant/providers/filesystem_smb/__init__.py index 8c186018..bc2c5b00 100644 --- a/music_assistant/providers/filesystem_smb/__init__.py +++ b/music_assistant/providers/filesystem_smb/__init__.py @@ -16,6 +16,7 @@ from music_assistant.helpers.util import get_ip_from_host from music_assistant.providers.filesystem_local import LocalFileSystemProvider, exists, makedirs from music_assistant.providers.filesystem_local.constants import ( CONF_ENTRY_CONTENT_TYPE, + CONF_ENTRY_CONTENT_TYPE_READ_ONLY, CONF_ENTRY_MISSING_ALBUM_ARTIST, ) @@ -46,7 +47,9 @@ async def setup( if not share or "/" in share or "\\" in share: msg = "Invalid share name" raise LoginFailed(msg) - return SMBFileSystemProvider(mass, manifest, config) + # base_path will be the path where we're going to mount the remote share + base_path = f"/tmp/{config.instance_id}" # noqa: S108 + return SMBFileSystemProvider(mass, manifest, config, base_path) async def get_config_entries( @@ -63,7 +66,7 @@ async def get_config_entries( values: the (intermediate) raw values for config entries sent with the action. """ # ruff: noqa: ARG001 - return ( + base_entries = ( ConfigEntry( key=CONF_HOST, type=ConfigEntryType.STRING, @@ -107,7 +110,6 @@ async def get_config_entries( description="[optional] Use if your music is stored in a sublevel of the share. " "E.g. 'collections' or 'albums/A-K'.", ), - CONF_ENTRY_CONTENT_TYPE, ConfigEntry( key=CONF_MOUNT_OPTIONS, type=ConfigEntryType.STRING, @@ -121,6 +123,16 @@ async def get_config_entries( CONF_ENTRY_MISSING_ALBUM_ARTIST, ) + if instance_id is None or values is None: + return ( + CONF_ENTRY_CONTENT_TYPE, + *base_entries, + ) + return ( + *base_entries, + CONF_ENTRY_CONTENT_TYPE_READ_ONLY, + ) + class SMBFileSystemProvider(LocalFileSystemProvider): """ @@ -149,11 +161,8 @@ class SMBFileSystemProvider(LocalFileSystemProvider): async def handle_async_init(self) -> None: """Handle async initialization of the provider.""" - # base_path will be the path where we're going to mount the remote share - self.base_path = f"/tmp/{self.instance_id}" # noqa: S108 if not await exists(self.base_path): await makedirs(self.base_path) - try: # do unmount first to cleanup any unexpected state await self.unmount(ignore_error=True) @@ -161,7 +170,6 @@ class SMBFileSystemProvider(LocalFileSystemProvider): except Exception as err: msg = f"Connection failed for the given details: {err}" raise LoginFailed(msg) from err - await self.check_write_access() async def unload(self, is_removed: bool = False) -> None: