[project @ 5634]
[audio-mpd.git] / lib / Audio / MPD / Collection.pm
blob86830a27aa643731006fa624040ecd7710aeb68a
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 Audio::MPD::Collection;
20 use strict;
21 use warnings;
22 use Audio::MPD::Item::Directory;
23 use Audio::MPD::Item::Song;
24 use Scalar::Util qw[ weaken ];
26 use base qw[ Class::Accessor::Fast ];
27 __PACKAGE__->mk_accessors( qw[ _mpd ] );
30 our ($VERSION) = '$Rev$' =~ /(\d+)/;
32 #--
33 # Constructor
36 # my $collection = Audio::MPD::Collection->new( $mpd );
38 # This will create the object, holding a back-reference to the Audio::MPD
39 # object itself (for communication purposes). But in order to play safe and
40 # to free the memory in time, this reference is weakened.
42 # Note that you're not supposed to call this constructor yourself, an
43 # Audio::MPD::Collection is automatically created for you during the creation
44 # of an Audio::MPD object.
46 sub new {
47 my ($pkg, $mpd) = @_;
49 my $self = { _mpd => $mpd };
50 weaken( $self->{_mpd} );
51 return $self;
55 #--
56 # Public methods
58 # -- Collection: retrieving songs & directories
61 # my @items = $collection->all_items( [$path] );
63 # Return *all* Audio::MPD::Items (both songs & directories) currently known
64 # by mpd.
66 # If $path is supplied (relative to mpd root), restrict the retrieval to
67 # songs and dirs in this directory.
69 sub all_items {
70 my ($self, $path) = @_;
71 $path ||= '';
73 my @lines = $self->_send_command( qq[listallinfo "$path"\n] );
74 my (@list, %param);
76 # parse lines in reverse order since "file:" comes first.
77 # therefore, let's first store every other parameter, and
78 # the "file:" line will trigger the object creation.
79 # of course, since we want to preserve the playlist order,
80 # this means that we're going to unshift the objects.
81 foreach my $line (reverse @lines) {
82 next unless $line =~ /^([^:]+):\s+(.+)$/;
83 $param{$1} = $2;
84 next unless $1 eq 'file' || $1 eq 'directory'; # last param of item
85 unshift @list, Audio::MPD::Item->new(%param);
86 %param = ();
88 return @list;
93 # my @items = $collection->all_items_simple( [$path] );
95 # Return *all* Audio::MPD::Items (both songs & directories) currently known
96 # by mpd.
98 # If $path is supplied (relative to mpd root), restrict the retrieval to
99 # songs and dirs in this directory.
101 # /!\ Warning: the Audio::MPD::Item::Song objects will only have their tag
102 # file filled. Any other tag will be empty, so don't use this sub for any
103 # other thing than a quick scan!
105 sub all_items_simple {
106 my ($self, $path) = @_;
107 $path ||= '';
109 my @lines = $self->_send_command( qq[listall "$path"\n] );
110 my (@list, %param);
112 # parse lines in reverse order since "file:" comes first.
113 # therefore, let's first store every other parameter, and
114 # the "file:" line will trigger the object creation.
115 # of course, since we want to preserve the playlist order,
116 # this means that we're going to unshift the objects.
117 foreach my $line (reverse @lines) {
118 next unless $line =~ /^([^:]+):\s+(.+)$/;
119 $param{$1} = $2;
120 next unless $1 eq 'file' || $1 eq 'directory'; # last param of item
121 unshift @list, Audio::MPD::Item->new(%param);
122 %param = ();
124 return @list;
129 # my @items = $collection->items_in_dir( [$path] );
131 # Return the items in the given $path. If no $path supplied, do it on mpd's
132 # root directory.
134 # Note that this sub does not work recusrively on all directories.
136 sub items_in_dir {
137 my ($self, $path) = @_;
138 $path ||= '';
140 my @lines = $self->_send_command( qq[lsinfo "$path"\n] );
141 my (@list, %param);
143 # parse lines in reverse order since "file:" comes first.
144 # therefore, let's first store every other parameter, and
145 # the "file:" line will trigger the object creation.
146 # of course, since we want to preserve the playlist order,
147 # this means that we're going to unshift the objects.
148 foreach my $line (reverse @lines) {
149 next unless $line =~ /^([^:]+):\s+(.+)$/;
150 $param{$1} = $2;
151 next unless $1 eq 'file' || $1 eq 'directory'; # last param of item
152 unshift @list, Audio::MPD::Item->new(%param);
153 %param = ();
155 return @list;
160 # -- Collection: retrieving the whole collection
163 # my @albums = $collection->all_albums;
165 # Return the list of all albums (strings) currently known by mpd.
167 sub all_albums {
168 my ($self) = @_;
169 return
170 map { /^Album: (.+)$/ ? $1 : () }
171 $self->_mpd->_send_command( "list album\n" );
176 # my @artists = $collection->all_artists;
178 # Return the list of all artists (strings) currently known by mpd.
180 sub all_artists {
181 my ($self) = @_;
182 return
183 map { /^Artist: (.+)$/ ? $1 : () }
184 $self->_mpd->_send_command( "list artist\n" );
189 # my @titles = $collection->all_titles;
191 # Return the list of all titles (strings) currently known by mpd.
193 sub all_titles {
194 my ($self) = @_;
195 return
196 map { /^Title: (.+)$/ ? $1 : () }
197 $self->_mpd->_send_command( "list title\n" );
202 # my @pathes = $collection->all_pathes;
204 # Return the list of all pathes (strings) currently known by mpd.
206 sub all_pathes {
207 my ($self) = @_;
208 return
209 map { /^File: (.+)$/ ? $1 : () }
210 $self->_mpd->_send_command( "list filename\n" );
214 # -- Collection: songs, albums & artists relations
217 # my @albums = albums_from_artist($artist);
219 # Return all albums performed by $artist or where $artist participated.
221 sub albums_from_artist {
222 my ($self, $artist) = @_;
223 return
224 map { /^Album: (.+)$/ ? $1 : () }
225 $self->_mpd->_send_command( qq[list album "$artist"\n] );
232 __END__
235 =head1 NAME
237 Audio::MPD::Collection - an object to query MPD's collection
240 =head1 SYNOPSIS
242 my $song = $mpd->collection->random_song;
245 =head1 DESCRIPTION
247 C<Audio::MPD::Collection> is a class meant to access & query MPD's
248 collection. You will be able to use those high-level methods instead
249 of using the low-level methods provided by mpd itself.
252 =head1 PUBLIC METHODS
254 =head2 Constructor
256 =over 4
258 =item new( $mpd )
260 This will create the object, holding a back-reference to the C<Audio::MPD>
261 object itself (for communication purposes). But in order to play safe and
262 to free the memory in time, this reference is weakened.
264 Note that you're not supposed to call this constructor yourself, an
265 C<Audio::MPD::Collection> is automatically created for you during the creation
266 of an C<Audio::MPD> object.
268 =back
271 =head2 Retrieving songs & directories
273 =over 4
275 =item all_items( [$path] )
277 Return B<all> C<Audio::MPD::Item>s (both songs & directories) currently known
278 by mpd.
280 If C<$path> is supplied (relative to mpd root), restrict the retrieval to
281 songs and dirs in this directory.
284 =item all_items_simple( [$path] )
286 Return B<all> C<Audio::MPD::Item>s (both songs & directories) currently known
287 by mpd.
289 If C<$path> is supplied (relative to mpd root), restrict the retrieval to
290 songs and dirs in this directory.
292 B</!\ Warning>: the C<Audio::MPD::Item::Song> objects will only have their
293 tag file filled. Any other tag will be empty, so don't use this sub for any
294 other thing than a quick scan!
297 =item items_in_dir( [$path] )
299 Return the items in the given C<$path>. If no C<$path> supplied, do it on
300 mpd's root directory.
302 Note that this sub does not work recusrively on all directories.
305 =back
308 =head2 Retrieving the whole collection
310 =over 4
312 =item all_albums()
314 Return the list of all albums (strings) currently known by mpd.
317 =item all_artists()
319 Return the list of all artists (strings) currently known by mpd.
322 =item all_titles()
324 Return the list of all song titles (strings) currently known by mpd.
327 =item all_pathes()
329 Return the list of all pathes (strings) currently known by mpd.
332 =back
335 =head2 Songs, albums & artists relations
337 =over 4
339 =item albums_from_artist( $artist )
341 Return all albums performed by $artist or where $artist participated.
344 =back
347 =head1 SEE ALSO
349 You can find more information on the mpd project on its homepage at
350 L<http://www.musicpd.org>, or its wiki L<http://mpd.wikia.com>.
352 Regarding this Perl module, you can report bugs on CPAN via
353 L<http://rt.cpan.org/Public/Bug/Report.html?Queue=Audio-MPD>.
355 Audio::MPD development takes place on <audio-mpd@googlegroups.com>: feel free
356 to join us. (use L<http://groups.google.com/group/audio-mpd> to sign in). Our
357 subversion repository is located at L<https://svn.musicpd.org>.
360 =head1 AUTHORS
362 Jerome Quelin <jquelin@cpan.org>
365 =head1 COPYRIGHT AND LICENSE
367 Copyright (c) 2007 Jerome Quelin <jquelin@cpan.org>
370 This program is free software; you can redistribute it and/or modify
371 it under the terms of the GNU General Public License as published by
372 the Free Software Foundation; either version 2 of the License, or
373 (at your option) any later version.
375 This program is distributed in the hope that it will be useful,
376 but WITHOUT ANY WARRANTY; without even the implied warranty of
377 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
378 GNU General Public License for more details.
380 =cut