Moved Playlist and FilePlaylist definitions back to hooke.playlist
authorW. Trevor King <wking@drexel.edu>
Sun, 9 May 2010 14:32:27 +0000 (10:32 -0400)
committerW. Trevor King <wking@drexel.edu>
Sun, 9 May 2010 14:32:27 +0000 (10:32 -0400)
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
hooke/plugin/playlist.py

index 74271ccd39e36b8dd72016f1bcd9df8f9c0ba7d8..5e79d5737e7a73c3be47a1974d0289258b39f9da 100644 (file)
@@ -976,7 +976,7 @@ class Hooke (object):
 
 def main():
     app = Hooke(debug=__debug__)
-    app.MainLoop()
+    app.main()
 
 if __name__ == '__main__':
     main()
index 58832d3537e39891b28a9c8981e62fc6aada887d..4dc83e3177fde634abb449f2e41f9b907a6e86d5 100644 (file)
@@ -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::
-
-            <?xml version="1.0" encoding="utf-8"?>
-            <playlist attribute="value">
-              <curve path="/my/file/path/"/ attribute="value" ...>
-              <curve path="...">
-            </playlist>
-
-        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
-        <?xml version="1.0" encoding="utf-8"?>
-        <playlist index="0" note="An example playlist" version="0.1">
-            <curve note="The first curve" path="../curve/one"/>
-            <curve note="The second curve" path="../curve/two"/>
-        </playlist>
-        <BLANKLINE>
-        >>> print p.flatten(absolute_paths=True) # doctest: +NORMALIZE_WHITESPACE +REPORT_UDIFF
-        <?xml version="1.0" encoding="utf-8"?>
-        <playlist index="0" note="An example playlist" version="0.1">
-            <curve note="The first curve" path="/path/to/curve/one"/>
-            <curve note="The second curve" path="/path/to/curve/two"/>
-        </playlist>
-        <BLANKLINE>
-        """
-        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 = '''<?xml version="1.0" encoding="utf-8"?>
-        ... <playlist index="1" note="An example playlist" version="0.1">
-        ...     <curve note="The first curve" path="../curve/one"/>
-        ...     <curve note="The second curve" path="../curve/two"/>
-        ... </playlist>
-        ... '''
-        >>> 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.
     """