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
;
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
];
30 # -- MPD interaction: general commands
35 # Fires back an event with the version number.
38 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
39 _from
=> $_[SENDER
]->ID,
40 _request
=> $_[STATE
],
42 data
=> $_[HEAP
]->{version
}
44 $_[KERNEL
]->yield( '_mpd_data', $msg );
51 # Kill the mpd server, and request the pococm to be shutdown.
54 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
55 _from
=> $_[SENDER
]->ID,
56 _request
=> $_[STATE
],
58 _commands
=> [ 'kill' ],
60 _post
=> 'disconnect', # shut down pococm behind us.
62 $_[KERNEL
]->yield( '_send', $msg );
67 # event: updatedb( [$path] )
69 # Force mpd to rescan its collection. If $path (relative to MPD's music
70 # directory) is supplied, MPD will only scan it - otherwise, MPD will rescan
71 # its whole collection.
74 my $path = defined $_[ARG0
] ?
$_[ARG0
] : '';
75 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
76 _from
=> $_[SENDER
]->ID,
77 _request
=> $_[STATE
],
79 _commands
=> [ "update $path" ],
82 $_[KERNEL
]->yield( '_send', $msg );
87 # event: urlhandlers()
89 # Return an array of supported URL schemes.
91 sub _onpub_urlhandlers
{
92 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
93 _from
=> $_[SENDER
]->ID,
94 _request
=> $_[STATE
],
96 _commands
=> [ 'urlhandlers' ],
97 _cooking
=> $STRIP_FIRST,
99 $_[KERNEL
]->yield( '_send', $msg );
103 # -- MPD interaction: handling volume & output
106 # event: volume( $volume )
108 # Sets the audio output volume percentage to absolute $volume.
109 # If $volume is prefixed by '+' or '-' then the volume is changed relatively
113 # create stub message.
114 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
115 _from
=> $_[SENDER
]->ID,
116 _request
=> $_[STATE
],
121 my $volume = $_[ARG0
];
122 if ( $volume =~ /^(-|\+)(\d+)/ ) {
123 $msg->_pre_from( '_volume_status' );
124 $msg->_pre_event( 'status' );
125 $msg->_pre_data( $volume );
127 $msg->_commands( [ "setvol $volume" ] );
130 $_[KERNEL
]->yield( '_send', $msg );
135 # event: _volume_status( $msg, $status )
137 # Use $status to get current volume, before sending real volume $msg.
139 sub _onpriv_volume_status
{
140 my ($msg, $status) = @_[ARG0
, ARG1
];
141 my $curvol = $status->data->volume;
142 my $volume = $msg->_pre_data;
143 $volume =~ /^(-|\+)(\d+)/;
144 $volume = $1 eq '+' ?
$curvol + $2 : $curvol - $2;
145 $msg->_commands( [ "setvol $volume" ] );
146 $_[KERNEL
]->yield( '_send', $msg );
151 # event: output_enable( $output )
153 # Enable the specified audio output. $output is the ID of the audio output.
155 sub _onpub_output_enable
{
156 my $output = $_[ARG0
];
157 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
158 _from
=> $_[SENDER
]->ID,
159 _request
=> $_[STATE
],
161 _commands
=> [ "enableoutput $output" ],
164 $_[KERNEL
]->yield( '_send', $msg );
169 # event: output_disable( $output )
171 # Disable the specified audio output. $output is the ID of the audio output.
173 sub _onpub_output_disable
{
174 my $output = $_[ARG0
];
175 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
176 _from
=> $_[SENDER
]->ID,
177 _request
=> $_[STATE
],
179 _commands
=> [ "disableoutput $output" ],
182 $_[KERNEL
]->yield( '_send', $msg );
186 # -- MPD interaction: retrieving info from current state
191 # Return a hash with the current statistics of MPD.
194 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
195 _from
=> $_[SENDER
]->ID,
196 _request
=> $_[STATE
],
198 _commands
=> [ 'stats' ],
200 _transform
=> $AS_STATS,
202 $_[KERNEL
]->yield( '_send', $msg );
209 # Return a hash with the current status of MPD.
212 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
213 _from
=> $_[SENDER
]->ID,
214 _request
=> $_[STATE
],
216 _commands
=> [ 'status' ],
218 _transform
=> $AS_STATUS,
220 $_[KERNEL
]->yield( '_send', $msg );
227 # Return a POCOCM::Item::Song representing the song currently playing.
230 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
231 _from
=> $_[SENDER
]->ID,
232 _request
=> $_[STATE
],
234 _commands
=> [ 'currentsong' ],
235 _cooking
=> $AS_ITEMS,
236 _transform
=> $AS_SCALAR,
238 $_[KERNEL
]->yield( '_send', $msg );
243 # event: song( [$song] )
245 # Return a POCOCM::Item::Song representing the song number $song.
246 # If $song is not supplied, returns the current song.
249 my ($k,$song) = @_[KERNEL
, ARG0
];
251 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
252 _from
=> $_[SENDER
]->ID,
253 _request
=> $_[STATE
],
255 _commands
=> [ defined $song ?
"playlistinfo $song" : 'currentsong' ],
256 _cooking
=> $AS_ITEMS,
257 _transform
=> $AS_SCALAR,
259 $_[KERNEL
]->yield( '_send', $msg );
263 # -- MPD interaction: altering settings
264 # -- MPD interaction: controlling playback
267 # event: play( [$song] )
269 # Begin playing playlist at song number $song. If no argument supplied,
273 my $number = defined $_[ARG0
] ?
$_[ARG0
] : '';
274 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
275 _from
=> $_[SENDER
]->ID,
276 _request
=> $_[STATE
],
278 _commands
=> [ "play $number" ],
281 $_[KERNEL
]->yield( '_send', $msg );
286 # event: playid( [$song] )
288 # Begin playing playlist at song ID $song. If no argument supplied,
292 my $number = defined $_[ARG0
] ?
$_[ARG0
] : '';
293 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
294 _from
=> $_[SENDER
]->ID,
295 _request
=> $_[STATE
],
297 _commands
=> [ "playid $number" ],
300 $_[KERNEL
]->yield( '_send', $msg );
305 # event: pause( [$sate] )
307 # Pause playback. If $state is 0 then the current track is unpaused, if
308 # $state is 1 then the current track is paused.
310 # Note that if $state is not given, pause state will be toggled.
313 my $state = defined $_[ARG0
] ?
$_[ARG0
] : '';
314 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
315 _from
=> $_[SENDER
]->ID,
316 _request
=> $_[STATE
],
318 _commands
=> [ "pause $state" ],
321 $_[KERNEL
]->yield( '_send', $msg );
331 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
332 _from
=> $_[SENDER
]->ID,
333 _request
=> $_[STATE
],
335 _commands
=> [ 'stop' ],
338 $_[KERNEL
]->yield( '_send', $msg );
345 # Play next song in playlist.
348 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
349 _from
=> $_[SENDER
]->ID,
350 _request
=> $_[STATE
],
352 _commands
=> [ 'next' ],
355 $_[KERNEL
]->yield( '_send', $msg );
362 # Play previous song in playlist.
365 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
366 _from
=> $_[SENDER
]->ID,
367 _request
=> $_[STATE
],
369 _commands
=> [ 'previous' ],
372 $_[KERNEL
]->yield( '_send', $msg );
377 # event: seek( $time, [$song] )
379 # Seek to $time seconds in song number $song. If $song number is not specified
380 # then the perl module will try and seek to $time in the current song.
383 my ($time, $song) = @_[ARG0
, ARG1
];
384 $time ||= 0; $time = int $time;
385 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
386 _from
=> $_[SENDER
]->ID,
387 _request
=> $_[STATE
],
392 if ( defined $song ) {
393 $msg->_commands( [ "seek $song $time" ] );
395 $msg->_pre_from( '_seek_need_current' );
396 $msg->_pre_event( 'status' );
397 $msg->_pre_data( $time );
399 $_[KERNEL
]->yield( '_send', $msg );
404 # event: _seek_need_current( $msg, $current )
406 # Use $current to get current song, before sending real seek $msg.
408 sub _onpriv_seek_need_current
{
409 my ($msg, $current) = @_[ARG0
, ARG1
];
410 my $song = $current->data->song;
411 my $time = $msg->_pre_data;
412 $msg->_commands( [ "seek $song $time" ] );
413 $_[KERNEL
]->yield( '_send', $msg );
418 # event: seekid( $time, [$songid] )
420 # Seek to $time seconds in song ID $songid. If $songid number is not specified
421 # then the perl module will try and seek to $time in the current song.
424 my ($time, $song) = @_[ARG0
, ARG1
];
425 $time ||= 0; $time = int $time;
426 my $msg = POE
::Component
::Client
::MPD
::Message
->new( {
427 _from
=> $_[SENDER
]->ID,
428 _request
=> $_[STATE
],
433 if ( defined $song ) {
434 $msg->_commands( [ "seekid $song $time" ] );
436 $msg->_pre_from( '_seekid_need_current' );
437 $msg->_pre_event( 'status' );
438 $msg->_pre_data( $time );
440 $_[KERNEL
]->yield( '_send', $msg );
445 # event: _seekid_need_current( $msg, $current )
447 # Use $current to get current song, before sending real seekid $msg.
449 sub _onpriv_seekid_need_current
{
450 my ($msg, $current) = @_[ARG0
, ARG1
];
451 my $song = $current->data->song;
452 my $time = $msg->_pre_data;
453 $msg->_commands( [ "seekid $song $time" ] );
454 $_[KERNEL
]->yield( '_send', $msg );
464 POE::Component::Client::MPD::Commands - module handling basic commands
469 C<POCOCM::Commands> is responsible for handling general purpose commands.
470 To achieve those commands, send the corresponding event to the POCOCM
471 session you created: it will be responsible for dispatching the event
477 The following is a list of general purpose events accepted by POCOCM.
480 =head2 General commands
482 =head2 Handling volume & output
484 =head2 Retrieving info from current state
486 =head2 Altering settings
488 =head2 Controlling playback
493 For all related information (bug reporting, mailing-list, pointers to
494 MPD and POE, etc.), refer to C<POE::Component::Client::MPD>'s pod,
500 Jerome Quelin, C<< <jquelin at cpan.org> >>
503 =head1 COPYRIGHT & LICENSE
505 Copyright 2007 Jerome Quelin, all rights reserved.
507 This program is free software; you can redistribute it and/or modify
508 it under the terms of the GNU General Public License as published by
509 the Free Software Foundation; either version 2 of the License, or
510 (at your option) any later version.
512 This program is distributed in the hope that it will be useful,
513 but WITHOUT ANY WARRANTY; without even the implied warranty of
514 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
515 GNU General Public License for more details.
517 You should have received a copy of the GNU General Public License
518 along with this program; if not, write to the Free Software
519 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA