From 0ba85adf2f6fb71eb929358f66a141d53816fd1c Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Sun, 9 May 2010 10:32:27 -0400 Subject: [PATCH] Moved Playlist and FilePlaylist definitions back to hooke.playlist We shouldn't define core classes in plugins. This will make the plugin clearer, separating the core functionality from the silly plugin interface to that core functionality. Such Builtins are useful for the Hooke command line and GUIs, but not for people using Python to import hooke directly. --- hooke/hooke.py | 2 +- hooke/plugin/playlist.py | 231 +-------------------------------------- 2 files changed, 4 insertions(+), 229 deletions(-) diff --git a/hooke/hooke.py b/hooke/hooke.py index 74271cc..5e79d57 100644 --- a/hooke/hooke.py +++ b/hooke/hooke.py @@ -976,7 +976,7 @@ class Hooke (object): def main(): app = Hooke(debug=__debug__) - app.MainLoop() + app.main() if __name__ == '__main__': main() diff --git a/hooke/plugin/playlist.py b/hooke/plugin/playlist.py index 58832d3..4dc83e3 100644 --- a/hooke/plugin/playlist.py +++ b/hooke/plugin/playlist.py @@ -2,17 +2,11 @@ :class:`hooke.plugin.Command`\s. """ -import copy -import hashlib -import os -import os.path -import xml.dom.minidom +from ..playlist import FilePlaylist +from ..plugin import Builtin, Command, Argument -from .. import curve as curve -from ..plugin import Plugin, Command, Argument - -class PlaylistPlugin (Plugin): +class PlaylistPlugin (Builtin): def __init__(self): super(PlaylistPlugin, self).__init__(name='playlist') @@ -21,225 +15,6 @@ class PlaylistPlugin (Plugin): SaveCommand(), LoadCommand(), AddCommand(), RemoveCommand(), FilterCommand()] -class Playlist (list): - """A list of :class:`hooke.curve.Curve`\s. - - Keeps a list of :attr:`drivers` for loading curves, the - :attr:`index` (i.e. "bookmark") of the currently active curve, and - a :class:`dict` of additional informtion (:attr:`info`). - """ - def __init__(self, drivers, name=None): - super(Playlist, self).__init__() - self.drivers = drivers - self.name = name - self.info = {} - self._index = 0 - - def append_curve_by_path(self, path, info=None, identify=True): - if self.path != None: - path = os.path.join(self.path, path) - path = os.path.normpath(path) - c = curve.Curve(path, info=info) - if identify == True: - c.identify(self.drivers) - self.append(c) - return c - - def active_curve(self): - return self[self._index] - - def has_curves(self): - return len(self) > 0 - - def jump(self, index): - if len(self) == 0: - self._index = 0 - else: - self._index = index % len(self) - - def next(self): - self.jump(self._index + 1) - - def previous(self): - self.jump(self._index - 1) - - def filter(self, keeper_fn=lambda curve:True): - playlist = copy.deepcopy(self) - for curve in reversed(playlist.curves): - if keeper_fn(curve) != True: - playlist.curves.remove(curve) - try: # attempt to maintain the same active curve - playlist._index = playlist.index(self.active_curve()) - except ValueError: - playlist._index = 0 - return playlist - -class FilePlaylist (Playlist): - version = '0.1' - - def __init__(self, drivers, name=None, path=None): - if name == None and path != None: - name = os.path.basename(path) - super(FilePlaylist, self).__init__(drivers, name) - self.path = path - self._digest = None - - def is_saved(self): - return self.digest() == self._digest - - def digest(self): - r"""Compute the sha1 digest of the flattened playlist - representation. - - Examples - -------- - - >>> root_path = os.path.sep + 'path' - >>> p = FilePlaylist(drivers=[], - ... path=os.path.join(root_path, 'to','playlist')) - >>> p.info['note'] = 'An example playlist' - >>> c = curve.Curve(os.path.join(root_path, 'to', 'curve', 'one')) - >>> 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' - >>> p.append(c) - >>> p.digest() - "\xa1\x99\x8a\x99\xed\xad\x13'\xa7w\x12\x00\x07Z\xb3\xd0zN\xa2\xe1" - """ - string = self.flatten() - return hashlib.sha1(string).digest() - - def flatten(self, absolute_paths=False): - """Create a string representation of the playlist. - - A playlist is an XML document with the following syntax:: - - - - - - - - Relative paths are interpreted relative to the location of the - playlist file. - - Examples - -------- - - >>> root_path = os.path.sep + 'path' - >>> p = FilePlaylist(drivers=[], - ... path=os.path.join(root_path, 'to','playlist')) - >>> p.info['note'] = 'An example playlist' - >>> c = curve.Curve(os.path.join(root_path, 'to', 'curve', 'one')) - >>> 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' - >>> p.append(c) - >>> print p.flatten() # 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 - doc = implementation.createDocument(None, 'playlist', None) - root = doc.documentElement - 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)) - for curve in self: # save curves and their attributes - curve_element = doc.createElement('curve') - root.appendChild(curve_element) - path = os.path.abspath(os.path.expanduser(curve.path)) - if absolute_paths == False: - path = os.path.relpath( - path, - os.path.abspath(os.path.expanduser(self.path))) - curve_element.setAttribute('path', path) - for key,value in curve.info.items(): - curve_element.setAttribute(key, str(value)) - string = doc.toprettyxml(encoding='utf-8') - root.unlink() # break circular references for garbage collection - return string - - def _from_xml_doc(self, doc): - """Load a playlist from an :class:`xml.dom.minidom.Document` - instance. - """ - root = doc.documentElement - for attribute,value in root.attributes.items(): - if attribute == 'version': - assert value == self.version, \ - 'Cannot read v%s playlist with a v%s reader' \ - % (value, self.version) - elif attribute == 'index': - self._index = int(value) - else: - self.info[attribute] = value - for curve_element in doc.getElementsByTagName('curve'): - path = curve_element.getAttribute('path') - info = dict(curve_element.attributes.items()) - info.pop('path') - self.append_curve_by_path(path, info, identify=False) - self.jump(self._index) # ensure valid index - - def from_string(self, string): - """Load a playlist from a string. - - Examples - -------- - - >>> string = ''' - ... - ... - ... - ... - ... ''' - >>> p = FilePlaylist(drivers=[], - ... path=os.path.join('path', 'to','playlist')) - >>> p.from_string(string) - >>> p._index - 1 - >>> p.info - {u'note': u'An example playlist'} - >>> for curve in p: - ... print curve.path - path/to/curve/one - path/to/curve/two - """ - doc = xml.dom.minidom.parseString(string) - return self._from_xml_doc(doc) - - def load(self, path=None): - """Load a playlist from a file. - """ - if path != None: - self.path = path - if self.name == None: - self.name = os.path.basename(self.path) - doc = xml.dom.minidom.parse(path) - return self._from_xml_doc(doc) - - def save(self, path): - """Saves the playlist in a XML file. - """ - f = file(path, 'w') - f.write(self.flatten()) - f.close() - class NextCommand (Command): """Move playlist to the next curve. """ -- 2.26.2