import copy
import hashlib
+import os
import os.path
import types
import xml.dom.minidom
from . import curve as curve
from .compat import minidom as minidom # dynamically patch xml.sax.minidom
+from .util.itertools import reverse_enumerate
class NoteIndexList (list):
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.ApplyCommand`. After the
+ iteration completes, :attr:`_index` is restored to its
+ original value.
"""
+ index = self._index
items = self
if reverse == True:
- items = reversed(self)
- for item in items:
+ items = reverse_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)
self.drivers = drivers
self._loaded = [] # List of loaded curves, see :meth:`._setup_item`.
self._max_loaded = 100 # curves to hold in memory simultaneously.
- self._curve_load_args = ()
- self._curve_load_kwargs = {}
- def append_curve_by_path(self, path, info=None, identify=True):
+ 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)
return c
- def set_curve_load_args(self, *args, **kwargs):
- self._curve_load_args = args
- self._curve_load_kwargs = kwargs
-
def _setup_item(self, curve):
if curve != None and curve not in self._loaded:
if curve not in self:
if curve.driver == None:
c.identify(self.drivers)
if curve.data == None:
- curve.load(*self._curve_load_args, **self._curve_load_kwargs)
+ curve.load()
self._loaded.append(curve)
if len(self._loaded) > self._max_loaded:
oldest = self._loaded.pop(0)
class FilePlaylist (Playlist):
+ """A file-backed :class:`Playlist`.
+ """
version = '0.1'
def __init__(self, drivers, name=None, path=None):
Relative paths are interpreted relative to the location of the
playlist file.
-
+
Examples
--------
or not isinstance(value, types.StringTypes)):
continue
root.setAttribute(self._clean_key(key), str(value))
+ if self.path == None:
+ base_path = os.getcwd()
+ else:
+ base_path = os.path.abspath(
+ os.path.expanduser(self.path))
for curve in self: # save curves and their attributes
curve_element = doc.createElement('curve')
root.appendChild(curve_element)
if absolute_paths == False:
path = os.path.relpath(
path,
- os.path.dirname(
- os.path.abspath(
- os.path.expanduser(self.path))))
+ os.path.dirname(base_path))
curve_element.setAttribute('path', path)
for key,value in curve.info.items():
if (key in self._ignored_keys
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)
+ dirname = os.path.dirname(self.path) or '.'
+ 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()