Pass Hooke instance to CommandEngine.run(), not UserInterface.run().
[hooke.git] / hooke / plugin / playlist.py
1 """Defines :class:`PlaylistPlugin` several associated
2 :class:`hooke.plugin.Command`\s for handling :mod:`hooke.playlist`
3 classes.
4 """
5
6 import glob
7
8 from ..command import Command, Argument
9 from ..playlist import FilePlaylist
10 from ..plugin import Builtin
11
12
13 class PlaylistPlugin (Builtin):
14     def __init__(self):
15         super(PlaylistPlugin, self).__init__(name='playlist')
16
17     def commands(self):
18         return [NextCommand(), PreviousCommand(), JumpCommand(),
19                 SaveCommand(), LoadCommand(),
20                 AddCommand(), AddGlobCommand(),
21                 RemoveCommand(), FilterCommand()]
22
23 # Define common or complicated arguments
24
25 def current_playlist_callback(hooke, command, argument, value):
26     return hooke.playlists.current()
27
28 PlaylistArgument = Argument(
29     name='playlist', type='playlist', callback=current_playlist_callback,
30     help="""
31 :class:`hooke.plugin.playlist.Playlist` to act on.  Defaults to the
32 current playlist.
33 """.strip()),
34
35 def playlist_name_callback(hooke, command, argument, value):
36         return hooke.playlists.free_name()
37
38 PlaylistNameArgument = Argument(
39     name='name', type='string', optional=True, callback=playlist_name_callback,
40     help="""
41 Name of the new playlist (defaults to an auto-generated name).
42 """.strip())
43
44
45 # Define commands
46
47 class NextCommand (Command):
48     """Move playlist to the next curve.
49     """
50     def __init__(self):
51         super(NextCommand, self).__init__(
52             name='next curve',
53             arguments=[PlaylistArgument],
54             help=self.__doc__)
55
56     def _run(self, hooke, inqueue, outqueue, params):
57         params['playlist'].next()
58
59 class PreviousCommand (Command):
60     """Move playlist to the previous curve.
61     """
62     def __init__(self):
63         super(PreviousCommand, self).__init__(
64             name='previous curve',
65             arguments=[PlaylistArgument],
66             help=self.__doc__)
67
68     def _run(self, hooke, inqueue, outqueue, params):
69         params['playlist'].previous()
70
71 class JumpCommand (Command):
72     """Move playlist to a given curve.
73     """
74     def __init__(self):
75         super(JumpCommand, self).__init__(
76             name='jump to curve',
77             arguments=[
78                 PlaylistArgument,
79                 Argument(name='index', type='int', optional=False, help="""
80 Index of target curve.
81 """.strip()),
82                 ],
83             help=self.__doc__)
84
85     def _run(self, hooke, inqueue, outqueue, params):
86         params['playlist'].jump(params['index'])
87
88 class SaveCommand (Command):
89     """Save a playlist.
90     """
91     def __init__(self):
92         super(SaveCommand, self).__init__(
93             name='save playlist',
94             arguments=[
95                 PlaylistArgument,
96                 Argument(name='output', type='file',
97                          help="""
98 File name for the output playlist.  Defaults to overwriting the input
99 playlist.
100 """.strip()),
101                 ],
102             help=self.__doc__)
103
104     def _run(self, hooke, inqueue, outqueue, params):
105         params['playlist'].save(params['output'])
106
107 class LoadCommand (Command):
108     """Load a playlist.
109     """
110     def __init__(self):
111         super(LoadCommand, self).__init__(
112             name='load playlist',
113             arguments=[
114                 Argument(name='input', type='file', optional=False,
115                          help="""
116 File name for the input playlist.
117 """.strip()),
118                 Argument(name='drivers', type='driver', optional=False,
119                          count=-1,
120                          help="""
121 Drivers for loading curves.
122 """.strip()),
123                 ],
124             help=self.__doc__)
125
126     def _run(self, hooke, inqueue, outqueue, params):
127         p = FilePlaylist(drivers=params['drivers'], path=params['input'])
128         p.load()
129         hooke.playlists.append(p)
130         outqueue.put(p)
131
132 class AddCommand (Command):
133     """Add a curve to a playlist.
134     """
135     def __init__(self):
136         super(AddCommand, self).__init__(
137             name='add curve to playlist',
138             arguments=[
139                 PlaylistArgument,
140                 Argument(name='input', type='file', optional=False,
141                          help="""
142 File name for the input :class:`hooke.curve.Curve`.
143 """.strip()),
144                 Argument(name='info', type='dict', optional=True,
145                          help="""
146 Additional information for the input :class:`hooke.curve.Curve`.
147 """.strip()),
148                 ],
149             help=self.__doc__)
150
151     def _run(self, hooke, inqueue, outqueue, params):
152         params['playlist'].append_curve_by_path(params['input'],
153                                                 params['info'])
154
155 class AddGlobCommand (Command):
156     """Add curves to a playlist with file globbing.
157
158     Adding lots of files one at a time can be tedious.  With this
159     command you can use globs (`data/curves/*.dat`) to add curves
160     for all matching files at once.
161     """
162     def __init__(self):
163         super(AddGlobCommand, self).__init__(
164             name='glob curves to playlist',
165             arguments=[
166                 PlaylistArgument,
167                 Argument(name='input', type='glob', optional=False,
168                          help="""
169 File name glob for the input :class:`hooke.curve.Curve`.
170 """.strip()),
171                 Argument(name='info', type='dict', optional=True,
172                          help="""
173 Additional information for the input :class:`hooke.curve.Curve`.
174 """.strip()),
175                 ],
176             help=self.__doc__)
177
178     def _run(self, hooke, inqueue, outqueue, params):
179         for path in sorted(glob.glob(params['input'])):
180             params['playlist'].append_curve_by_path(path, params['info'])
181
182 class RemoveCommand (Command):
183     """Remove a curve from a playlist.
184     """
185     def __init__(self):
186         super(RemoveCommand, self).__init__(
187             name='remove curve from playlist',
188             arguments=[
189                 PlaylistArgument,
190                 Argument(name='index', type='int', optional=False, help="""
191 Index of target curve.
192 """.strip()),
193                 ],
194             help=self.__doc__)
195
196     def _run(self, hooke, inqueue, outqueue, params):
197         params['playlist'].pop(params['index'])
198         params['playlist'].jump(params._index)
199
200 class FilterCommand (Command):
201     """Create a subset playlist via a selection function.
202
203     Removing lots of curves one at a time can be tedious.  With this
204     command you can use a function `filter` to select the curves you
205     wish to keep.
206     """
207     def __init__(self):
208         super(FilterCommand, self).__init__(
209             name='filter playlist',
210             arguments=[
211                 PlaylistArgument,
212                 PlaylistNameArgument,
213                 Argument(name='filter', type='function', optional=False,
214                          help="""
215 Function returning `True` for "good" curves.  `filter(curve) -> True/False`.
216 """.strip()),
217                 ],
218             help=self.__doc__)
219
220     def _run(self, hooke, inqueue, outqueue, params):
221         p = params['playlist'].filter(params['filter'])
222         hooke.playlists.add(p)
223         outqueue.put(p)