simplify media changed events a bit
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Wed, 27 Jul 2022 15:53:42 +0000 (17:53 +0200)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Wed, 27 Jul 2022 15:53:42 +0000 (17:53 +0200)
only send media_item added/changed event after all actions are done

music_assistant/controllers/music/albums.py
music_assistant/controllers/music/artists.py
music_assistant/controllers/music/playlists.py
music_assistant/controllers/music/radio.py
music_assistant/controllers/music/tracks.py
music_assistant/mass.py

index 76575cdd6db40fe0393050f9734af8ba61941235..a0ca7524c4ef238493f73edeb7eedf26faa51d05 100644 (file)
@@ -92,16 +92,24 @@ class AlbumsController(MediaControllerBase[Album]):
         """Add album to local db and return the database item."""
         # grab additional metadata
         await self.mass.metadata.get_album_metadata(item)
-        db_item = await self.add_db_item(item)
+        existing = await self.get_db_item_by_prov_id(item.item_id, item.provider)
+        if existing:
+            db_item = await self.update_db_item(existing.item_id, item)
+        else:
+            db_item = await self.add_db_item(item)
         # also fetch same album on all providers
         await self._match(db_item)
+        # return final db_item after all match/metadata actions
         db_item = await self.get_db_item(db_item.item_id)
