[project @ 6089]
[poe-component-client-mpd.git] / lib / POE / Component / Client / MPD.pm
blob80f3a04e93df1c5e1b77bbec2f92dfed103ecbbc
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;
20 use strict;
21 use warnings;
23 use POE;
24 use POE::Component::Client::MPD::Collection;
25 use POE::Component::Client::MPD::Commands;
26 use POE::Component::Client::MPD::Connection;
27 use POE::Component::Client::MPD::Message;
28 use POE::Component::Client::MPD::Playlist;
29 use base qw[ Class::Accessor::Fast ];
30 __PACKAGE__->mk_accessors( qw[ _host _password _port _version ] );
33 our $VERSION = '0.3.1';
37 # my $id = spawn( \%params )
39 # This method will create a POE session responsible for communicating
40 # with mpd. It will return the poe id of the session newly created.
42 # You can tune the pococm by passing some arguments as a hash reference,
43 # where the hash keys are:
44 # - host: the hostname of the mpd server. If none given, defaults to
45 # MPD_HOST env var. If this var isn't set, defaults to localhost.
46 # - port: the port of the mpd server. If none given, defaults to
47 # MPD_PORT env var. If this var isn't set, defaults to 6600.
48 # - password: the password to sent to mpd to authenticate the client.
49 # If none given, defaults to C<MPD_PASSWORD> env var. If this var
50 # isn't set, defaults to empty string.
51 # - alias: an optional string to alias the newly created POE session.
53 sub spawn {
54 my ($type, $args) = @_;
56 my $collection = POE::Component::Client::MPD::Collection->new;
57 my $commands = POE::Component::Client::MPD::Commands->new;
58 my $playlist = POE::Component::Client::MPD::Playlist->new;
60 my $session = POE::Session->create(
61 args => [ $args ],
62 inline_states => {
63 # private events
64 '_start' => \&_onpriv_start,
65 '_send' => \&_onpriv_send,
66 '_post_array2scalar' => \&_onpriv_post_array2scalar,
67 # protected events
68 '_mpd_data' => \&_onprot_mpd_data,
69 '_mpd_error' => \&_onprot_mpd_error,
70 '_mpd_version' => \&_onprot_mpd_version,
71 # public events
72 'disconnect' => \&_onpub_disconnect,
74 object_states => [
75 $commands => { # general purpose commands
76 # -- MPD interaction: general commands
77 'updatedb' => '_onpub_updatedb',
78 # -- MPD interaction: handling volume & output
79 'volume' => '_onpub_volume',
80 'output_enable' => '_onpub_output_enable',
81 'output_disable' => '_onpub_output_disable',
82 # -- MPD interaction: retrieving info from current state
83 'stats' => '_onpub_stats',
84 '_stats_postback' => '_onpriv_stats_postback',
85 'status' => '_onpub_status',
86 '_status_postback' => '_onpriv_status_postback',
87 'current' => '_onpub_current',
88 # -- MPD interaction: altering settings
89 # -- MPD interaction: controlling playback
90 'play' => '_onpub_play',
91 'playid' => '_onpub_playid',
92 'pause' => '_onpub_pause',
93 'stop' => '_onpub_stop',
94 'next' => '_onpub_next',
95 'prev' => '_onpub_prev',
97 $collection => { # collection related commands
98 'coll.all_files' => '_onpub_all_files',
100 $playlist => { # playlist related commands
101 'pl.add' => '_onpub_add',
102 'pl.delete' => '_onpub_delete',
107 return $session->ID;
112 # public events
115 # event: disconnect()
117 # Request the pococm to be shutdown. No argument.
119 sub _onpub_disconnect {
120 my ($k,$h) = @_[KERNEL, HEAP];
121 $k->alias_remove( $h->{alias} ) if defined $h->{alias}; # refcount--
122 $k->post( $h->{_socket}, 'disconnect' ); # pococm-conn
127 # protected events.
130 # Event: _mpd_data( $msg )
132 # Received when mpd finished to send back some data.
134 sub _onprot_mpd_data {
135 my $msg = $_[ARG0];
136 return if $msg->_answer == $DISCARD;
138 # check for post-callback.
139 if ( defined $msg->_post ) {
140 $_[KERNEL]->yield( $msg->_post, $msg ); # need a post-treatment...
141 $msg->_post( undef ); # remove postback.
142 return;
145 # send result.
146 $_[KERNEL]->post( $msg->_from, 'mpd_result', $msg );
149 sub _onprot_mpd_error {
150 warn "mpd error\n";
155 # Event: _mpd_version( $vers )
157 # Event received during connection, when mpd server sends its version.
158 # Store it for later usage if needed.
160 sub _onprot_mpd_version {
161 $_[HEAP]->{version} = $_[ARG0];
166 # private events
169 # Event: _start( \%params )
171 # Called when the poe session gets initialized. Receive a reference
172 # to %params, same as spawn() received.
174 sub _onpriv_start {
175 my ($h, $args) = @_[HEAP, ARG0];
177 # set up connection details.
178 $args = {} unless defined $args;
179 my %params = (
180 host => $ENV{MPD_HOST} || 'localhost',
181 port => $ENV{MPD_PORT} || '6600',
182 password => $ENV{MPD_PASSWORD} || '',
183 %$args, # overwrite previous defaults
184 id => $_[SESSION]->ID, # required for connection
187 # set an alias (for easier communication) if requested.
188 $h->{alias} = delete $params{alias};
189 $_[KERNEL]->alias_set($h->{alias}) if defined $h->{alias};
191 $h->{password} = delete $params{password};
192 $h->{_socket} = POE::Component::Client::MPD::Connection->spawn(\%params);
196 =begin FIXME
199 # _connected()
201 # received when the poe::component::client::tcp is (re-)connected to the
202 # mpd server.
204 sub _connected {
205 my ($self, $k) = @_[OBJECT, KERNEL];
206 $k->post($_[HEAP]{_socket}, 'send', 'status' );
207 # send password information
210 =end FIXME
212 =cut
217 # event: _send( $msg )
219 # Event received to request message sending over tcp to mpd server.
220 # $msg is a pococm-message partially filled.
222 sub _onpriv_send {
223 $_[KERNEL]->post( $_[HEAP]->{_socket}, 'send', $_[ARG0] );
228 # event: _post_array2scalar( $msg )
230 # Transform $msg->data from array ref to a single scalar. Useful only
231 # as a postback callback, and if there's only one value in data().
233 sub _onpriv_post_array2scalar {
234 my $msg = $_[ARG0];
235 my $data = $msg->data->[0];
236 $msg->data($data);
237 $_[KERNEL]->yield( '_mpd_data', $msg );
243 __END__
246 =head1 NAME
248 POE::Component::Client::MPD - a full-blown mpd client library
251 =head1 SYNOPSIS
253 use POE qw[ Component::Client::MPD ];
254 POE::Component::Client::MPD->spawn( {
255 host => 'localhost',
256 port => 6600,
257 password => 's3kr3t', # mpd password
258 alias => 'mpd', # poe alias
259 } );
261 # ... later on ...
262 $_[KERNEL]->post( 'mpd', 'next' );
265 =head1 DESCRIPTION
267 POCOCM gives a clear message-passing interface (sitting on top of POE)
268 for talking to and controlling MPD (Music Player Daemon) servers. A
269 connection to the MPD server is established as soon as a new POCOCM
270 object is created.
272 Commands are then sent to the server as messages are passed.
275 =head1 PUBLIC PACKAGE METHODS
277 =head2 spawn( \%params )
279 This method will create a POE session responsible for communicating with mpd.
280 It will return the poe id of the session newly created.
282 You can tune the pococm by passing some arguments as a hash reference, where
283 the hash keys are:
285 =over 4
287 =item * host
289 The hostname of the mpd server. If none given, defaults to C<MPD_HOST>
290 environment variable. If this var isn't set, defaults to C<localhost>.
293 =item * port
295 The port of the mpd server. If none given, defaults to C<MPD_PORT>
296 environment variable. If this var isn't set, defaults to C<6600>.
299 =item * password
301 The password to sent to mpd to authenticate the client. If none given, defaults
302 to C<MPD_PASSWORD> environment variable. If this var isn't set, defaults to C<>.
305 =item * alias
307 An optional string to alias the newly created POE session.
310 =back
313 =head1 PUBLIC EVENTS
315 For a list of public events that you can send to a POCOCM session, check:
317 =over 4
319 =item *
321 C<POCOCM::Commands> for general commands
323 =item *
325 C<POCOCM::Playlist> for playlist-related commands
327 =item *
329 C<POCOCM::Collection> for collection-related commands
331 =back
334 =head1 BUGS
336 Please report any bugs or feature requests to C<bug-poe-component-client-mpd at
337 rt.cpan.org>, or through the web interface at
338 L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=POE-Component-Client-MPD>.
339 I will be notified, and then you'll automatically be notified of progress on
340 your bug as I make changes.
343 =head1 SEE ALSO
345 You can find more information on the mpd project on its homepage at
346 L<http://www.musicpd.org>, or its wiki L<http://mpd.wikia.com>.
348 C<POE::Component::Client::MPD development> takes place on C<< <audio-mpd
349 at googlegroups.com> >>: feel free to join us. (use
350 L<http://groups.google.com/group/audio-mpd> to sign in). Our subversion
351 repository is located at L<https://svn.musicpd.org>.
354 You can also look for information on this module at:
356 =over 4
358 =item * AnnoCPAN: Annotated CPAN documentation
360 L<http://annocpan.org/dist/POE-Component-Client-MPD>
362 =item * CPAN Ratings
364 L<http://cpanratings.perl.org/d/POE-Component-Client-MPD>
366 =item * RT: CPAN's request tracker
368 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=POE-Component-Client-MPD>
370 =back
373 =head1 AUTHOR
375 Jerome Quelin, C<< <jquelin at cpan.org> >>
378 =head1 COPYRIGHT & LICENSE
380 Copyright 2007 Jerome Quelin, all rights reserved.
382 This program is free software; you can redistribute it and/or modify
383 it under the terms of the GNU General Public License as published by
384 the Free Software Foundation; either version 2 of the License, or
385 (at your option) any later version.
387 This program is distributed in the hope that it will be useful,
388 but WITHOUT ANY WARRANTY; without even the implied warranty of
389 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
390 GNU General Public License for more details.
392 You should have received a copy of the GNU General Public License
393 along with this program; if not, write to the Free Software
394 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
396 =cut