Browse Source

implemented symuid.library.itunes.XmlLibrary & .XmlDict

Fabian Peter Hammerle 5 years ago
parent
commit
54d2f837a4
2 changed files with 48 additions and 8 deletions
  1. 4 8
      symuid-import-itunes
  2. 44 0
      symuid/library/itunes.py

+ 4 - 8
symuid-import-itunes

@@ -7,6 +7,7 @@ import mutagen
 import mutagen.id3
 import mutagen.mp4
 import os
+import symuid.library.itunes
 import urllib.parse
 import xml.etree.ElementTree
 
@@ -75,13 +76,8 @@ def set_play_count_tag(track_path, player, library_id, reg_dt, play_count):
 
 def symuid_import_itunes(xml_library_path, root_url, root_path):
     root_path = os.path.expanduser(root_path)
-    lib = xml.etree.ElementTree.parse(xml_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'):
+    lib = symuid.library.itunes.XmlLibrary(xml_library_path)
+    for track_node in lib._root_dict['Tracks'].iterfind('./dict'):
         try:
             track_url = get_itunes_dict_value(track_node, 'Location')
         except KeyError:
@@ -104,7 +100,7 @@ def symuid_import_itunes(xml_library_path, root_url, root_path):
             set_play_count_tag(
                 track_path=track_path,
                 player='itunes',
-                library_id=lib_id,
+                library_id=lib.id,
                 reg_dt=last_play_dt,
                 play_count=play_count,
             )

+ 44 - 0
symuid/library/itunes.py

@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+import dateutil.parser
+import xml.etree.ElementTree
+
+
+class XmlDict:
+
+    def __init__(self, node):
+        assert isinstance(node, xml.etree.ElementTree.Element), node
+        assert node.tag == 'dict', node.tag
+        self._node = node
+
+    def _get_value_node(self, key):
+        # WORKAROUND method getnext() is sadly not available
+        for child_idx, child_node in enumerate(self._node):
+            if child_node.tag == 'key' and child_node.text == key:
+                return self._node[child_idx + 1]
+        raise KeyError(key)
+
+    def __getitem__(self, key):
+        value_node = self._get_value_node(key)
+        if value_node.tag == 'string':
+            return value_node.text
+        elif value_node.tag == 'integer':
+            return int(value_node.text)
+        elif value_node.tag == 'date':
+            return dateutil.parser.parse(value_node.text)
+        else:
+            return value_node
+
+
+class XmlLibrary:
+
+    def __init__(self, path):
+        self._tree = xml.etree.ElementTree.parse(path)
+        self._root_dict = XmlDict(self._tree.find('./dict'))
+        self._id = self._root_dict['Library Persistent ID']
+        assert isinstance(self._id, str), self._id
+        assert len(self._id) > 4
+
+    @property
+    def id(self):
+        return self._id