You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
1.6 KiB

package Playlist::XSPF;
use strict;
use warnings;
use feature qw(switch);
use utf8;
use XML::XPath;
our $VERSION = 0.1;
sub new {
my ($class) = @_;
return bless({ items => [], version => 0 }, $class);
}
sub items {
my ($self) = @_;
return wantarray ? @{$self->{items}} : $self->{items};
}
sub add {
my ($self, %args) = @_;
foreach my $key (qw(title location)) {
next if $args{$key};
return "Missing '$key' parameter";
}
$self->{items} //= [];
push @{$self->{items}}, {
title => $args{title},
location => $args{location},
};
return;
}
sub load {
my ($self, $file) = @_;
my $xp = XML::XPath->new(filename => $file);
if (my $vers = $xp->find('/playlist/@version')) {
$self->{version} = $vers;
} else {
return "Can't find playlist version";
}
my $tracks = $xp->find('/playlist/trackList/track');
foreach my $track ($tracks->get_nodelist) {
my $item = {};
foreach my $child ($track->getChildNodes) {
next unless (ref $child eq 'XML::XPath::Node::Element');
my $value = $child->string_value();
given ($child->getName()) {
when (m/title/oi) { $item->{title} = $value; }
when (m/location/oi) { $item->{location} = $value; }
default { warn "garbage inside <track> element: $_ -> $value\n"; }
}
}
unless ($item->{title} and $item->{location}) {
warn "Missing mandatory 'title' or 'location' field\n";
next;
}
push @{ $self->{items} }, $item;
}
return $self->items;
}
1;
__END__
=pod
=head1 LINKS
L<https://en.wikipedia.org/wiki/XML_Shareable_Playlist_Format>
=cut