Browse Source

print file urls in itunes xml library when new param --itunes-library-path is specified

Fabian Peter Hammerle 6 years ago
parent
commit
0d786a4b52
1 changed files with 44 additions and 2 deletions
  1. 44 2
      symuid

+ 44 - 2
symuid

@@ -6,6 +6,7 @@ import mutagen.id3
 import mutagen.mp4
 import os
 import subprocess
+import xml.etree.ElementTree
 
 # http://id3.org/id3v2.4.0-frames#4.1.
 TRACK_UUID_ID3_OWNER_ID = 'symuid'
@@ -13,6 +14,7 @@ TRACK_UUID_ID3_OWNER_ID = 'symuid'
 # http://mutagen.readthedocs.io/en/latest/api/mp4.html
 TRACK_UUID_MP4_TAG = '----:symuid:uuid'
 
+
 def generate_uuid():
     return subprocess.check_output(['uuid', '-v', '4', '-F', 'BIN']).strip()
 
@@ -41,12 +43,13 @@ def get_or_assign_uuid_id3(id3_tags):
         assert uuid is not None
     return uuid
 
+
 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,
+            dataformat=mutagen.mp4.AtomDataType.UUID,
         )
         mp4_file.save()
         mp4_file.load(filename=mp4_file.filename)
@@ -56,7 +59,45 @@ def get_or_assign_uuid_mp4(mp4_file):
     return mp4_file[TRACK_UUID_MP4_TAG][0]
 
 
-def symuid(path):
+def get_itunes_dict_value_node(dict_node, key):
+    assert isinstance(dict_node, xml.etree.ElementTree.Element)
+    assert isinstance(key, str)
+    # WORKAROUND method getnext() is sadly not available
+    for child_idx, child_node in enumerate(dict_node):
+        if child_node.tag == 'key' and child_node.text == key:
+            return dict_node[child_idx + 1]
+    raise KeyError()
+
+
+def get_itunes_dict_value(dict_node, key):
+    value_node = get_itunes_dict_value_node(dict_node, key)
+    if value_node.tag == 'string':
+        return value_node.text
+    elif value_node.tag == 'integer':
+        return int(value_node.text)
+    else:
+        return value_node
+
+
+def import_itunes_play_count(itunes_library_path):
+    lib = xml.etree.ElementTree.parse(itunes_library_path)
+    # WORKAROUND find('.//key[.="Library Persistent ID"]')
+    #  -> SyntaxError: invalid predicate
+    lib_root_dict = lib.find('./dict')
+    lib_id = get_itunes_dict_value(lib_root_dict, 'Library Persistent ID')
+    assert isinstance(lib_id, str) and len(lib_id) > 0, lib_id
+    for track_node in get_itunes_dict_value(lib_root_dict, 'Tracks').iterfind('./dict'):
+        try:
+            track_url = get_itunes_dict_value(track_node, 'Location')
+        except KeyError:
+            track_url = None
+        if track_url and track_url.startswith('file://'):
+            print(track_url)
+
+
+def symuid(path, itunes_library_path=None):
+    if itunes_library_path:
+        import_itunes_play_count(itunes_library_path)
     if os.path.isdir(path):
         for dirpath, dirnames, filenames in os.walk(path):
             for filename in filenames:
@@ -80,6 +121,7 @@ def _init_argparser():
     import argparse
     argparser = argparse.ArgumentParser(description=None)
     argparser.add_argument('path')
+    argparser.add_argument('--itunes-library-path')
     return argparser