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')
36 return [NextCommand(), PreviousCommand(), JumpCommand(),
37 IndexCommand(), CurveListCommand(),
38 SaveCommand(), LoadCommand(),
39 AddCommand(), AddGlobCommand(),
40 RemoveCommand(), FilterCommand(), NoteFilterCommand()]
43 # Define common or complicated arguments
45 def current_playlist_callback(hooke, command, argument, value):
48 playlist = hooke.playlists.current()
50 raise Failure('No playlists loaded')
53 PlaylistArgument = Argument(
54 name='playlist', type='playlist', callback=current_playlist_callback,
56 :class:`hooke.playlist.Playlist` to act on. Defaults to the current
60 def playlist_name_callback(hooke, command, argument, value):
61 return hooke.playlists.free_name()
63 PlaylistNameArgument = Argument(
64 name='name', type='string', optional=True, callback=playlist_name_callback,
66 Name of the new playlist (defaults to an auto-generated name).
69 def all_drivers_callback(hooke, command, argument, value):
75 class NextCommand (Command):
76 """Move playlist to the next curve.
79 super(NextCommand, self).__init__(
81 arguments=[PlaylistArgument],
84 def _run(self, hooke, inqueue, outqueue, params):
85 params['playlist'].next()
87 class PreviousCommand (Command):
88 """Move playlist to the previous curve.
91 super(PreviousCommand, self).__init__(
92 name='previous curve',
93 arguments=[PlaylistArgument],
96 def _run(self, hooke, inqueue, outqueue, params):
97 params['playlist'].previous()
99 class JumpCommand (Command):
100 """Move playlist to a given curve.
103 super(JumpCommand, self).__init__(
104 name='jump to curve',
107 Argument(name='index', type='int', optional=False, help="""
108 Index of target curve.
113 def _run(self, hooke, inqueue, outqueue, params):
114 params['playlist'].jump(params['index'])
116 class IndexCommand (Command):
117 """Print the index of the current curve.
119 The first curve has index 0.
122 super(IndexCommand, self).__init__(
129 def _run(self, hooke, inqueue, outqueue, params):
130 outqueue.put(params['playlist']._index)
132 class CurveListCommand (Command):
133 """Get the curves in a playlist.
136 super(CurveListCommand, self).__init__(
137 name='playlist curves',
143 def _run(self, hooke, inqueue, outqueue, params):
144 outqueue.put([c for c in params['playlist']])
146 class SaveCommand (Command):
150 super(SaveCommand, self).__init__(
151 name='save playlist',
154 Argument(name='output', type='file',
156 File name for the output playlist. Defaults to overwriting the input
162 def _run(self, hooke, inqueue, outqueue, params):
163 params['playlist'].save(params['output'])
165 class LoadCommand (Command):
169 super(LoadCommand, self).__init__(
170 name='load playlist',
172 Argument(name='input', type='file', optional=False,
174 File name for the input playlist.
176 Argument(name='drivers', type='driver', optional=True,
177 count=-1, callback=all_drivers_callback,
179 Drivers for loading curves.
184 def _run(self, hooke, inqueue, outqueue, params):
185 p = FilePlaylist(drivers=params['drivers'], path=params['input'])
187 hooke.playlists.append(p)
190 class AddCommand (Command):
191 """Add a curve to a playlist.
194 super(AddCommand, self).__init__(
195 name='add curve to playlist',
198 Argument(name='input', type='file', optional=False,
200 File name for the input :class:`hooke.curve.Curve`.
202 Argument(name='info', type='dict', optional=True,
204 Additional information for the input :class:`hooke.curve.Curve`.
209 def _run(self, hooke, inqueue, outqueue, params):
210 params['playlist'].append_curve_by_path(params['input'],
213 class AddGlobCommand (Command):
214 """Add curves to a playlist with file globbing.
216 Adding lots of files one at a time can be tedious. With this
217 command you can use globs (`data/curves/*.dat`) to add curves
218 for all matching files at once.
221 super(AddGlobCommand, self).__init__(
222 name='glob curves to playlist',
225 Argument(name='input', type='glob', optional=False,
227 File name glob for the input :class:`hooke.curve.Curve`.
229 Argument(name='info', type='dict', optional=True,
231 Additional information for the input :class:`hooke.curve.Curve`.
236 def _run(self, hooke, inqueue, outqueue, params):
237 for path in sorted(glob.glob(params['input'])):
238 params['playlist'].append_curve_by_path(path, params['info'])
240 class RemoveCommand (Command):
241 """Remove a curve from a playlist.
244 super(RemoveCommand, self).__init__(
245 name='remove curve from playlist',
248 Argument(name='index', type='int', optional=False, help="""
249 Index of target curve.
254 def _run(self, hooke, inqueue, outqueue, params):
255 params['playlist'].pop(params['index'])
256 params['playlist'].jump(params._index)
258 class FilterCommand (Command):
259 """Create a subset playlist via a selection function.
261 Removing lots of curves one at a time can be tedious. With this
262 command you can use a function `filter` to select the curves you
266 super(FilterCommand, self).__init__(
267 name='filter playlist',
270 PlaylistNameArgument,
271 Argument(name='filter', type='function', optional=False,
273 Function returning `True` for "good" curves. `filter(curve) -> True/False`.
278 def _run(self, hooke, inqueue, outqueue, params):
279 p = params['playlist'].filter(params['filter'])
280 hooke.playlists.add(p)
283 class NoteFilterCommand (FilterCommand):
284 """Create a subset playlist of curves with `.info['note'] != None`.
287 super(NoteFilterCommand, self).__init__()
288 self.name = 'note filter playlist'
289 self.arguments = [a for a in self.arguments if a.name != 'filter']
291 def _run(self, hooke, inqueue, outqueue, params):
292 params['filter'] = lambda curve : \
293 'note' in curve.info and curve.info['note'] != None
294 return super(NoteFilterCommand, self)._run(
295 hooke, inqueue, outqueue, params)