From: Eric Gillespie Date: Fri, 4 Mar 2022 03:48:24 +0000 (-0600) Subject: split out some shared code and tidy 0-prefixing on DISCNUMBER X-Git-Url: https://diplodocus.org/git/flac-archive/commitdiff_plain/10d83bbfbcd2461f4fd53f6bc17d1250922214b5?hp=cfd5982bbc4e0321c4bf6e13ac54337f38372066 split out some shared code and tidy 0-prefixing on DISCNUMBER --- diff --git a/GNUmakefile b/GNUmakefile index 764db47..824340b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -30,6 +30,9 @@ MAN=\ all: apic-read apic-write strip-tags ${SCRIPTS} ${MAN} +test: + prove -r t + #CXX= /opt/llvm-3.3.src/bin/clang -std=c++11 -g -Wall CXX= g++ -std=c++0x -g -Wall @@ -73,4 +76,4 @@ uninstall: rm -f $(addprefix ${DESTDIR}${man1dir}/, $(addsuffix .1, ${SCRIPTS})) rm -f $(addprefix ${DESTDIR}${cat1dir}/, $(addsuffix .0, ${SCRIPTS})) -.PHONY: all clean install uninstall +.PHONY: all test clean install uninstall diff --git a/fa-encode b/fa-encode index 5a8a72d..c18b1bc 100755 --- a/fa-encode +++ b/fa-encode @@ -61,50 +61,21 @@ package epg::flac::archive::encode; use v5.12; use warnings; -sub mangle_for_file_name { - my $fn = shift; - $fn =~ s/\s+/_/g; - $fn =~ s/[^A-Za-z0-9._]/-/g; - $fn -} - -sub read_tags { - my $fn = shift; - open(my $fh, '<', $fn) || die("open($fn): $!"); - my %album; - my @tracks; - my $tracknum = 0; - while (<$fh>) { - chomp; - s/^([^=[\]]+)(\[(\d+)])?=// || die("no field name in $_"); - my $name = $1; - # TODO validate $name - # TODO album tags should be illegal after track tags - if (defined($3)) { - if ($3 == $tracknum + 2) { - $tracknum++; - } elsif ($3 != $tracknum + 1) { - $tracknum++; # increment from 0 to 1 for error message - die("illegal track number jump from $tracknum to $3") - } - push(@{$tracks[$tracknum]->{$name}}, $_); - } else { - push(@{$album{$name}}, $_); - } - } +use FindBin; - \%album, \@tracks -} - -sub quote { - my $s = shift; - $s =~ s/'/'\\''/g; - "'$s'" -} +require "$FindBin::Bin/tags.p"; +epg::flac::archive::tags->import( + qw[ + read_tags + mangle_for_file_name + quote + ]); sub main { my $input_directory = shift; - my ($album, $tracks) = read_tags("$input_directory/tags"); + my $fn = "$input_directory/tags"; + open(my $fh, '<', $fn) || die("open($fn): $!"); + my ($album, $tracks) = read_tags($fh); if (!defined($album->{ALBUM}) || scalar(@{$album->{ALBUM}}) != 1) { die('exactly one ALBUM tag required') } @@ -127,7 +98,7 @@ sub main { if (scalar(@{$album->{DISCNUMBER}}) != 1) { die('one or zero DISCNUMBER tags required') } - @discnumber = (sprintf('%02d', $album->{DISCNUMBER}->[0])); + @discnumber = ($album->{DISCNUMBER}->[0]); } my $dir = join('/', '..', mangle_for_file_name($artist), mangle_for_file_name($album_tag)); @@ -156,7 +127,7 @@ sub main { my $fn = join('/', $dir, join('_', - @discnumber, + (map { sprintf('%02d', $_) } @discnumber), $tracknum_s, mangle_for_file_name($title) . '.flac', ), diff --git a/t/mangle.t b/t/mangle.t new file mode 100644 index 0000000..d0867eb --- /dev/null +++ b/t/mangle.t @@ -0,0 +1,23 @@ +use v5.12; +use warnings; + +use Test::More tests => 5; + +require './tags.pl'; +epg::flac::archive::tags->import('mangle_for_file_name'); + +is mangle_for_file_name('foo'), 'foo', + 'no mangling needed'; + +# This is dumb, but does it matter? Garbage in... +is mangle_for_file_name('-'), '', + 'nothing but a -'; + +is mangle_for_file_name("-don't keep (most) of this \"stuff\"!"), + 'don-t_keep_most_of_this_stuff'; + +is mangle_for_file_name("'repeated things ()"), + 'repeated_things'; + +is mangle_for_file_name("y u put\nnewline"), + 'y_u_put_newline'; diff --git a/t/read_tags.t b/t/read_tags.t new file mode 100644 index 0000000..653f35a --- /dev/null +++ b/t/read_tags.t @@ -0,0 +1,59 @@ +use v5.12; +use warnings; + +use Test::Simple tests => 3; +use Test::Differences; + +require './tags.pl'; +epg::flac::archive::tags->import('read_tags'); + +my $fh = str_file_handle(''); +eq_or_diff + [read_tags($fh)], + [{}, []], + 'empty file'; + +$fh = str_file_handle('FOO=bar'); +eq_or_diff + [read_tags($fh)], + [{ + FOO => [ + 'bar', + ], + }, + []], + 'random tag'; + +$fh = str_file_handle(< ["It's Your Call"], + ARTIST => ['Reba McEntire'], + }, + [ + { + ARTIST => [ + 'Reba McEntire', + 'Vince Gill', + ], + TITLE => ["The Heart Won't Lie"], + }, + ], + ], + 'track ARTIST overrides album ARTIST'; + +exit; + +sub str_file_handle { + my $contents = join('', @_); + open(my $fh, '+<', \$contents); + $fh +} diff --git a/tags.pl b/tags.pl new file mode 100644 index 0000000..696a97d --- /dev/null +++ b/tags.pl @@ -0,0 +1,59 @@ +package epg::flac::archive::tags; + +use v5.12; +use warnings; + +use Exporter 'import'; + +our @EXPORT_OK = qw[ + read_tags + mangle_for_file_name + quote +]; + +sub read_tags { + my $fh = shift; + my %album; + my @tracks; + my $tracknum = 0; + while (<$fh>) { + chomp; + s/^([^=[\]]+)(\[(\d+)])?=// || die("no field name in $_"); + my $name = $1; + # TODO validate $name + # TODO album tags should be illegal after track tags + if (defined($3)) { + if ($3 == $tracknum + 2) { + $tracknum++; + } elsif ($3 != $tracknum + 1) { + $tracknum++; # increment from 0 to 1 for error message + die("illegal track number jump from $tracknum to $3") + } + push(@{$tracks[$tracknum]->{$name}}, $_); + } else { + push(@{$album{$name}}, $_); + } + } + + \%album, \@tracks +} + +sub mangle_for_file_name { + my $fn = shift; + $fn =~ s/[!,.?]//g; # discard these punctuation marks + $fn =~ s/\s+/_/g; # replace all whitespace with _ + $fn =~ s/[^A-Za-z0-9_]/-/g; # everything else with - + $fn =~ s/_[_-]/_/g; # collapse repeated _ or - to _ + $fn =~ s/-[_-]/_/g; # more + $fn =~ s/^[_-]+//; # discard any _ or - at beginning + $fn =~ s/[_-]+$//; # at end too + $fn +} + +sub quote { + my $s = shift; + $s =~ s/'/'\\''/g; + "'$s'" +} + +1;