X-Git-Url: http://git.tremily.us/?p=hooke.git;a=blobdiff_plain;f=hooke%2Fplaylist.py;h=352617ce90120c7c2afd6698300d61293535096d;hp=ed05b35b85a1301368b0578295ee99fade21e20e;hb=643629fa189f2bc8d05a6d9903ccd22637bc563d;hpb=fff8f680ded76ec0535f6f49a5e5b226d9ebd505 diff --git a/hooke/playlist.py b/hooke/playlist.py index ed05b35..352617c 100644 --- a/hooke/playlist.py +++ b/hooke/playlist.py @@ -23,6 +23,7 @@ import copy import hashlib +import os import os.path import types import xml.dom.minidom @@ -45,15 +46,26 @@ class NoteIndexList (list): self._index = 0 def __str__(self): - return '<%s %s>' % (self.__class__.__name__, self.name) + return str(self.__unicode__()) + + def __unicode__(self): + return u'<%s %s>' % (self.__class__.__name__, self.name) + + def __repr__(self): + return self.__str__() def _setup_item(self, item): """Perform any required initialization before returning an item. """ pass - def index(self): - return self._index + def index(self, value=None, *args, **kwargs): + """Extend `list.index`, returning the current index if `value` + is `None`. + """ + if value == None: + return self._index + return super(NoteIndexList, self).index(value, *args, **kwargs) def current(self): if len(self) == 0: @@ -74,10 +86,34 @@ class NoteIndexList (list): def previous(self): self.jump(self._index - 1) + def items(self, reverse=False): + """Iterate through `self` calling `_setup_item` on each item + before yielding. + + Notes + ----- + Updates :attr:`_index` during the iteration so + :func:`~hooke.plugin.curve.current_curve_callback` works as + expected in :class:`~hooke.command.Command`\s called from + :class:`~hooke.plugin.playlist.ApplyCommandStack`. After the + iteration completes, :attr:`_index` is restored to its + original value. + """ + index = self._index + items = self + if reverse == True: + items = reversed(enumerate(self)) + else: + items = enumerate(self) + for i,item in items: + self._index = i + self._setup_item(item) + yield item + self._index = index + def filter(self, keeper_fn=lambda item:True, *args, **kwargs): c = copy.deepcopy(self) - for item in reversed(c): - c._setup_item(item) + for item in c.items(reverse=True): if keeper_fn(item, *args, **kwargs) != True: c.remove(item) try: # attempt to maintain the same current item @@ -86,6 +122,7 @@ class NoteIndexList (list): c._index = 0 return c + class Playlist (NoteIndexList): """A :class:`NoteIndexList` of :class:`hooke.curve.Curve`\s. @@ -97,11 +134,10 @@ class Playlist (NoteIndexList): self._loaded = [] # List of loaded curves, see :meth:`._setup_item`. self._max_loaded = 100 # curves to hold in memory simultaneously. - def append_curve_by_path(self, path, info=None, identify=True): - if self.path != None: - path = os.path.join(os.path.dirname(self.path), path) + def append_curve_by_path(self, path, info=None, identify=True, hooke=None): path = os.path.normpath(path) c = curve.Curve(path, info=info) + c.set_hooke(hooke) if identify == True: c.identify(self.drivers) self.append(c) @@ -120,11 +156,15 @@ class Playlist (NoteIndexList): oldest = self._loaded.pop(0) oldest.unload() + class FilePlaylist (Playlist): + """A file-backed :class:`Playlist`. + """ version = '0.1' def __init__(self, drivers, name=None, path=None): super(FilePlaylist, self).__init__(drivers, name) + self.path = None self.set_path(path) self._digest = None self._ignored_keys = [ @@ -139,6 +179,11 @@ class FilePlaylist (Playlist): if self.name == None: self.name = os.path.basename(path) + def append_curve_by_path(self, path, *args, **kwargs): + if self.path != None: + path = os.path.join(os.path.dirname(self.path), path) + super(FilePlaylist, self).append_curve_by_path(path, *args, **kwargs) + def is_saved(self): return self.digest() == self._digest @@ -198,7 +243,7 @@ class FilePlaylist (Playlist): Relative paths are interpreted relative to the location of the playlist file. - + Examples -------- @@ -311,18 +356,23 @@ class FilePlaylist (Playlist): doc = xml.dom.minidom.parseString(string) self._from_xml_doc(doc, identify=identify) - def load(self, path=None, identify=True): + def load(self, path=None, identify=True, hooke=None): """Load a playlist from a file. """ self.set_path(path) doc = xml.dom.minidom.parse(self.path) self._from_xml_doc(doc, identify=identify) self._digest = self.digest() + for curve in self: + curve.set_hooke(hooke) - def save(self, path=None): + def save(self, path=None, makedirs=True): """Saves the playlist in a XML file. """ self.set_path(path) - f = file(self.path, 'w') - f.write(self.flatten()) - f.close() + dirname = os.path.dirname(self.path) + if makedirs == True and not os.path.isdir(dirname): + os.makedirs(dirname) + with open(self.path, 'w') as f: + f.write(self.flatten()) + self._digest = self.digest()