Fix AlbumType detection (#330)
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Thu, 19 May 2022 21:59:32 +0000 (23:59 +0200)
committerGitHub <noreply@github.com>
Thu, 19 May 2022 21:59:32 +0000 (23:59 +0200)
* Fix AlbumType detection

music_assistant/controllers/music/albums.py
music_assistant/controllers/music/artists.py
music_assistant/controllers/music/providers/filesystem.py
music_assistant/helpers/database.py

index ac55b90db6a74bdfa0e4ce35404d78c3af0dde08..6303b604019d11b8dc8a8fcec7526d9b25d1e3e7 100644 (file)
@@ -57,10 +57,10 @@ class AlbumsController(MediaControllerBase[Album]):
         # merge duplicates using a dict
         final_items: Dict[str, Track] = {}
         for track in tracks:
-            if track.disc_number is None or track.track_number is None:
-                key = f"{track.name}.{track.version}"
-            else:
-                key = f"{track.disc_number}.{track.track_number}"
+            key = f".{track.name}.{track.version}"
+            if track.disc_number and track.track_number:
+                key += f".{track.disc_number}.{track.track_number}"
+
             if key in final_items:
                 final_items[key].provider_ids.update(track.provider_ids)
             else:
index d157af198401c9ff050b1329b5e79b7e8a261941..26b03aa84dfc6d02b37a993a4f90f0a746044a50 100644 (file)
@@ -48,7 +48,7 @@ class ArtistsController(MediaControllerBase[Artist]):
             self.get_provider_artist_toptracks(item.item_id, item.prov_id)
             for item in artist.provider_ids
         ]
-        # use intermediate set to remove duplicates
+        # use intermediate set to remove (some) duplicates
         return list(set(itertools.chain.from_iterable(await asyncio.gather(*coros))))
 
     async def albums(
@@ -64,7 +64,7 @@ class ArtistsController(MediaControllerBase[Artist]):
             self.get_provider_artist_albums(item.item_id, item.prov_id)
             for item in artist.provider_ids
         ]
-        # use intermediate set to remove duplicates
+        # use intermediate set to remove (some) duplicates
         return list(set(itertools.chain.from_iterable(await asyncio.gather(*coros))))
 
     async def add(self, item: Artist) -> Artist:
index b977955428bca18cb0992bbd5836f9a8934b90b9..40176176fc60caa739eec677ad5bf612e66e6d61 100644 (file)
@@ -459,14 +459,6 @@ class FileSystemProvider(MusicProvider):
                 in_library=True,
             )
 
-            # try to guess the album type
-            if name.lower() == track.album.name.lower():
-                track.album.album_type = AlbumType.SINGLE
-            elif track.album.artist not in (x.name for x in track.artists):
-                track.album.album_type = AlbumType.COMPILATION
-            else:
-                track.album.album_type = AlbumType.ALBUM
-
         if (
             track.album
             and track.album.artist
@@ -596,7 +588,8 @@ class FileSystemProvider(MusicProvider):
                 artist.metadata.genres = set(split_items(genre))
         # find local images
         images = []
-        for _filename in os.listdir(artist_path):
+        async for _path in scantree(artist_path):
+            _filename = _path.path
             ext = _filename.split(".")[-1]
             if ext not in ("jpg", "png"):
                 continue
@@ -679,9 +672,22 @@ class FileSystemProvider(MusicProvider):
                 album.metadata.genres = set(split_items(genre))
         # parse name/version
         album.name, album.version = parse_title_and_version(album.name)
+
+        # try to guess the album type
+        album_tracks = [
+            x async for x in scantree(album_path) if TinyTag.is_supported(x.path)
+        ]
+        if artist and artist.sort_name == "variousartists":
+            album.album_type = AlbumType.COMPILATION
+        elif len(album_tracks) <= 5:
+            album.album_type = AlbumType.SINGLE
+        else:
+            album.album_type = AlbumType.ALBUM
+
         # find local images
         images = []
-        for _filename in os.listdir(album_path):
+        async for _path in scantree(album_path):
+            _filename = _path.path
             ext = _filename.split(".")[-1]
             if ext not in ("jpg", "png"):
                 continue
index a3b381ff4c10daf124e9be805ba603b9bda72a97..69c151bf08d0207b2afc87e33d8e3c80e51a62b8 100755 (executable)
@@ -10,7 +10,7 @@ if TYPE_CHECKING:
     from music_assistant.mass import MusicAssistant
 
 
-SCHEMA_VERSION = 12
+SCHEMA_VERSION = 13
 
 TABLE_PROV_MAPPINGS = "provider_mappings"
 TABLE_TRACK_LOUDNESS = "track_loudness"
@@ -199,7 +199,7 @@ class Database:
                 # always create db tables if they don't exist to prevent errors trying to access them later
                 await self.__create_database_tables(db)
 
-                if prev_version < 12:
+                if prev_version < 13:
                     # fixed nasty bugs in file provider, start clean just in case.
                     await db.execute(f"DROP TABLE IF EXISTS {TABLE_ARTISTS}")
                     await db.execute(f"DROP TABLE IF EXISTS {TABLE_ALBUMS}")