package MP3::M3U::Parser::Export; use strict; use warnings; use vars qw( $VERSION ); use Carp qw( croak ); use MP3::M3U::Parser::Constants; use MP3::M3U::Parser::Dummy; $VERSION = '2.30'; my %DEFAULT = ( format => 'html', filename => 'mp3_m3u%s.%s', encoding => 'ISO-8859-1', drives => 'on', overwrite => 0, toscalar => 0, ); sub export { my($self, @args) = @_; my %opt = @args % 2 ? () : @args; my $format = $opt{'-format'} || $self->{expformat} || $DEFAULT{format }; my $encoding = $opt{'-encoding'} || $self->{encoding} || $DEFAULT{encoding }; my $drives = $opt{'-drives'} || $self->{expdrives} || $DEFAULT{drives }; my $overwrite = $opt{'-overwrite'} || $self->{overwrite} || $DEFAULT{overwrite}; my $to_scalar = $opt{'-toscalar'} || $self->{exptoscalar} || $DEFAULT{toscalar }; my $file = $opt{'-file'} || $self->_default_filename( $format ); $file = $self->_locate_file($file) if ! $to_scalar; my $OUTPUT = $format eq 'xml' ? $self->_export_to_xml( $encoding ) : $self->_export_to_html( $encoding, $drives, $to_scalar, $file) ; if ( $to_scalar ) { ${$to_scalar} = $OUTPUT; } else { my $fh = $self->_check_export_params( $file, $to_scalar, $overwrite ); print {$fh} $OUTPUT or croak "Can't print to FH: $!"; $fh->close; } $self->{EXPORTF}++; return $self if defined wantarray; return; } sub _default_filename { my($self, $format) = @_; croak 'Export format is missing' if ! $format; return sprintf $DEFAULT{filename}, $self->{EXPORTF}, $format; } sub _check_export_params { my($self, $file, $to_scalar, $overwrite) = @_; my $fh; if ( $to_scalar && ( ! ref $to_scalar || ref $to_scalar ne 'SCALAR' ) ) { croak '-toscalar must be a SCALAR reference'; } if ( ! $to_scalar ) { if ( -e $file && ! $overwrite ) { croak "The export file '$file' exists & overwrite option is not set"; } require IO::File; $fh = IO::File->new; $fh->open( $file, '>' ) or croak "I can't open export file '$file' for writing: $!"; } return $fh; } sub _export_to_html { my($self, $encoding, $drives, $to_scalar, $file) = @_; my $OUTPUT = EMPTY_STRING; # I don't think that weird numbers in the html mean anything # to anyone. So, if you didn't want to format seconds in your # code, I'm overriding it here (only for export(); Outside # export(), you'll get the old value): my $old_seconds = $self->{seconds}; $self->{seconds} = 'format'; my %t; @t{ qw( up cd data down ) } = split m{\Q\E}xms, $self->_template; foreach (keys %t) { $t{$_} = $self->_trim( $t{$_} ); } my $tmptime = $self->{TOTAL_TIME} ? $self->_seconds($self->{TOTAL_TIME}) : undef; my @tmptime; if ($tmptime) { @tmptime = split m{:}xms,$tmptime; unshift @tmptime, 'Z' if $#tmptime <= 1; } my $average = $self->{AVERAGE_TIME} ? $self->_seconds( $self->{AVERAGE_TIME} ) : 'Unknown' ; my $HTML = { ENCODING => $encoding, SONGS => $self->{TOTAL_SONGS}, TOTAL => $self->{TOTAL_FILES}, AVERTIME => $average, FILE => $to_scalar ? EMPTY_STRING : $self->_locate_file($file), TOTAL_FILES => $self->{TOTAL_FILES}, TOTAL_TIME => @tmptime ? [ @tmptime ] : EMPTY_STRING, }; $OUTPUT .= $self->_tcompile(template => $t{up}, params=> {HTML => $HTML}); my($song,$cdrom, $dlen); foreach my $cd (@{ $self->{'_M3U_'} }) { next if($#{$cd->{data}} < 0); $cdrom .= "$cd->{drive}\\" if $drives ne 'off'; $cdrom .= $cd->{list}; $OUTPUT .= sprintf $t{cd}."\n", $cdrom; foreach my $m3u (@{ $cd->{data} }) { $song = $m3u->[ID3]; if ( ! $song ) { my @test_path = split /\\/xms, $m3u->[PATH]; my $tp = pop @test_path || $m3u->[PATH]; my @test_file = split /\./xms, $song; $song = $test_file[0] || $tp; } $dlen = $m3u->[LEN] ? $self->_seconds($m3u->[LEN]) : ' '; $song = $song ? $self->_escape($song) : ' '; $OUTPUT .= sprintf "%s\n", $self->_tcompile( template => $t{data}, params => { data => { len => $dlen, song => $song, } } ); } $cdrom = EMPTY_STRING; } $OUTPUT .= $t{down}; $self->{seconds} = $old_seconds; # restore return $OUTPUT; } sub _export_to_xml { my($self, $encoding) = @_; my $OUTPUT = EMPTY_STRING; $self->{TOTAL_TIME} = $self->_seconds($self->{TOTAL_TIME}) if $self->{TOTAL_TIME} > 0; $OUTPUT .= sprintf qq~\n~, $encoding; $OUTPUT .= sprintf qq~\n~, $self->{TOTAL_FILES}, $self->{TOTAL_SONGS}, $self->{TOTAL_TIME}, $self->{AVERAGE_TIME}; my $sc = 0; foreach my $cd (@{ $self->{'_M3U_'} }) { $sc = $#{$cd->{data}}+1; next if ! $sc; $OUTPUT .= sprintf qq~\n~, $cd->{list}, $cd->{drive}, $sc; foreach my $m3u (@{ $cd->{data} }) { $OUTPUT .= sprintf qq~%s\n~, $self->_escape( $m3u->[ID3] ) || EMPTY_STRING, $m3u->[LEN] || EMPTY_STRING, $self->_escape( $m3u->[PATH] ); } $OUTPUT .= "\n"; $sc = 0; } $OUTPUT .= "\n"; return $OUTPUT; } # compile template sub _tcompile { my($self, @args) = @_; my $class = ref $self; croak 'Invalid number of parameters' if @args % 2; require Text::Template; my %opt = @args; my $t = Text::Template->new( TYPE => 'STRING', SOURCE => $opt{template}, DELIMITERS => ['<%', '%>'], ) or croak "Couldn't construct the template: $Text::Template::ERROR"; my @globals; foreach my $p ( keys %{ $opt{params} } ) { my $ref = ref $opt{params}->{$p}; my $prefix = $ref eq 'HASH' ? q{%} : $ref eq 'ARRAY' ? q{@} : q{$} ; push @globals, $prefix . $p; } my $text = $t->fill_in(PACKAGE => $class . '::Dummy', PREPEND => sprintf('use strict;use vars qw[%s];', join q{ }, @globals ), HASH => $opt{params}, ) or croak "Couldn't fill in template: $Text::Template::ERROR"; return $text; } # HTML template code sub _template { return <<'MP3M3UPARSERTEMPLATE'; MP3::M3U::Parser Generated PlayList

MP3::M3U::Parser

playlist


<%$HTML{SONGS}%> tracks and <%$HTML{TOTAL}%> Lists in playlist, average track length: <%$HTML{AVERTIME}%>.
Playlist length: <% my $time; if ($HTML{TOTAL_TIME}) { my @time = @{$HTML{TOTAL_TIME}}; $time = qq~ $time[0] hours ~ if $time[0] ne 'Z'; $time .= qq~ $time[1] minutes $time[2] seconds. ~; } else { $time = qq~Unknown.~; } $time; %>
<% qq~Right-click here to save this HTML file.~ if $HTML{FILE} %>

<% $HTML{TOTAL_FILES} > 1 ? "Playlists and Files" : "Playlist files"; %>:

%s
<%$data{len}%><%$data{song}%>

This HTML File is based on WinAmp`s HTML List. MP3M3UPARSERTEMPLATE } 1; __END__ =pod =head1 NAME MP3::M3U::Parser::Export - Exports playlist to HTML/XML =head1 SYNOPSIS Private module. =head1 DESCRIPTION This document describes version C<2.30> of C released on C<30 May 2010>. - =head1 METHODS =head2 export See C in L. =head1 SEE ALSO L. =head1 AUTHOR Burak Gursoy . =head1 COPYRIGHT Copyright 2003 - 2010 Burak Gursoy. All rights reserved. =head1 LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.10.1 or, at your option, any later version of Perl 5 you may have available. =cut