Apache-MP3

 view release on metacpan or  search on metacpan

MP3.pm  view on Meta::CPAN


  #THESE ARE ALPHABETIZED.  KEEP THEM IN ORDER!
  %$data = (
	    album  => $comments->{album}  || $comments->{ALBUM}  || '',
	    artist => $comments->{artist} || $comments->{ARTIST} || '',
	    bitrate     => int($details->{bytes_sec}*8/1024),
	    comment => $comments->{comment} || $comments->{COMMENT} || '',
	    duration    => sprintf("%d:%2.2d", int $sec/60,$sec%60),
	    genre  => $comments->{genre}  || $comments->{GENRE}  || '',
	    min         => int $sec/60,
	    samplerate  => $details->{sample_rate},
	    sec         => $sec %60,
	    seconds     => $sec,
	    title  => $comments->{title}  || $comments->{TITLE}  || '',
	    track  => $comments->{tracknumber} || $comments->{TRACKNUMBER} || '',
	    year   => $comments->{year}   || $comments->{YEAR}   || '',
	   )
}

# a limited escape of URLs (does not escape directory slashes)
sub path_escape {
  my $self = shift;
  my $uri = shift;
  $$uri =~ s!([^a-zA-Z0-9_/.-])!uc sprintf("%%%02x",ord($1))!eg;
}

# get fields to display in list of MP3 files
sub fields {
  my $self = shift;
  my @f = split /\W+/,$self->r->dir_config('Fields')||'';
  return map { lc $_  } @f if @f;          # lower case
  return qw(title artist duration bitrate); # default
}

# read from the cache
sub read_cache {
  my $self = shift;
  my $file = shift;
  return unless my $cache = $self->cache_dir;
  my $cache_file = "$cache$file";
  my $file_age = -M $file;
  return unless -e $cache_file && -M $cache_file <= $file_age;
  return unless my $c = IO::File->new($cache_file);
  my ($data,$buffer);
  while (read($c,$buffer,4096)) {
    $data .= $buffer;
  }
  close $c;
  my @data = split $;,$data;
  push @data,'' if @data %2;  # avoid odd numbered hashes
  return @data;
}

# write to the cache
sub write_cache {
  my $self = shift;
  my ($file,$data) = @_;
  return unless my $cache = $self->cache_dir;
  my $cache_file = "$cache$file";

  # some checks and untaint
  return if $cache_file =~ m!/\.\./!; # no relative path tricks
  $cache_file =~ m!^(/.+)$! or return;
  $cache_file = $1;

  my $dirname = dirname($cache_file);
  -d $dirname || eval{mkpath($dirname)} || return;

  if (my $c = IO::File->new(">$cache_file")) {
    print $c join $;,%$data;
  }

  1;
}

# called to open the MP3 file
# can override to do downsampling, etc
sub open_file {
  my $self = shift;
  my $file = shift;
  return IO::File->new($file,O_RDONLY);
}

# find all playable files in current directory
sub find_mp3s {
  my $self    = shift;
  my $recurse = shift;

  #changing this so that it is possible to find mp3s from search page
  #  my $uri = dirname($self->r->uri);
  my $uri = dirname(shift || $self->r->uri);

  my $dir = dirname($self->r->filename);

  my @uris = $self->sort_mp3s($self->_find_mp3s($dir,$recurse));
  foreach (@uris) {
    # strip directory part
    substr($_,0,length($dir)+1) = '' if index($_,$dir) == 0;
    # turn into a URL
    $_ = "$uri/$_";
  }
  return \@uris;
}

# recursive find
sub _find_mp3s {
  my $self = shift;
  my ($d,$recurse) = @_;
  my ($directories,$files) = $self->read_directory($d);
  # Add the directory back onto each file
  unless ($d eq '.') {
    foreach my $k (keys %$files) {
      $files->{"$d/$k"} = $files->{$k};
      delete $files->{$k};
    }
  }

  if ($recurse) {
    foreach (@$directories) {
      my $f = $self->_find_mp3s("$d/$_",$recurse);
      # Add the new files to our main hash



( run in 1.224 second using v1.01-cache-2.11-cpan-39bf76dae61 )