=head1 SYNOPSIS
-B<fa-rip> [B<-d> I<device>] [B<-t> I<track-count>]
+B<fa-rip> [B<-d> I<device>] [B<-p> I<post-processor> [B<-t> I<track-count>]
=cut
CDDEV
);
+use Fcntl qw(O_CREAT O_WRONLY);
use File::Temp;
use Getopt::Long qw(:config gnu_getopt no_ignore_case);
use POSIX ':sys_wait_h';
my $command = shift;
my $status;
- system($command);
+ $status = system($command);
- if (WIFEXITED($?)) {
- $status = WEXITSTATUS($?);
- if ($status != 0) {
- die("$command exited $status");
+ if (WIFEXITED($status)) {
+ if (($status = WEXITSTATUS($status)) != 0) {
+ die("$command exited with status $status");
}
-
- } elsif (WIFSIGNALED($?)) {
- $status = WTERMSIG($?);
- die("$command signalled $status");
-
- } elsif (WIFSTOPPED($?)) {
- $status = WSTOPSIG($?);
- die("$command stopped $status");
-
+ } elsif (WIFSIGNALED($status)) {
+ die("$command killed with signal ", WTERMSIG($status));
+ } elsif (WIFSTOPPED($status)) {
+ die("$command stopped with signal ", WSTOPSIG($status));
} else {
die("Major horkage on system($command): \$? = $? \$! = $!");
}
return $trackcount;
}
+sub tags_file {
+ my $fn = shift;
+ my $trackcount = shift;
+ my $various = shift;
+ my $artist = shift;
+ my $album = shift;
+ my $fh;
+ my $i;
+ my $track;
+ my $name;
+
+ open($fh, '>', $fn) or die("open('>$fn'): $!");
+ print($fh 'ARTIST=', (defined($artist) and $artist or ''), "\n");
+ print($fh 'ALBUM=', (defined($album) and $album or ''), "\n");
+ # MusicBrainz doesn't have dates yet; these are usually wrong anyway.
+ print($fh "DATE=\n");
+
+ for $i (1 .. $trackcount) {
+ $various and print($fh "ARTIST[$i]=\n");
+ if ($track = shift(@_)) {
+ $name = $track->get_name;
+ } else {
+ $name = '';
+ }
+ print($fh "TITLE[$i]=$name\n");
+ }
+
+ close($fh) or die("close(>$fn): $!");
+}
+
sub tags {
my $device = shift;
my $trackcount = shift;
my @results;
my $album;
my $i;
- my @tracks;
- my $name;
- my $track;
- my $j;
+ my $various;
+ my $seen_various;
if (defined($device)) {
$mb = new MusicBrainz::Client::Simple (device=>$device);
die($mb->get_error);
}
- open(F, '>candidate-tags-0') or die("open('>candidate-tags-0'): $!");
- print(F "$_=\n") for ('ARTIST', 'ALBUM', 'DATE');
- print(F "TITLE=\n") for 1 .. $trackcount;
- close(F) or die("close('>candidate-tags-0'): $!");
+ tags_file('candidate-tags-0', $trackcount, 0);
for $album (@results) {
$i++;
- open(F, ">candidate-tags-$i") or die("open(>candidate-tags-$i): $!");
- print(F 'ARTIST=', $album->get_artist->get_name, "\n");
- print(F 'ALBUM=', $album->get_name, "\n");
-
- # MusicBrainz doesn't have dates yet; these are usually wrong anyway.
- print(F "DATE=\n");
-
- @tracks = $album->get_tracks;
- for $j (1 .. $trackcount) {
- if ($track = shift(@tracks)) {
- $name = $track->get_name;
- } else {
- $name = '';
+ if ($various = $album->has_various_artists) {
+ if (not $seen_various) {
+ $seen_various = 1;
+ tags_file('candidate-tags-0v', $trackcount, 1);
}
- print(F "TITLE=$name\n");
}
- close(F) or die("close(>candidate-tags-$i): $!");
+ tags_file("candidate-tags-$i", $trackcount, $various,
+ $album->get_artist->get_name, $album->get_name,
+ $album->get_tracks);
}
}
die;
}
+sub make_post_processor {
+ my $command = shift;
+
+ defined($command) or return;
+
+ sysopen(F, 'post-processor', O_CREAT | O_WRONLY, 0555)
+ or die("sysopen(post-processor, O_CREAT | O_WRONLY, 0555): $!");
+ print(F $command, ' "$@"', "\n");
+ close(F) or die("close(post-processor, O_CREAT | O_WRONLY, 0555): $!");
+}
+
MAIN: {
+ my $post_processor;
my $trackcount;
my $help;
my $tempdir;
GetOptions(
'device|d=s' => \$CDDEV,
+ 'post-processor|p=s', \$post_processor,
'tracks|t=i' => \$trackcount,
'help|h|?' => \$help,
) or pod2usage();
$tempdir = File::Temp::tempdir('flac-archive.XXXXXXXXXX');
chdir($tempdir) or die("chdir($tempdir): $!");
+ make_post_processor($post_processor);
$trackcount = mkcue($CDDEV, $trackcount);
tags($CDDEV, $trackcount);
rip($CDDEV, $trackcount);
Use I<device> as the CD-ROM device, instead of the default
"/dev/cdrom" or the environment variable CDDEV.
+=item B<-p> [B<--post-processor>] I<post-processor>
+
+Create a "post-processor" file in the temporary directory containing
+the line 'I<post-processor> "$@"'. See B<fa-flacd>'s man page for
+information about this hook.
+
=item B<-t> [B<--tracks>] I<track-count>
Archive only the first I<track-count> tracks. This is handy for