From f7964165707b3e45f93960236a695596fa62bcd1 Mon Sep 17 00:00:00 2001 From: Marius Gavrilescu Date: Sat, 22 Oct 2016 18:11:22 +0100 Subject: [PATCH] Load tag-reading modules on demand --- lib/App/MusicExpo.pm | 42 +++++++++++++++++++++++++----------------- t/App-MusicExpo.t | 23 ++++++++++++++++------- t/musicexpo-cache.t | 27 +++++++++++++++++++++------ 3 files changed, 62 insertions(+), 30 deletions(-) diff --git a/lib/App/MusicExpo.pm b/lib/App/MusicExpo.pm index c1433ca..f2ee745 100644 --- a/lib/App/MusicExpo.pm +++ b/lib/App/MusicExpo.pm @@ -5,13 +5,8 @@ use warnings; our $VERSION = '1.001_001'; -use Audio::FLAC::Header qw//; use HTML::Template::Compiled qw//; use Memoize qw/memoize/; -use MP3::Info qw/get_mp3tag/; -use Ogg::Vorbis::Header::PurePerl; -use MP4::Info qw/get_mp4tag get_mp4info/; -use Audio::Opusfile qw//; use DB_File qw//; use Encode qw/encode/; @@ -54,7 +49,7 @@ sub flacinfo{ sub mp3info{ my $file=$_[0]; - my %tag = map { encode 'UTF-8', $_ } %{get_mp3tag $file}; + my %tag = map { encode 'UTF-8', $_ } %{MP3::Info::get_mp3tag $file}; my @trkn = split m#/#s, $tag{TRACKNUM} // ''; freeze +{ @@ -96,8 +91,8 @@ sub mp4_format ($){ ## no critic (ProhibitSubroutinePrototypes) sub mp4info{ my $file=$_[0]; - my %tag = map { ref() ? $_ : encode 'UTF-8', $_ } %{get_mp4tag $file}; - my %info = %{get_mp4info $file}; + my %tag = map { ref() ? $_ : encode 'UTF-8', $_ } %{MP4::Info::get_mp4tag $file}; + my %info = %{MP4::Info::get_mp4info $file}; freeze +{ format => mp4_format $info{ENCODING}, @@ -132,23 +127,35 @@ sub opusinfo { freeze \%data; } -my %info = ( - '.flac' => \&flacinfo, - '.mp3' => \&mp3info, - '.ogg' => \&vorbisinfo, - '.oga' => \&vorbisinfo, - '.mp4' => \&mp4info, - '.aac' => \&mp4info, - '.m4a' => \&mp4info, - '.opus' => \&opusinfo, +my @optional_modules = ( + [ 'Audio::FLAC::Header', \&flacinfo, '.flac' ], + [ 'MP3::Info', \&mp3info, '.mp3' ], + [ 'Ogg::Vorbis::Header::PurePerl', \&vorbisinfo, '.ogg', '.oga' ], + [ 'MP4::Info', \&mp4info, '.mp4', '.aac', '.m4a' ], + [ 'Audio::Opusfile', \&opusinfo, '.opus' ] ); +my %info; + +for (@optional_modules) { + my ($module, $coderef, @extensions_handled) = @$_; + if (eval "require $module") { + $info{$_} = $coderef for @extensions_handled + } +} + +unless (%info) { + warn 'No tags-reading module detected. Install one of the following modules: ' . join ', ', map { $_->[0] } @optional_modules; +} + sub normalizer{ "$_[0]|".(stat $_[0])[9] } sub make_fragment{ join '-', map { lc =~ y/a-z0-9/_/csr } @_ } +sub extensions_handled { keys %info } + sub run { if ($cache) { tie my %cache, 'DB_File', $cache, O_RDWR|O_CREAT, 0644; ## no critic (ProhibitTie) @@ -158,6 +165,7 @@ sub run { my %files; for my $file (@ARGV) { my ($basename, undef, $suffix) = fileparse $file, keys %info; + next unless $suffix; $files{$basename} //= []; push @{$files{$basename}}, thaw scalar $info{$suffix}->($file); } diff --git a/t/App-MusicExpo.t b/t/App-MusicExpo.t index 09b2bde..ea1c496 100644 --- a/t/App-MusicExpo.t +++ b/t/App-MusicExpo.t @@ -2,7 +2,7 @@ use v5.14; use warnings; -use Test::More tests => 37; +use Test::More tests => 46; use Scalar::Util qw/looks_like_number/; use Storable qw/thaw/; @@ -19,18 +19,27 @@ my %data = ( genre => 'Electro' ); +my %handled = map { $_ => 1 } App::MusicExpo::extensions_handled; + sub test { my ($format, $sub, $file) = @_; - my $info = thaw $sub->($file); - is $info->{format}, $format, "$format format"; - for (sort keys %data) { - my $op = looks_like_number $data{$_} ? '==' : 'eq'; - cmp_ok $info->{$_}, $op, $data{$_}, "$format $_" + my ($ext) = $file =~ /(\..+)$/; + + SKIP: + { + skip "Cannot handle $ext files (tag-reading module missing)", 9 unless $handled{$ext}; + my $info = thaw $sub->($file); + is $info->{format}, $format, "$format format"; + for (sort keys %data) { + my $op = looks_like_number $data{$_} ? '==' : 'eq'; + cmp_ok $info->{$_}, $op, $data{$_}, "$format $_" + } + is $info->{file}, $file, "$format file"; } - is $info->{file}, $file, "$format file"; } test FLAC => \&App::MusicExpo::flacinfo, 'empty.flac'; test MP3 => \&App::MusicExpo::mp3info, 'empty3.mp3'; test Vorbis => \&App::MusicExpo::vorbisinfo, 'empty.ogg'; test AAC => \&App::MusicExpo::mp4info, 'empty4.aac'; +test Opus => \&App::MusicExpo::opusinfo, 'empty2.opus'; diff --git a/t/musicexpo-cache.t b/t/musicexpo-cache.t index 47e07c9..b703b7a 100644 --- a/t/musicexpo-cache.t +++ b/t/musicexpo-cache.t @@ -18,9 +18,28 @@ close STDOUT; my $out; open STDOUT, '>', \$out; +my %handled = map { $_ => 1 } App::MusicExpo::extensions_handled; + +my $prefix = 'CelluleSilenceL'autre endroitElectro01/092005'; + +my @lines; +if ($handled{'.flac'} && $handled{'.ogg'}) { + push @lines, $prefix . 'FLAC Vorbis ' +} elsif ($handled{'.flac'}) { + push @lines, $prefix . 'FLAC ' +} elsif ($handled{'.ogg'}) { + push @lines, $prefix . 'Vorbis ' +} + +push @lines, $prefix . 'Opus ' if $handled{'.opus'}; +push @lines, $prefix . 'MP3 ' if $handled{'.mp3'}; +push @lines, 'L'autre endroitElectro1/92005AAC ' if $handled{'.aac'}; + +my $contents = join "\n", @lines; + App::MusicExpo->run; -is $out, <<'OUT', 'output is correct'; +is $out, <<"OUT", 'output is correct'; Music @@ -32,11 +51,7 @@ is $out, <<'OUT', 'output is correct'; -$contents
TitleArtistAlbumGenreTrackYearType -
CelluleSilenceL'autre endroitElectro01/092005FLAC Vorbis -
CelluleSilenceL'autre endroitElectro01/092005Opus -
CelluleSilenceL'autre endroitElectro01/092005MP3 -
CelluleSilenceL'autre endroitElectro1/92005AAC +
OUT -- 2.30.2