From 13d7ede05e4a0c1f80d028e35a94de6b8d9300ad Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 2 Aug 2010 13:48:39 -0400 Subject: [PATCH] Adjust hooke.playlist to allow spaces in .info keys. --- hooke/playlist.py | 49 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/hooke/playlist.py b/hooke/playlist.py index b58e9b6..bba2990 100644 --- a/hooke/playlist.py +++ b/hooke/playlist.py @@ -161,6 +161,26 @@ class FilePlaylist (Playlist): string = self.flatten() return hashlib.sha1(string).digest() + def _clean_key(self, key): + """Replace spaces in keys with \\u00B7 (middle dot). + + This character is deemed unlikely to occur in keys to our + playlist and curve info dictionaries, while many keys have + spaces in them. + + \\u00B7 is allowed in XML 1.0 as of the 5th edition. See + the `4th edition errata`_ for details. + + .. _4th edition errata: + http://www.w3.org/XML/xml-V10-4e-errata#E09 + """ + return key.replace(' ', u'\u00B7') + + def _restore_key(self, key): + """Restore keys encoded with :meth:`_clean_key`. + """ + return key.replace(u'\u00B7', ' ') + def flatten(self, absolute_paths=False): """Create a string representation of the playlist. @@ -186,22 +206,23 @@ class FilePlaylist (Playlist): >>> c.info['note'] = 'The first curve' >>> p.append(c) >>> c = curve.Curve(os.path.join(root_path, 'to', 'curve', 'two')) - >>> c.info['note'] = 'The second curve\\nwith endlines' + >>> c.info['attr with spaces'] = 'The second curve\\nwith endlines' >>> p.append(c) - >>> print p.flatten() # doctest: +NORMALIZE_WHITESPACE +REPORT_UDIFF + >>> def _print(string): + ... escaped_string = unicode(string, 'utf-8').encode('unicode escape') + ... print escaped_string.replace('\\\\n', '\\n').replace('\\\\t', '\\t'), + >>> _print(p.flatten()) # doctest: +NORMALIZE_WHITESPACE +REPORT_UDIFF - + - - >>> print p.flatten(absolute_paths=True) # doctest: +NORMALIZE_WHITESPACE +REPORT_UDIFF + >>> _print(p.flatten(absolute_paths=True)) # doctest: +NORMALIZE_WHITESPACE +REPORT_UDIFF - + - """ implementation = xml.dom.minidom.getDOMImplementation() # create the document DOM object and the root element @@ -210,7 +231,7 @@ class FilePlaylist (Playlist): root.setAttribute('version', self.version) # store playlist version root.setAttribute('index', str(self._index)) for key,value in self.info.items(): # save info variables - root.setAttribute(key, str(value)) + root.setAttribute(self._clean_key(key), str(value)) for curve in self: # save curves and their attributes curve_element = doc.createElement('curve') root.appendChild(curve_element) @@ -225,7 +246,7 @@ class FilePlaylist (Playlist): for key,value in curve.info.items(): if key in self._ignored_keys: continue - curve_element.setAttribute(key,str(value)) + curve_element.setAttribute(self._clean_key(key), str(value)) string = doc.toprettyxml(encoding='utf-8') root.unlink() # break circular references for garbage collection return string @@ -236,6 +257,7 @@ class FilePlaylist (Playlist): """ root = doc.documentElement for attribute,value in root.attributes.items(): + attribute = self._restore_key(attribute) if attribute == 'version': assert value == self.version, \ 'Cannot read v%s playlist with a v%s reader' \ @@ -246,13 +268,14 @@ class FilePlaylist (Playlist): self.info[attribute] = value for curve_element in doc.getElementsByTagName('curve'): path = curve_element.getAttribute('path') - info = dict(curve_element.attributes.items()) + info = dict([(self._restore_key(key), value) + for key,value in curve_element.attributes.items()]) info.pop('path') self.append_curve_by_path(path, info, identify=identify) self.jump(self._index) # ensure valid index def from_string(self, string, identify=True): - """Load a playlist from a string. + u"""Load a playlist from a string. Examples -------- @@ -260,7 +283,7 @@ class FilePlaylist (Playlist): >>> string = ''' ... ... - ... + ... ... ... ''' >>> p = FilePlaylist(drivers=[], @@ -274,7 +297,7 @@ class FilePlaylist (Playlist): ... print curve.path path/to/curve/one path/to/curve/two - >>> p[-1].info['note'] + >>> p[-1].info['attr with spaces'] u'The second curve\\nwith endlines' """ doc = xml.dom.minidom.parseString(string) -- 2.26.2