Filesys-Virtual-DAAP
view release on metacpan or search on metacpan
lib/Filesys/Virtual/DAAP.pm view on Meta::CPAN
=cut
# HACKY - mixin this from the ::Plain class, it only deals with the
# mapping of root_path, cwd, and home_path, so it should be safe
*_resolve_path = \&Filesys::Virtual::Plain::_resolve_path;
sub new {
my $ref = shift;
my $self = $ref->SUPER::new(@_);
$self->_tmpdir( tempdir( CLEANUP => 1 ) );
$self->_client( Net::DAAP::Client->new( $self->host ) );
push @{ $self->_client->{SONG_ATTRIBUTES} },
qw( daap.songcompilation daap.songtracknumber daap.songtrackcount );
$self->_client->{SERVER_PORT} = $self->port || 3689;
$self->_client->connect;
$self->_build_vfs;
return $self;
}
sub _build_vfs {
my $self = shift;
my $daap = $self->_client;
$self->_vfs( {} );
for my $song (values %{ $daap->songs }) {
bless $song, __PACKAGE__."::Song";
$self->_vfs->{Library}
{ $self->_fs_safe(
$song->{'daap.songcompilation'} ? 'Compilations'
: $song->{'daap.songartist'}) }
{ $self->_fs_safe( $song->{'daap.songalbum'} || "Unknown album" ) }
{ $song->filename } = $song;
}
for my $playlist (values %{ $daap->playlists }) {
my $i;
for my $song (@{ $daap->playlist( $playlist->{'dmap.itemid'} ) } ) {
next unless $song; # huh - how can this be false? it is though.
# clone the data from the Song object, only override the
# daap.songtracknumber and the daap.songtrackcount, so the
# cleverness in ::Song->filename for generating a filename
# with the correct width prefix works
$song = bless {
%$song,
'daap.songtracknumber' => ++$i,
'daap.songtrackcount' => $playlist->{'dmap.itemcount'},
}, __PACKAGE__."::Song";
$self->_vfs->{Playlists}
{ $self->_fs_safe( $playlist->{'dmap.itemname'} ) }
{ $song->filename } = $song;
}
}
#print Dump $self->_vfs;
}
sub _get_leaf {
my $self = shift;
my $path = $self->_resolve_path( shift );
my (undef, @chunks) = split m{/}, $path;
my $walk = $self->_vfs;
$walk = $walk->{$_} for @chunks;
return $walk;
}
sub list {
my $self = shift;
my $leaf = $self->_get_leaf( shift );
return unless $leaf;
return blessed $leaf ? $leaf->filename : qw( . .. ), sort keys %{ $leaf };
}
sub list_details {
my $self = shift;
my $leaf = $self->_get_leaf( shift );
return unless $leaf;
return blessed $leaf ? $self->_ls_file( $leaf->filename => $leaf ) :
map { $self->_ls_file( $_ => $leaf->{$_} ) } qw( . .. ), sort keys %{ $leaf };
}
sub _ls_file {
my $self = shift;
my ($name, $leaf) = @_;
if (blessed $leaf) {
# drwxr-xr-x 46 richardc richardc 1564 5 May 10:03 Applications
return sprintf "-r--r--r-- 1 richardc richardc %8s 7 May 12:41 %s",
$leaf->size, $leaf->filename;
}
else {
return sprintf "drwxr-xr-x 3 richardc richardc %8s 7 May 12:41 %s",
1024, $name;
}
}
sub chdir {
my $self = shift;
my $to = $self->_resolve_path( shift );
my $leaf = $self->_get_leaf( $to );
return undef unless ref $leaf eq 'HASH';
return $self->cwd( $to );
}
# well if ::Plain can't be bothered, we can't be bothered either
sub modtime { return (0, "") }
sub stat {
my $self = shift;
my $leaf = $self->_get_leaf( shift );
return unless $leaf;
my $blocksize = 1024;
if (blessed $leaf) {
# dev, ino, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, blksize, blocks
return (0+$self, 0+$leaf, 0100444, 1, 0, 0, 0, $leaf->size,
$leaf->atime, $leaf->mtime, $leaf->ctime,
$blocksize, ($leaf->size / $blocksize) + 1);
}
else {
return (0+$self, 0+$leaf, 042555, 1, 0, 0, 0, $blocksize,
( run in 0.696 second using v1.01-cache-2.11-cpan-71847e10f99 )