Apache-MP3
view release on metacpan or search on metacpan
my $NO = '^(no|false)$'; # regular expression
my $YES = '^(yes|true)$'; # regular expression
sub handler : method {
my $class = shift;
my $obj = $class->new(@_) or die "Can't create object: $!";
return $obj->run();
}
sub new {
my $class = shift;
my $r = shift if @_ == 1;
my $self = bless {@_}, ref($class) || $class;
$self->{r} ||= $r if $r;
my @lang_tags;
push @lang_tags,split /,\s+/,$r->headers_in->{'Accept-language'}
if $r->headers_in->{'Accept-language'};
push @lang_tags,$r->dir_config('DefaultLanguage') || 'en-US';
$self->{'lh'} ||=
Apache::MP3::L10N->get_handle(@lang_tags)
|| die "No language handle?"; # shouldn't ever happen!
$self->{'supported_types'} =
{
# type condition handler method
'audio/mpeg' => eval "use MP3::Info; 1;" && 'read_mpeg',
'audio/mpeg4' => eval "use MP4::Info; 1;" && 'read_mpeg4',
'application/x-ogg' => eval "use Ogg::Vorbis; 1;" && 'read_vorbis_ogg' ||
eval "use Ogg::Vorbis::Header::PurePerl; 1;"
&& 'read_vorbis_hp',
'audio/x-wav' => eval "use Audio::Wav; 1;" && 'read_wav'
};
$self->{'suffixes'} = [ qw(.ogg .OGG .wav .WAV .mp3 .MP3 .mpeg .MPEG .m4a .mp4 .m4p)];
return $self;
}
sub x { # maketext plus maybe escape. The "x" for "xlate"
my $x = (my $lh = shift->{'lh'})->maketext(@_);
$x =~ s/([^\x00-\x7f])/'&#'.ord($1).';'/eg
if $x =~ m/[^\x00-\x7f]/ and $lh->must_escape;
return $x;
}
sub lh { return shift->{lh} } # language handle
sub aright { -align => shift->{lh}->right }
# align "right" (or, in case of Arabic (etc), really left).
sub aleft { -align => shift->{lh}->left }
# align "light" (or, in case of Arabic (etc), really right).
sub r { return shift->{r} }
sub html_content_type {
my $self = shift;
return 'text/html; charset=' . $self->lh->encoding
}
sub help_screen {
my $self = shift;
$self->r->content_type( $self->html_content_type );
return OK if $self->r->header_only;
print start_html(
-lang => $self->lh->language_tag,
-title => $self->x('Quick Help Summary'),
-dir => $self->lh->direction,
-head => meta({-http_equiv => 'Content-Type',
-content => $self->html_content_type
}
),
-script =>{-src=>$self->default_dir.'/functions.js'},
);
my $help_img_url = $self->help_img_url; # URL for the image
my ($url,$width,$height) = $help_img_url=~/(.+):(\d+)x(\d+)/;
$url ||= $help_img_url;
$width ||= 500;
$height ||= 400;
print img({-src => $url,
-alt => "",
-height => $height,
-width => $width,
$self->aleft,
}), "\n";
print join "\n".br(),
$self->help_figure_list
;
print "\n", end_html();
return;
}
sub help_figure_list {
my $self = shift;
# Provide a legend for the items in the figure
return(
b("A"). $self->x("= Stream all songs"),
b("B"). $self->x("= Shuffle-play all Songs"),
b("C"). $self->x("= Stream all songs"),
b("D"). $self->x("= Go to earlier directory"),
b("E"). $self->x("= Stream contents"),
b("F"). $self->x("= Enter directory"),
b("G"). $self->x("= Stream this song"),
b("H"). $self->x("= Select for streaming"),
b("I"). $self->x("= Download this song"),
b("J"). $self->x("= Stream this song"),
b("K"). $self->x("= Sort by field"),
);
}
sub run {
my $self = shift;
my $r = $self->r;
my $last_modified = (stat(_))[9];
$self->r->headers_out->add('ETag' => sprintf("%lx-%s", $last_modified, $VERSION));
if (my $check = $self->r->headers_in->{"If-None-Match"}) {
my ($time, $ver) = $check =~ /^([a-f0-9]+)-([0-9.]+)$/;
if ($check eq '*' or (hex($time) == $last_modified and $ver == $VERSION)) {
return HTTP_NOT_MODIFIED;
}
}
return DECLINED unless my ($directories,$mp3s,$playlists,$txtfiles)
= $self->read_directory($dir);
$self->r->content_type( $self->html_content_type );
return OK if $self->r->header_only;
$self->page_top($dir);
$self->directory_top($dir);
print "\n<!-- begin main -->\n";
if(@$directories) {
print "\n<!-- begin subdirs -->\n";
$self->list_subdirs($directories);
print "\n<!-- end subdirs -->\n";
}
if(@$txtfiles) {
print "\n<!-- begin txtfiles -->\n";
$self->list_txtfiles($txtfiles);
print "\n<!-- end txtfiles -->\n";
}
if(@$playlists) {
print "\n<!-- begin playlists -->\n";
$self->list_playlists($playlists);
print "\n<!-- end playlists -->\n";
}
if(%$mp3s) {
print "\n<!-- begin mp3s -->\n";
$self->list_mp3s($mp3s);
print "\n<!-- end mp3s -->\n";
}
print "\n<!-- end main -->\n";
print hr unless %$mp3s;
$self->directory_bottom($dir);
return OK;
}
# print the HTML at the top of the page
sub page_top {
my $self = shift;
my $dir = shift;
my $title = $self->r->uri;
print start_html(
-title => $title,
-head => meta({-http_equiv => 'Content-Type',
-content => 'text/html; charset='
. $self->html_content_type
}),
-lang => $self->lh->language_tag,
-dir => $self->lh->direction,
-style => {-src=>$self->stylesheet},
-script =>{-src=>$self->default_dir.'/functions.js'},
);
}
# print the HTML at the top of a directory listing
sub directory_top {
my $self = shift;
my $dir = shift;
my $title = $self->r->uri;
my $links;
print start_table({-width => '100%'}), start_TR;
print start_td({-width=>'100%'});
if ($self->path_style eq 'staircase') {
$links = $self->generate_navpath_staircase($title);
} elsif ($self->path_style eq 'arrows') {
$links = $self->generate_navpath_arrows($title);
} elsif ($self->path_style eq 'slashes') {
$links = $self->generate_navpath_slashes($title);
}
print a({-href=>'./playlist.m3u?Play+All+Recursive=1'},
img({-src => $self->cd_icon($dir), $self->aleft, -alt=>
$self->x('Stream All'),
-border=>0})),
$links,
a({-href=>'./playlist.m3u?Shuffle+All+Recursive=1'},
font({-class=>'directory'}, '[',
$self->x('Shuffle All'),
']'
))
.' '.
a({-href=>'./playlist.m3u?Play+All+Recursive=1'},
font({-class=>'directory'}, '[',
$self->x('Stream All'),
']'
)),
br({-clear=>'ALL'}),;
if (my $t = $self->stream_timeout) {
print p(strong(
$self->x('Note:')
),' ',
$self->x("In this demo, streaming is limited to approximately [quant,_1,second,seconds].", $t),
"\n"
);
}
print end_td;
print end_TR, end_table;
}
# staircase style path
( run in 0.722 second using v1.01-cache-2.11-cpan-39bf76dae61 )