-        # add the album's tracks to the db
-        for prov in item.provider_ids:
-            for track in await self._get_provider_album_tracks(
-                prov.item_id, prov.prov_type, prov.prov_id
-            ):
-                await self.mass.music.tracks.add_db_item(track)
+        self.mass.signal_event(
+            MassEvent(
+                EventType.MEDIA_ITEM_UPDATED
+                if existing
+                else EventType.MEDIA_ITEM_ADDED,
+                db_item.uri,
+                db_item,
+            )
+        )
         return db_item
 
     async def _get_provider_album_tracks(
@@ -203,11 +211,7 @@ class AlbumsController(MediaControllerBase[Album]):
             item_id = new_item["item_id"]
             self.logger.debug("added %s to database", item.name)
             # return created object
-            db_item = await self.get_db_item(item_id)
-            self.mass.signal_event(
-                MassEvent(EventType.MEDIA_ITEM_ADDED, db_item.uri, db_item)
-            )
-            return db_item
+            return await self.get_db_item(item_id)
 
     async def update_db_item(
         self,
index a33f40b9858256fac007421ce8bac1b1db8fed15..b985fa15a9098e40894ef233a9be531530a44e6a 100644 (file)
@@ -117,10 +117,24 @@ class ArtistsController(MediaControllerBase[Artist]):
         """Add artist to local db and return the database item."""
         # grab musicbrainz id and additional metadata
         await self.mass.metadata.get_artist_metadata(item)
-        db_item = await self.add_db_item(item)
+        existing = await self.get_db_item_by_prov_id(item.item_id, item.provider)
+        if existing:
+            db_item = await self.update_db_item(existing.item_id, item)
+        else:
+            db_item = await self.add_db_item(item)
         # also fetch same artist on all providers
         await self.match_artist(db_item)
+        # return final db_item after all match/metadata actions
         db_item = await self.get_db_item(db_item.item_id)
+        self.mass.signal_event(
+            MassEvent(
+                EventType.MEDIA_ITEM_UPDATED
+                if existing
+                else EventType.MEDIA_ITEM_ADDED,
+                db_item.uri,
+                db_item,
+            )
+        )
         return db_item
 
     async def match_artist(self, db_artist: Artist):
@@ -264,11 +278,7 @@ class ArtistsController(MediaControllerBase[Artist]):
             item_id = new_item["item_id"]
             self.logger.debug("added %s to database", item.name)
             # return created object
-            db_item = await self.get_db_item(item_id)
-            self.mass.signal_event(
-                MassEvent(EventType.MEDIA_ITEM_ADDED, db_item.uri, db_item)
-            )
-            return db_item
+            return await self.get_db_item(item_id)
 
     async def update_db_item(
         self,
index 2656d570abf854ac94874e07fd890da89291bd02..52666b0c10ae01d8e84fcf4c545fa2617f454322 100644 (file)
@@ -85,7 +85,21 @@ class PlaylistController(MediaControllerBase[Playlist]):
         """Add playlist to local db and return the new database item."""
         item.metadata.last_refresh = int(time())
         await self.mass.metadata.get_playlist_metadata(item)
-        return await self.add_db_item(item)
+        existing = await self.get_db_item_by_prov_id(item.item_id, item.provider)
+        if existing:
+            db_item = await self.update_db_item(existing.item_id, item)
+        else:
+            db_item = await self.add_db_item(item)
+        self.mass.signal_event(
+            MassEvent(
+                EventType.MEDIA_ITEM_UPDATED
+                if existing
+                else EventType.MEDIA_ITEM_ADDED,
+                db_item.uri,
+                db_item,
+            )
+        )
+        return db_item
 
     async def create(
         self, name: str, prov_id: Union[ProviderType, str, None] = None
@@ -234,11 +248,7 @@ class PlaylistController(MediaControllerBase[Playlist]):
             item_id = new_item["item_id"]
             self.logger.debug("added %s to database", item.name)
             # return created object
-            db_item = await self.get_db_item(item_id)
-            self.mass.signal_event(
-                MassEvent(EventType.MEDIA_ITEM_ADDED, db_item.uri, db_item)
-            )
-            return db_item
+            return await self.get_db_item(item_id)
 
     async def update_db_item(
         self,
index a64aa2fcdb59c109eed70b4b0bc388e2a09f5fcc..5f263b0d2dd7f22a36426cef112d406be4d8e42d 100644 (file)
@@ -61,7 +61,21 @@ class RadioController(MediaControllerBase[Radio]):
         """Add radio to local db and return the new database item."""
         item.metadata.last_refresh = int(time())
         await self.mass.metadata.get_radio_metadata(item)
-        return await self.add_db_item(item)
+        existing = await self.get_db_item_by_prov_id(item.item_id, item.provider)
+        if existing:
+            db_item = await self.update_db_item(existing.item_id, item)
+        else:
+            db_item = await self.add_db_item(item)
+        self.mass.signal_event(
+            MassEvent(
+                EventType.MEDIA_ITEM_UPDATED
+                if existing
+                else EventType.MEDIA_ITEM_ADDED,
+                db_item.uri,
+                db_item,
+            )
+        )
+        return db_item
 
     async def add_db_item(self, item: Radio, overwrite_existing: bool = False) -> Radio:
         """Add a new item record to the database."""
@@ -79,11 +93,7 @@ class RadioController(MediaControllerBase[Radio]):
             item_id = new_item["item_id"]
             self.logger.debug("added %s to database", item.name)
             # return created object
-            db_item = await self.get_db_item(item_id)
-            self.mass.signal_event(
-                MassEvent(EventType.MEDIA_ITEM_ADDED, db_item.uri, db_item)
-            )
-            return db_item
+            return await self.get_db_item(item_id)
 
     async def update_db_item(
         self,
index 2d78363e7903113b716a4083b572296816612a9f..6e05d2a89eccc55fec94abcc6bdb616c37bdce10 100644 (file)
@@ -63,10 +63,25 @@ class TracksController(MediaControllerBase[Track]):
         assert item.artists
         # grab additional metadata
         await self.mass.metadata.get_track_metadata(item)
-        db_item = await self.add_db_item(item)
+        existing = await self.get_db_item_by_prov_id(item.item_id, item.provider)
+        if existing:
+            db_item = await self.update_db_item(existing.item_id, item)
+        else:
+            db_item = await self.add_db_item(item)
         # also fetch same track on all providers (will also get other quality versions)
         await self._match(db_item)
-        return await self.get_db_item(db_item.item_id)
+        # return final db_item after all match/metadata actions
+        db_item = await self.get_db_item(db_item.item_id)
+        self.mass.signal_event(
+            MassEvent(
+                EventType.MEDIA_ITEM_UPDATED
+                if existing
+                else EventType.MEDIA_ITEM_ADDED,
+                db_item.uri,
+                db_item,
+            )
+        )
+        return db_item
 
     async def versions(
         self,
@@ -195,11 +210,7 @@ class TracksController(MediaControllerBase[Track]):
             item_id = new_item["item_id"]
             # return created object
             self.logger.debug("added %s to database: %s", item.name, item_id)
-            db_item = await self.get_db_item(item_id)
-            self.mass.signal_event(
-                MassEvent(EventType.MEDIA_ITEM_ADDED, db_item.uri, db_item)
-            )
-            return db_item
+            return await self.get_db_item(item_id)
 
     async def update_db_item(
         self,
index cf355b018210d840d72287729137eb97014a64d5..f5ce954b9a20a58db9ccc222ff03472a4ae64231 100644 (file)
@@ -102,6 +102,10 @@ class MusicAssistant:
         """Signal event to subscribers."""
         if self.closed:
             return
+        if self.logger.isEnabledFor(logging.DEBUG):
+            self.logger.getChild("event").debug(
+                "%s %s", event.type.value, event.object_id or ""
+            )
         for cb_func, event_filter, id_filter in self._listeners:
             if not (event_filter is None or event.type in event_filter):
                 continue