Transition from v0.1 XML playlists to v0.2 YAML playlists.
[hooke.git] / contrib / upgrade_playlist_0p1.py
1 #!/usr/bin/python
2 # Copyright
3
4 """Upgrade version 0.1 playlists (XML) to the current Hooke playlist
5 file format.
6 """
7
8 import sys
9 import xml.dom.minidom
10
11 import yaml
12
13 from hooke.playlist import FilePlaylist
14
15
16 class Converter (FilePlaylist):
17     def _restore_key(self, key):
18         """Restore keys encoded with :meth:`_clean_key`.
19         """
20         return key.replace(u'\u00B7', ' ')
21
22     def _from_xml_doc(self, doc, identify=True):
23         """Load a playlist from an :class:`xml.dom.minidom.Document`
24         instance.
25         """
26         root = doc.documentElement
27         for attribute,value in root.attributes.items():
28             attribute = self._restore_key(attribute)
29             if attribute == 'version':
30                 assert value == '0.1', \
31                     'Cannot read v%s playlist with a v%s reader' \
32                     % (value, self.version)
33             elif attribute == 'index':
34                 self._index = int(value)
35             else:
36                 self.info[attribute] = value
37         for curve_element in doc.getElementsByTagName('curve'):
38             path = curve_element.getAttribute('path')
39             info = dict([(self._restore_key(key), value)
40                          for key,value in curve_element.attributes.items()])
41             info.pop('path')
42             self.append_curve_by_path(path, info, identify=identify)
43         self.jump(self._index) # ensure valid index
44
45     def from_string(self, string, identify=True):
46         u"""Load a playlist from a string.
47
48         Examples
49         --------
50
51         >>> string = '''<?xml version="1.0" encoding="utf-8"?>
52         ... <playlist index="1" note="An example playlist" version="0.1">
53         ...     <curve note="The first curve" path="../curve/one"/>
54         ...     <curve attr\xb7with\xb7spaces="The second curve&#xA;with endlines" path="../curve/two"/>
55         ... </playlist>
56         ... '''
57         >>> p = FilePlaylist(drivers=[],
58         ...                  path=os.path.join('path', 'to', 'my', 'playlist'))
59         >>> p.from_string(string, identify=False)
60         >>> p._index
61         1
62         >>> p.info
63         {u'note': u'An example playlist'}
64         >>> for curve in p:
65         ...     print curve.path
66         path/to/curve/one
67         path/to/curve/two
68         >>> p[-1].info['attr with spaces']
69         u'The second curve\\nwith endlines'
70         """
71         doc = xml.dom.minidom.parseString(string)
72         self._from_xml_doc(doc, identify=identify)
73
74     def load(self, path=None, identify=True, hooke=None):
75         """Load a playlist from a file.
76         """
77         self.set_path(path)
78         doc = xml.dom.minidom.parse(self.path)
79         self._from_xml_doc(doc, identify=identify)
80         #self._digest = self.digest()
81         for curve in self:
82             curve.set_hooke(hooke)
83
84
85 if __name__ == '__main__':
86     if len(sys.argv) < 2:
87         print >> sys.stderr, 'usage: upgrade_playlist_0p1.py X.hkp [Y.hkp ...]'
88         sys.exit(1)
89
90     for path in sys.argv[1:]:
91         p = Converter(drivers=None, path=path)
92         p.load(identify=False)
93         p.save()