72cb47cab308b218214861a9b5a0e7a6eba9afae
[hooke.git] / contrib / upgrade_playlist_0p1.py
1 #!/usr/bin/python
2 # Copyright (C) 2010-2012 W. Trevor King <wking@drexel.edu>
3 #
4 # This file is part of Hooke.
5 #
6 # Hooke is free software: you can redistribute it and/or modify it
7 # under the terms of the GNU Lesser General Public License as
8 # published by the Free Software Foundation, either version 3 of the
9 # License, or (at your option) any later version.
10 #
11 # Hooke is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
14 # Public License for more details.
15 #
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with Hooke.  If not, see
18 # <http://www.gnu.org/licenses/>.
19
20 """Upgrade version 0.1 playlists (XML) to the current Hooke playlist
21 file format.
22 """
23
24 import sys
25 import xml.dom.minidom
26
27 import yaml
28
29 from hooke.playlist import FilePlaylist
30
31
32 class Converter (FilePlaylist):
33     def _restore_key(self, key):
34         """Restore keys encoded with :meth:`_clean_key`.
35         """
36         return key.replace(u'\u00B7', ' ')
37
38     def _from_xml_doc(self, doc, identify=True):
39         """Load a playlist from an :class:`xml.dom.minidom.Document`
40         instance.
41         """
42         root = doc.documentElement
43         for attribute,value in root.attributes.items():
44             attribute = self._restore_key(attribute)
45             if attribute == 'version':
46                 assert value == '0.1', \
47                     'Cannot read v%s playlist with a v%s reader' \
48                     % (value, self.version)
49             elif attribute == 'index':
50                 self._index = int(value)
51             else:
52                 self.info[attribute] = value
53         for curve_element in doc.getElementsByTagName('curve'):
54             path = curve_element.getAttribute('path')
55             info = dict([(self._restore_key(key), value)
56                          for key,value in curve_element.attributes.items()])
57             info.pop('path')
58             self.append_curve_by_path(path, info, identify=identify)
59         self.jump(self._index) # ensure valid index
60
61     def from_string(self, string, identify=True):
62         u"""Load a playlist from a string.
63
64         Examples
65         --------
66
67         >>> string = '''<?xml version="1.0" encoding="utf-8"?>
68         ... <playlist index="1" note="An example playlist" version="0.1">
69         ...     <curve note="The first curve" path="../curve/one"/>
70         ...     <curve attr\xb7with\xb7spaces="The second curve&#xA;with endlines" path="../curve/two"/>
71         ... </playlist>
72         ... '''
73         >>> p = FilePlaylist(drivers=[],
74         ...                  path=os.path.join('path', 'to', 'my', 'playlist'))
75         >>> p.from_string(string, identify=False)
76         >>> p._index
77         1
78         >>> p.info
79         {u'note': u'An example playlist'}
80         >>> for curve in p:
81         ...     print curve.path
82         path/to/curve/one
83         path/to/curve/two
84         >>> p[-1].info['attr with spaces']
85         u'The second curve\\nwith endlines'
86         """
87         doc = xml.dom.minidom.parseString(string)
88         self._from_xml_doc(doc, identify=identify)
89
90     def load(self, path=None, identify=True, hooke=None):
91         """Load a playlist from a file.
92         """
93         self.set_path(path)
94         doc = xml.dom.minidom.parse(self.path)
95         self._from_xml_doc(doc, identify=identify)
96         #self._digest = self.digest()
97         for curve in self:
98             curve.set_hooke(hooke)
99
100
101 if __name__ == '__main__':
102     if len(sys.argv) < 2:
103         print >> sys.stderr, 'usage: upgrade_playlist_0p1.py X.hkp [Y.hkp ...]'
104         sys.exit(1)
105
106     for path in sys.argv[1:]:
107         p = Converter(drivers=None, path=path)
108         p.load(identify=False)
109         p.save()