package Text::Playlist::PLS; use strict; use warnings; our $VERSION = 0.1; sub new { my ($class) = @_; return bless({ items => [] }, $class); } sub items { my ($self) = @_; return wantarray ? @{$self->{items}} : $self->{items}; } sub add { my ($self, %args) = @_; foreach my $key (qw(file title)) { next if $args{$key}; return "Missing '$key' parameter"; } $self->{items} //= []; push @{$self->{items}}, { file => $args{file}, title => $args{title}, length => $args{length} || "-1", }; return; } sub load { my ($self, $file) = @_; $self->{items} = []; open(my $FH, "<", $file) or die $!; my @lines = <$FH>; close($FH); chomp for @lines; # safeguard return "Not looks like playlist" unless grep { $_ eq "[playlist]" } @lines; my $count = 0; foreach my $line (@lines) { if ($line =~ m/(File|Title|Length)(\d+)\s*=\s*(.*)/oi) { my ($key, $num, $value) = (lc($1), $2 - 1, $3); $value =~ s/(^\s*|\s*$)//og; $self->{items}->[$num] //= {}; $self->{items}->[$num]->{$key} = $value; next; } if ($line =~ m/numberofentries\s*=\s*(\d+)/oi) { $count = $1; next; } } warn "Number of entries not matches parsed items" if ($count != scalar @{$self->{items}}); return $self->items; } sub dump { my ($self) = @_; my $count = 0; my @lines = ('[playlist]'); foreach my $item ($self->items) { $count += 1; foreach my $key (qw(file title length)) { push @lines, sprintf("%s%d=%s", ucfirst($key), $count, $item->{$key}); } } splice(@lines, 1, 0, sprintf("numberofentries=%d", $count)); push @lines, "Version=2", ""; return join("\n", @lines); } sub save { my ($self, $file) = @_; open(my $FH, ">", $file) or die $!; print $FH $self->dump(); close($FH); return 1; } 1;