[project @ 6101]
[poe-component-client-mpd.git] / lib / POE / Component / Client / MPD / Commands.pm
blob452694633cd1a84fd75613d1c69cc47e1e6a00a7
2 # This program is free software; you can redistribute it and/or modify
3 # it under the terms of the GNU General Public License as published by
4 # the Free Software Foundation; either version 2 of the License, or
5 # (at your option) any later version.
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
12 # You should have received a copy of the GNU General Public License
13 # along with this program; if not, write to the Free Software
14 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 package POE::Component::Client::MPD::Commands;
20 use strict;
21 use warnings;
23 use POE;
24 use POE::Component::Client::MPD::Message;
25 use POE::Component::Client::MPD::Stats;
26 use POE::Component::Client::MPD::Status;
27 use base qw[ Class::Accessor::Fast ];
29 # -- MPD interaction: general commands
32 # event: updatedb( [$path] )
34 # Force mpd to rescan its collection. If $path (relative to MPD's music
35 # directory) is supplied, MPD will only scan it - otherwise, MPD will rescan
36 # its whole collection.
38 sub _onpub_updatedb {
39 my $path = defined $_[ARG0] ? $_[ARG0] : '';
40 my $msg = POE::Component::Client::MPD::Message->new( {
41 _from => $_[SENDER]->ID,
42 _request => $_[STATE],
43 _answer => $DISCARD,
44 _commands => [ "update $path" ],
45 _cooking => $RAW,
46 } );
47 $_[KERNEL]->yield( '_send', $msg );
51 # -- MPD interaction: handling volume & output
54 # event: volume( $volume )
56 # Sets the audio output volume percentage to absolute $volume.
57 # If $volume is prefixed by '+' or '-' then the volume is changed relatively
58 # by that value.
60 sub _onpub_volume {
61 my $volume = $_[ARG0]; # FIXME: +/- prefix
62 my $msg = POE::Component::Client::MPD::Message->new( {
63 _from => $_[SENDER]->ID,
64 _request => $_[STATE],
65 _answer => $DISCARD,
66 _commands => [ "setvol $volume" ],
67 _cooking => $RAW,
68 } );
69 $_[KERNEL]->yield( '_send', $msg );
74 # event: output_enable( $output )
76 # Enable the specified audio output. $output is the ID of the audio output.
78 sub _onpub_output_enable {
79 my $output = $_[ARG0];
80 my $msg = POE::Component::Client::MPD::Message->new( {
81 _from => $_[SENDER]->ID,
82 _request => $_[STATE],
83 _answer => $DISCARD,
84 _commands => [ "enableoutput $output" ],
85 _cooking => $RAW,
86 } );
87 $_[KERNEL]->yield( '_send', $msg );
92 # event: output_disable( $output )
94 # Disable the specified audio output. $output is the ID of the audio output.
96 sub _onpub_output_disable {
97 my $output = $_[ARG0];
98 my $msg = POE::Component::Client::MPD::Message->new( {
99 _from => $_[SENDER]->ID,
100 _request => $_[STATE],
101 _answer => $DISCARD,
102 _commands => [ "disableoutput $output" ],
103 _cooking => $RAW,
104 } );
105 $_[KERNEL]->yield( '_send', $msg );
109 # -- MPD interaction: retrieving info from current state
112 # event: stats()
114 # Return a hash with the current statistics of MPD.
116 sub _onpub_stats {
117 my $msg = POE::Component::Client::MPD::Message->new( {
118 _from => $_[SENDER]->ID,
119 _request => $_[STATE],
120 _answer => $SEND,
121 _commands => [ 'stats' ],
122 _cooking => $AS_KV,
123 _post => '_stats_postback',
124 } );
125 $_[KERNEL]->yield( '_send', $msg );
130 # event: _stats_postback( $msg )
132 # Transform $msg->data from hash to a POCOCM::Stats object with the current
133 # statistics of MPD.
135 sub _onpriv_stats_postback {
136 my $msg = $_[ARG0];
137 my %stats = @{ $msg->data };
138 my $stats = POE::Component::Client::MPD::Stats->new( \%stats );
139 $msg->data($stats);
140 $_[KERNEL]->yield( '_mpd_data', $msg );
145 # event: status()
147 # Return a hash with the current status of MPD.
149 sub _onpub_status {
150 my $msg = POE::Component::Client::MPD::Message->new( {
151 _from => $_[SENDER]->ID,
152 _request => $_[STATE],
153 _answer => $SEND,
154 _commands => [ 'status' ],
155 _cooking => $AS_KV,
156 _post => '_status_postback',
157 } );
158 $_[KERNEL]->yield( '_send', $msg );
163 # event: _status_postback( $msg )
165 # Transform $msg->data from hash to a POCOCM::Status object with the current
166 # status of MPD.
168 sub _onpriv_status_postback {
169 my $msg = $_[ARG0];
170 my %stats = @{ $msg->data };
171 my $stats = POE::Component::Client::MPD::Status->new( \%stats );
172 $msg->data($stats);
173 $_[KERNEL]->yield( '_mpd_data', $msg );
178 # event: current()
180 # Return a POCOCM::Item::Song representing the song currently playing.
182 sub _onpub_current {
183 my $msg = POE::Component::Client::MPD::Message->new( {
184 _from => $_[SENDER]->ID,
185 _request => $_[STATE],
186 _answer => $SEND,
187 _commands => [ 'currentsong' ],
188 _cooking => $AS_ITEMS,
189 _post => '_post_array2scalar',
190 } );
191 $_[KERNEL]->yield( '_send', $msg );
195 # -- MPD interaction: altering settings
196 # -- MPD interaction: controlling playback
199 # event: play( [$song] )
201 # Begin playing playlist at song number $song. If no argument supplied,
202 # resume playing.
204 sub _onpub_play {
205 my $number = defined $_[ARG0] ? $_[ARG0] : '';
206 my $msg = POE::Component::Client::MPD::Message->new( {
207 _from => $_[SENDER]->ID,
208 _request => $_[STATE],
209 _answer => $DISCARD,
210 _commands => [ "play $number" ],
211 _cooking => $RAW,
212 } );
213 $_[KERNEL]->yield( '_send', $msg );
218 # event: playid( [$song] )
220 # Begin playing playlist at song ID $song. If no argument supplied,
221 # resume playing.
223 sub _onpub_playid {
224 my $number = defined $_[ARG0] ? $_[ARG0] : '';
225 my $msg = POE::Component::Client::MPD::Message->new( {
226 _from => $_[SENDER]->ID,
227 _request => $_[STATE],
228 _answer => $DISCARD,
229 _commands => [ "playid $number" ],
230 _cooking => $RAW,
231 } );
232 $_[KERNEL]->yield( '_send', $msg );
237 # event: pause( [$sate] )
239 # Pause playback. If $state is 0 then the current track is unpaused, if
240 # $state is 1 then the current track is paused.
242 # Note that if $state is not given, pause state will be toggled.
244 sub _onpub_pause {
245 my $state = defined $_[ARG0] ? $_[ARG0] : '';
246 my $msg = POE::Component::Client::MPD::Message->new( {
247 _from => $_[SENDER]->ID,
248 _request => $_[STATE],
249 _answer => $DISCARD,
250 _commands => [ "pause $state" ],
251 _cooking => $RAW,
252 } );
253 $_[KERNEL]->yield( '_send', $msg );
258 # event: stop()
260 # Stop playback
262 sub _onpub_stop {
263 my $msg = POE::Component::Client::MPD::Message->new( {
264 _from => $_[SENDER]->ID,
265 _request => $_[STATE],
266 _answer => $DISCARD,
267 _commands => [ 'stop' ],
268 _cooking => $RAW,
269 } );
270 $_[KERNEL]->yield( '_send', $msg );
275 # event: next()
277 # Play next song in playlist.
279 sub _onpub_next {
280 my $msg = POE::Component::Client::MPD::Message->new( {
281 _from => $_[SENDER]->ID,
282 _request => $_[STATE],
283 _answer => $DISCARD,
284 _commands => [ 'next' ],
285 _cooking => $RAW,
286 } );
287 $_[KERNEL]->yield( '_send', $msg );
292 # event: prev()
294 # Play previous song in playlist.
296 sub _onpub_prev {
297 my $msg = POE::Component::Client::MPD::Message->new( {
298 _from => $_[SENDER]->ID,
299 _request => $_[STATE],
300 _answer => $DISCARD,
301 _commands => [ 'previous' ],
302 _cooking => $RAW,
303 } );
304 $_[KERNEL]->yield( '_send', $msg );
309 # event: seek( $time, [$song] )
311 # Seek to $time seconds in song number $song. If $song number is not specified
312 # then the perl module will try and seek to $time in the current song.
314 sub _onpub_seek {
315 my ($time, $song) = @_[ARG0, ARG1];
316 $time ||= 0; $time = int $time;
317 my $msg = POE::Component::Client::MPD::Message->new( {
318 _from => $_[SENDER]->ID,
319 _request => $_[STATE],
320 _answer => $DISCARD,
321 _cooking => $RAW,
322 } );
324 if ( defined $song ) {
325 $msg->_commands( [ "seek $song $time" ] );
326 } else {
327 $msg->_pre_from( '_seek_need_current' );
328 $msg->_pre_event( 'status' );
329 $msg->_pre_data( $time );
331 $_[KERNEL]->yield( '_send', $msg );
336 # event: _seek_need_current( $msg, $current )
338 # Use $current to get current song, before sending real seek $msg.
340 sub _onpriv_seek_need_current {
341 my ($msg, $current) = @_[ARG0, ARG1];
342 my $song = $current->data->song;
343 my $time = $msg->_pre_data;
344 $msg->_commands( [ "seek $song $time" ] );
345 $_[KERNEL]->yield( '_send', $msg );
350 # event: seekid( $time, [$songid] )
352 # Seek to $time seconds in song ID $songid. If $songid number is not specified
353 # then the perl module will try and seek to $time in the current song.
355 sub _onpub_seekid {
356 my ($time, $song) = @_[ARG0, ARG1];
357 $time ||= 0; $time = int $time;
358 my $msg = POE::Component::Client::MPD::Message->new( {
359 _from => $_[SENDER]->ID,
360 _request => $_[STATE],
361 _answer => $DISCARD,
362 _cooking => $RAW,
363 } );
365 if ( defined $song ) {
366 $msg->_commands( [ "seekid $song $time" ] );
367 } else {
368 $msg->_pre_from( '_seekid_need_current' );
369 $msg->_pre_event( 'status' );
370 $msg->_pre_data( $time );
372 $_[KERNEL]->yield( '_send', $msg );
377 # event: _seekid_need_current( $msg, $current )
379 # Use $current to get current song, before sending real seekid $msg.
381 sub _onpriv_seekid_need_current {
382 my ($msg, $current) = @_[ARG0, ARG1];
383 my $song = $current->data->song;
384 my $time = $msg->_pre_data;
385 $msg->_commands( [ "seekid $song $time" ] );
386 $_[KERNEL]->yield( '_send', $msg );
392 __END__
394 =head1 NAME
396 POE::Component::Client::MPD::Commands - module handling basic commands
399 =head1 DESCRIPTION
401 C<POCOCM::Commands> is responsible for handling general purpose commands.
402 To achieve those commands, send the corresponding event to the POCOCM
403 session you created: it will be responsible for dispatching the event
404 where it is needed.
407 =head1 PUBLIC EVENTS
409 The following is a list of general purpose events accepted by POCOCM.
412 =head2 General commands
414 =head2 Handling volume & output
416 =head2 Retrieving info from current state
418 =head2 Altering settings
420 =head2 Controlling playback
423 =head1 SEE ALSO
425 For all related information (bug reporting, mailing-list, pointers to
426 MPD and POE, etc.), refer to C<POE::Component::Client::MPD>'s pod,
427 section C<SEE ALSO>
430 =head1 AUTHOR
432 Jerome Quelin, C<< <jquelin at cpan.org> >>
435 =head1 COPYRIGHT & LICENSE
437 Copyright 2007 Jerome Quelin, all rights reserved.
439 This program is free software; you can redistribute it and/or modify
440 it under the terms of the GNU General Public License as published by
441 the Free Software Foundation; either version 2 of the License, or
442 (at your option) any later version.
444 This program is distributed in the hope that it will be useful,
445 but WITHOUT ANY WARRANTY; without even the implied warranty of
446 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
447 GNU General Public License for more details.
449 You should have received a copy of the GNU General Public License
450 along with this program; if not, write to the Free Software
451 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
453 =cut