1 # Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
3 # This file is part of Hooke.
5 # Hooke is free software: you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation, either
8 # version 3 of the License, or (at your option) any later version.
10 # Hooke is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with Hooke. If not, see
17 # <http://www.gnu.org/licenses/>.
19 """The ``playlist`` module provides :class:`PlaylistPlugin` and
20 several associated :class:`hooke.command.Command`\s for handling
21 :mod:`hooke.playlist` classes.
26 from ..command import Command, Argument, Failure
27 from ..playlist import FilePlaylist
28 from ..plugin import Builtin
31 class PlaylistPlugin (Builtin):
33 super(PlaylistPlugin, self).__init__(name='playlist')
35 NextCommand(self), PreviousCommand(self), JumpCommand(self),
36 IndexCommand(self), CurveListCommand(self),
37 SaveCommand(self), LoadCommand(self),
38 AddCommand(self), AddGlobCommand(self),
39 RemoveCommand(self), FilterCommand(self), NoteFilterCommand(self)]
42 # Define common or complicated arguments
44 def current_playlist_callback(hooke, command, argument, value):
47 playlist = hooke.playlists.current()
49 raise Failure('No playlists loaded')
52 PlaylistArgument = Argument(
53 name='playlist', type='playlist', callback=current_playlist_callback,
55 :class:`hooke.playlist.Playlist` to act on. Defaults to the current
59 def playlist_name_callback(hooke, command, argument, value):
60 return hooke.playlists.free_name()
62 PlaylistNameArgument = Argument(
63 name='name', type='string', optional=True, callback=playlist_name_callback,
65 Name of the new playlist (defaults to an auto-generated name).
68 def all_drivers_callback(hooke, command, argument, value):
74 class NextCommand (Command):
75 """Move playlist to the next curve.
77 def __init__(self, plugin):
78 super(NextCommand, self).__init__(
80 arguments=[PlaylistArgument],
81 help=self.__doc__, plugin=plugin)
83 def _run(self, hooke, inqueue, outqueue, params):
84 params['playlist'].next()
86 class PreviousCommand (Command):
87 """Move playlist to the previous curve.
89 def __init__(self, plugin):
90 super(PreviousCommand, self).__init__(
91 name='previous curve',
92 arguments=[PlaylistArgument],
93 help=self.__doc__, plugin=plugin)
95 def _run(self, hooke, inqueue, outqueue, params):
96 params['playlist'].previous()
98 class JumpCommand (Command):
99 """Move playlist to a given curve.
101 def __init__(self, plugin):
102 super(JumpCommand, self).__init__(
103 name='jump to curve',
106 Argument(name='index', type='int', optional=False, help="""
107 Index of target curve.
110 help=self.__doc__, plugin=plugin)
112 def _run(self, hooke, inqueue, outqueue, params):
113 params['playlist'].jump(params['index'])
115 class IndexCommand (Command):
116 """Print the index of the current curve.
118 The first curve has index 0.
120 def __init__(self, plugin):
121 super(IndexCommand, self).__init__(
126 help=self.__doc__, plugin=plugin)
128 def _run(self, hooke, inqueue, outqueue, params):
129 outqueue.put(params['playlist']._index)
131 class CurveListCommand (Command):
132 """Get the curves in a playlist.
134 def __init__(self, plugin):
135 super(CurveListCommand, self).__init__(
136 name='playlist curves',
140 help=self.__doc__, plugin=plugin)
142 def _run(self, hooke, inqueue, outqueue, params):
143 outqueue.put([c for c in params['playlist']])
145 class SaveCommand (Command):
148 def __init__(self, plugin):
149 super(SaveCommand, self).__init__(
150 name='save playlist',
153 Argument(name='output', type='file',
155 File name for the output playlist. Defaults to overwriting the input
159 help=self.__doc__, plugin=plugin)
161 def _run(self, hooke, inqueue, outqueue, params):
162 params['playlist'].save(params['output'])
164 class LoadCommand (Command):
167 def __init__(self, plugin):
168 super(LoadCommand, self).__init__(
169 name='load playlist',
171 Argument(name='input', type='file', optional=False,
173 File name for the input playlist.
175 Argument(name='drivers', type='driver', optional=True,
176 count=-1, callback=all_drivers_callback,
178 Drivers for loading curves.
181 help=self.__doc__, plugin=plugin)
183 def _run(self, hooke, inqueue, outqueue, params):
184 p = FilePlaylist(drivers=params['drivers'], path=params['input'])
186 hooke.playlists.append(p)
189 class AddCommand (Command):
190 """Add a curve to a playlist.
192 def __init__(self, plugin):
193 super(AddCommand, self).__init__(
194 name='add curve to playlist',
197 Argument(name='input', type='file', optional=False,
199 File name for the input :class:`hooke.curve.Curve`.
201 Argument(name='info', type='dict', optional=True,
203 Additional information for the input :class:`hooke.curve.Curve`.
206 help=self.__doc__, plugin=plugin)
208 def _run(self, hooke, inqueue, outqueue, params):
209 params['playlist'].append_curve_by_path(params['input'],
212 class AddGlobCommand (Command):
213 """Add curves to a playlist with file globbing.
215 Adding lots of files one at a time can be tedious. With this
216 command you can use globs (`data/curves/*.dat`) to add curves
217 for all matching files at once.
219 def __init__(self, plugin):
220 super(AddGlobCommand, self).__init__(
221 name='glob curves to playlist',
224 Argument(name='input', type='glob', optional=False,
226 File name glob for the input :class:`hooke.curve.Curve`.
228 Argument(name='info', type='dict', optional=True,
230 Additional information for the input :class:`hooke.curve.Curve`.
233 help=self.__doc__, plugin=plugin)
235 def _run(self, hooke, inqueue, outqueue, params):
236 for path in sorted(glob.glob(params['input'])):
237 params['playlist'].append_curve_by_path(path, params['info'])
239 class RemoveCommand (Command):
240 """Remove a curve from a playlist.
242 def __init__(self, plugin):
243 super(RemoveCommand, self).__init__(
244 name='remove curve from playlist',
247 Argument(name='index', type='int', optional=False, help="""
248 Index of target curve.
251 help=self.__doc__, plugin=plugin)
253 def _run(self, hooke, inqueue, outqueue, params):
254 params['playlist'].pop(params['index'])
255 params['playlist'].jump(params._index)
257 class FilterCommand (Command):
258 """Create a subset playlist via a selection function.
260 Removing lots of curves one at a time can be tedious. With this
261 command you can use a function `filter` to select the curves you
264 def __init__(self, plugin, name='filter playlist', filter_fn=None):
265 super(FilterCommand, self).__init__(
269 PlaylistNameArgument,
271 help=self.__doc__, plugin=plugin)
272 self.filter_fn = filter_fn
273 if filter_fn == None:
274 self.arguments.append(
275 Argument(name='filter', type='function', optional=False,
277 Function returning `True` for "good" curves. `filter(curve) -> True/False`.
280 def _run(self, hooke, inqueue, outqueue, params):
281 if self.filter_fn == None:
282 filter_fn = params['filter']
284 filter_fn = self.filter_fn
285 p = params['playlist'].filter(filter_fn)
286 hooke.playlists.add(p)
289 class NoteFilterCommand (FilterCommand):
290 """Create a subset playlist of curves with `.info['note'] != None`.
292 def __init__(self, plugin):
293 super(NoteFilterCommand, self).__init__(
294 plugin, name='note filter playlist',
295 filter_fn=lambda curve : \
296 'note' in curve.info and curve.info['note'] != None)