[gnome-music/wip/mschraal/tageditor-13feb2020: 48/53] coresong: Add logic to update a tracker resource



commit 4ac59f9c5103af8432fae29ac0a99ab34f079eec
Author: Sumaid Syed <sumaidsyed gmail com>
Date:   Wed Nov 20 18:51:22 2019 +0100

    coresong: Add logic to update a tracker resource

 gnomemusic/coregrilo.py |  12 +++++
 gnomemusic/coresong.py  | 113 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 125 insertions(+)
---
diff --git a/gnomemusic/coregrilo.py b/gnomemusic/coregrilo.py
index 4a1e1856..7feb27bd 100644
--- a/gnomemusic/coregrilo.py
+++ b/gnomemusic/coregrilo.py
@@ -207,6 +207,18 @@ class CoreGrilo(GObject.GObject):
                     None)
                 break
 
+    def writeback_tracker(self, media, tags):
+        """Use Tracker queries to update tags.
+
+        The tags are associated with a Tracker resource
+        (song, album, artist or external resource), so they can cannot
+        be updated with grilo writeback support.
+
+        :param Grl.Media media: A Grilo media item
+        :param deque tags: A list of tags to update
+        """
+        self._tracker_wrapper.update_tags(media, tags)
+
     def search(self, text):
         for wrapper in self._wrappers.values():
             wrapper.search(text)
diff --git a/gnomemusic/coresong.py b/gnomemusic/coresong.py
index ec8d2371..94b4a9f6 100644
--- a/gnomemusic/coresong.py
+++ b/gnomemusic/coresong.py
@@ -22,12 +22,14 @@
 # code, but you are not obligated to do so.  If you do not wish to do so,
 # delete this exception statement from your version.
 
+from collections import deque
 from enum import IntEnum
 
 import gi
 gi.require_version('Grl', '0.3')
 from gi.repository import Grl, GLib, GObject
 
+from gnomemusic.musiclogger import MusicLogger
 import gnomemusic.utils as utils
 
 
@@ -35,6 +37,8 @@ class CoreSong(GObject.GObject):
     """Exposes a Grl.Media with relevant data as properties
     """
 
+    _log = MusicLogger()
+
     album = GObject.Property(type=str)
     album_disc_number = GObject.Property(type=int)
     artist = GObject.Property(type=str)
@@ -150,3 +154,112 @@ class CoreSong(GObject.GObject):
             self._grilo.get_tags(self, callback)
 
         self._grilo.get_chromaprint(self, chromaprint_retrieved)
+
+    def _update_from_tracker(self, tags):
+        """Update tags with Tracker requests.
+
+        The tags need to be inserted in a certain order: For example, a
+        musicbrainz release group identifier is associated with an album
+        resource. So, it needs to be updated after the album.
+        The following order is respected:
+        1. resources of a song (mb-recording-id and mb-track-id)
+        2. artist resource
+        3. resources of an artist (mb-artist-id)
+        4. album and albumdisc (with the disc number tag) resources
+        5. resources of an album (album artist, mb-release-id and
+           mb-release-group-id)
+
+        :param List tags: list of updated
+        """
+        changed_tags = deque()
+
+        mb_recording_id = tags["mb-recording-id"]
+        if (mb_recording_id
+                and mb_recording_id != self.props.media.get_mb_recording_id()):
+            self.props.media.set_mb_recording_id(tags["mb-recording-id"])
+            changed_tags.append("mb-recording-id")
+
+        if (tags["mb-track-id"]
+                and tags["mb-track-id"] != self.props.media.get_mb_track_id()):
+            self.props.media.set_mb_track_id(tags["mb-track-id"])
+            changed_tags.append("mb-track-id")
+
+        if tags["artist"] != self.props.media.get_artist():
+            self.props.media.set_artist(tags["artist"])
+            changed_tags.append("artist")
+
+        if (tags["mb-artist-id"]
+            and (tags["mb-artist-id"] != self.props.media.get_mb_artist_id()
+                 or "artist" in changed_tags)):
+            if tags["mb-artist-id"] != self.props.media.get_mb_artist_id():
+                self.props.media.set_mb_artist_id(tags["mb-artist-id"])
+            changed_tags.append("mb-artist-id")
+
+        if tags["album"] != self.props.media.get_album():
+            self.props.media.set_album(tags["album"])
+            changed_tags.append("album")
+
+        if int(tags["disc"]) != self.props.media.get_album_disc_number():
+            self.props.media.set_album_disc_number(int(tags["disc"]))
+            if "album" not in changed_tags:
+                changed_tags.append("album")
+
+        if (tags["album-artist"]
+            and (tags["album-artist"] != self.props.media.get_album_artist()
+                 or "album" in changed_tags)):
+            if tags["album-artist"] != self.props.media.get_album_artist():
+                self.props.media.set_album_artist(tags["album-artist"])
+            changed_tags.append("album-artist")
+
+        if (tags["mb-release-id"]
+            and (tags["mb-release-id"] != self.props.media.get_mb_release_id()
+                 or "album" in changed_tags)):
+            if tags["mb-release-id"] != self.props.media.get_mb_release_id():
+                self.props.media.set_mb_release_id(tags["mb-release-id"])
+            changed_tags.append("mb-release-id")
+
+        release_group_id = tags["mb-release-group-id"]
+        if (release_group_id
+            and (release_group_id != self.props.media.get_mb_release_group_id()
+                 or "album" in changed_tags)):
+            if release_group_id != self.props.media.get_mb_release_group_id():
+                self.props.media.set_mb_release_group_id(release_group_id)
+            changed_tags.append("mb-release-group-id")
+
+        if changed_tags:
+            self._log.debug(
+                "Updating tags from tracker: {}".format(changed_tags))
+            self._grilo.writeback_tracker(self.props.media, changed_tags)
+
+    def update_tags(self, tags):
+        """Update tags of a song.
+
+        The properties of a song can be updated with Grilo writeback
+        support. The other ones need to be updated with Tracker
+        requests.
+
+        :param dict tags: New tag values
+        """
+        def _writeback_cb():
+            self._update_from_tracker(tags)
+
+        writeback_keys = []
+        if tags["title"] != self.props.title:
+            self.props.media.set_title(tags["title"])
+            writeback_keys.append(Grl.METADATA_KEY_TITLE)
+
+        if int(tags["track"]) != self.props.track_number:
+            self.props.media.set_track_number(int(tags["track"]))
+            writeback_keys.append(Grl.METADATA_KEY_TRACK_NUMBER)
+
+        if tags["year"] != utils.get_media_year(self.props.media):
+            date = GLib.DateTime.new_utc(int(tags["year"]), 1, 1, 0, 0, 0)
+            self.props.media.set_creation_date(date)
+            writeback_keys.append(Grl.METADATA_KEY_CREATION_DATE)
+
+        if writeback_keys:
+            self._log.debug("Updating tags of a song: {}", writeback_keys)
+            self._grilo.writeback(
+                self.props.media, writeback_keys, _writeback_cb)
+        else:
+            self._update_from_tracker(tags)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]