Browse Source

added symuid.tag_interface.MP4.get_uuid()

Fabian Peter Hammerle 6 years ago
parent
commit
87eb035ce6
2 changed files with 33 additions and 19 deletions
  1. 11 17
      symuid-sync
  2. 22 2
      symuid/tag_interface.py

+ 11 - 17
symuid-sync

@@ -21,19 +21,12 @@ def generate_uuid():
     return subprocess.check_output(['uuid', '-v', '4', '-F', 'BIN']).strip()
 
 
-def get_or_assign_uuid_mp4(mp4_file):
-    if not TRACK_UUID_MP4_TAG in mp4_file:
-        mp4_file[TRACK_UUID_MP4_TAG] = mutagen.mp4.MP4FreeForm(
-            data=generate_uuid(),
-            # https://mutagen.readthedocs.io/en/latest/api/mp4.html#mutagen.mp4.AtomDataType.UUID
-            dataformat=mutagen.mp4.AtomDataType.UUID,
-        )
-        mp4_file.save()
-        mp4_file.load(filename=mp4_file.filename)
-        print("{!r}: assigned uuid {!r}".format(
-            mp4_file.filename, mp4_file[TRACK_UUID_MP4_TAG][0],
-        ))
-    return mp4_file[TRACK_UUID_MP4_TAG][0]
+def assign_uuid_mp4(mp4_file):
+    mp4_file[TRACK_UUID_MP4_TAG] = [mutagen.mp4.MP4FreeForm(
+        data=generate_uuid(),
+        # https://mutagen.readthedocs.io/en/latest/api/mp4.html#mutagen.mp4.AtomDataType.UUID
+        dataformat=mutagen.mp4.AtomDataType.UUID,
+    )]
 
 
 def log_path(track_path, msg, stream=sys.stdout):
@@ -51,10 +44,11 @@ def symuid_sync(path, path_ignore_regex, show_ignored=False):
             ignored_cb=lambda p: show_ignored and log_path(p, 'ignored'),
             unsupported_cb=lambda p, e: log_path_error(p, 'unsupported type, skipped'),
         ):
-        if isinstance(track._iface, symuid.tag_interface.MP4):
-            get_or_assign_uuid_mp4(track._iface._mutagen_file)
-        elif track._iface.get_uuid() is None:
-            track._iface.set_uuid(generate_uuid())
+        if track._iface.get_uuid() is None:
+            if isinstance(track._iface, symuid.tag_interface.MP4):
+                assign_uuid_mp4(track._iface._mutagen_file)
+            else:
+                track._iface.set_uuid(generate_uuid())
             track._iface.save()
             log_path(track.path, 'assigned uuid {!r}'.format(track._iface.get_uuid()))
 

+ 22 - 2
symuid/tag_interface.py

@@ -47,6 +47,7 @@ class ID3(_mutagen):
             desc=tag_label,
             text=[str(data)],
         )
+        # TODO overwrite instead of add() ?
         self._mutagen_file.tags.add(tag)
         return tag
 
@@ -65,6 +66,8 @@ class ID3(_mutagen):
 
 class MP4(_mutagen):
 
+    _UUID_TAG_KEY = 'symuid:uuid'
+
     def __init__(self, mutagen_file):
         assert mutagen_file.tags, mutagen_file
         assert isinstance(mutagen_file.tags, mutagen.mp4.MP4Tags), \
@@ -87,9 +90,20 @@ class MP4(_mutagen):
                 value = MP4._freeform_to_int(values[0])
                 yield (re.sub(r'^----:', '', label), value)
 
+    def _get_free(self, tag_label):
+        # freeform keys start with '----'
+        # http://mutagen.readthedocs.io/en/latest/api/mp4.html
+        tags = self._mutagen_file.tags['----:' + tag_label]
+        assert len(tags) == 1, tags
+        return tags[0]
+
     def get_free_int(self, tag_label):
-        tag, = self._mutagen_file.tags['----:' + tag_label]
-        return MP4._freeform_to_int(tag)
+        return MP4._freeform_to_int(self._get_free(tag_label))
+
+    def _get_free_uuid(self, tag_label):
+        tag = self._get_free(tag_label)
+        assert tag.dataformat == mutagen.mp4.AtomDataType.UUID, tag.dataformat
+        return tag
 
     def set_free_int(self, tag_label, data):
         assert isinstance(data, int)
@@ -101,3 +115,9 @@ class MP4(_mutagen):
         )
         self._mutagen_file.tags['----:' + tag_label] = tag
         return tag
+
+    def get_uuid(self):
+        try:
+            return self._get_free_uuid(self._UUID_TAG_KEY)
+        except KeyError:
+            return None