]> diplodocus.org Git - flac-archive/commitdiff
Collapse fa-rip and fa-tags into a single Perl program, fa-rip.
authorepg <>
Wed, 27 Oct 2004 04:54:16 +0000 (04:54 +0000)
committerepg <>
Wed, 27 Oct 2004 04:54:16 +0000 (04:54 +0000)
Fix up the documentation.

GNUmakefile
README
fa-flacd
fa-rip
fa-tags [deleted file]

index beeb953..4eddf3d 100644 (file)
@@ -19,11 +19,11 @@ ROFF=               nroff -Tascii -mandoc
 SCRIPTS=\
        fa-flacd \
        fa-rip \
-       fa-tags \
        flac2mp3 \
 
 MAN=\
        fa-flacd.1 fa-flacd.0 \
+       fa-rip.1 fa-rip.0 \
        flac2mp3.1 flac2mp3.0 \
 
 all: ${SCRIPTS} ${MAN}
@@ -51,12 +51,6 @@ ${DESTDIR}${man1dir}/%: % ${DESTDIR}${man1dir}
 ${DESTDIR}${cat1dir}/%: % ${DESTDIR}${cat1dir}
        ${INSTALL_DATA} $< $@
 
-${DESTDIR}${man1dir}/fa-rip.1 ${DESTDIR}${man1dir}/fa-tags.1:
-       ln -sf fa-flacd.1 $@
-
-${DESTDIR}${cat1dir}/fa-rip.0 ${DESTDIR}${cat1dir}/fa-tags.0:
-       ln -sf fa-flacd.0 $@
-
 ${DESTDIR}${bindir}:
        ${INSTALL_DIRECTORY} $@
 
diff --git a/README b/README
index ebdadea..953a17d 100644 (file)
--- a/README
+++ b/README
@@ -6,10 +6,7 @@ flac-archive requires:
 
    Perl >= 5.6
    MusicBrainz::Client
-   zsh >= 4.0, ksh93, or bash
    cdparanoia
    mkcue (http://diplodocus.org/projects/audio/)
-   mktemp -d (non-standard, but available on NetBSD, Mac OS X,
-       GNU/Linux, and probably just about everywhere else)
 
 flac2mp3 additionally requires lame.
index 5f3ab7f..2cc1210 100755 (executable)
--- a/fa-flacd
+++ b/fa-flacd
@@ -4,16 +4,12 @@
 
 =head1 NAME
 
-B<fa-flacd>, B<fa-rip>, B<fa-tags> - archive CDs to single FLAC files
+B<fa-flacd> - archive CDs to single FLAC files
 
 =head1 SYNOPSIS
 
 B<fa-flacd> [B<-jv>]
 
-B<fa-rip> [B<-d> I<device>] [B<-t> I<track-count>]
-
-B<fa-tags> I<track-count>
-
 =cut
 
 use strict;
@@ -212,29 +208,23 @@ __END__
 
 =head1 DESCRIPTION
 
-B<fa-flacd>, B<fa-rip>, and B<fa-tags> together comprise
-B<flac-archive>, a system for archiving audio CDs to single FLAC
-files.  B<fa-flacd> is the guts of the system.  It runs in the
-directory where the audio archives are stored, scanning for new CDs to
-encode and rename; it never exits.  B<fa-rip> generates the inputs for
-B<fa-flacd>: the ripped WAV file, Vorbis tags, and a cuesheet.
-B<fa-tags> is not meant to be run directly; B<fa-rip> uses it to
-generate the candidate Vorbis tags.
-
-All three programs expect to be run from the same directory.  They use
-that directory to manage directories named by artist and by disc ID.
-Intermediate files are written to the disc ID directory.  B<fa-flacd>
-processes the disc ID directories into per-album files in the artist
-directories.
-
-=head2 FA-FLACD
-
-B<fa-flacd> does not exit; it runs until the user kills it.  Every 5
-seconds it scans its current directory for directories with a file
-called "tags" and creates a processing job for each one.  The number
-of jobs B<fa-flacd> attempts to run is controlled by the B<-j> option
-and defaults to 4.  B<fa-flacd> will print diagnostic output when the
-B<-v> option is given.
+B<fa-flacd> and B<fa-rip> together comprise B<flac-archive>, a system
+for archiving audio CDs to single FLAC files.  B<fa-flacd> is the guts
+of the system.  It runs in the directory where the audio archives are
+stored, scanning for new ripped CDs to encode and rename; it never
+exits.  B<fa-rip> generates the inputs for B<fa-flacd>: the ripped WAV
+file, Vorbis tags, and a cuesheet.
+
+Both programs expect to be run from the same directory.  They use that
+directory to manage directories named by artist.  Intermediate files
+are written to temporary directories here.  B<fa-flacd> processes the
+temporary directories into per-album files in the artist directories.
+
+Every 5 seconds, B<fa-flacd> scans its current directory for
+directories with a file called "tags" and creates a processing job for
+each one.  The number of jobs B<fa-flacd> attempts to run is
+controlled by the B<-j> option and defaults to 4.  B<fa-flacd> will
+print diagnostic output when the B<-v> option is given.
 
 A processing job first renames the directory's "tags" file to
 "using-tags" so that B<ra-flacd> will not try to start another job for
@@ -243,49 +233,9 @@ so a new job will not be started until the user corrects the error
 condition and renames "using-tags" back to "tags".  Next, it encodes
 the "wav" file to a FLAC file, using the "cue" file for the cuesheet
 and "using-tags" for Vorbis tags.  Any diagnostic output is saved in
-the "log" file.  Finally, the "cue" and "log" files are moved to the
-artist directory (and named by album) and the ID directory is removed.
-
-=head2 FA-RIP
-
-B<fa-rip> uses C<mktemp(1)> to create a directory for storage of its
-intermediate files.  It uses C<mkcue(1)> to create the "cue" file and
-then passes the number of tracks (from the "cue" file) as command-line
-arguments to B<fa-tags>.
-
-If B<-t> I<track-count> is specified, that number is used instead of
-counting tracks in the "cue" file, and is also passed to C<mkcue(1)>
-to ensure that only that number of tracks is listed in the "cue" file.
-This is handy if the CD has stupid data tracks.
-
-Finally, it execs C<cdparanoia(1)> to rip the CD to the "wav" file.
-
-In order for this CD to be processed by B<fa-flacd>, the user must
-create a "tags" file.  This is usually done by renaming one of the
-candidate-tags files and deleting the others.
-
-=head2 FA-TAGS
-
-B<fa-tags> uses C<MusicBrainz::Client> to populate candidate-tags
-files.  These are numbered in the order of entries read from
-MusicBrainz, e.g. candidate-tags-1, candidate-tags-2, etc.  B<fa-tags>
-also creates candidate-tags-0, which has the correct fields for this
-CD (including correct number of TITLE= lines), but with all fields
-blank.
-
-B<fa-tags> requires the number of tracks as its sole argument.
-
-=head1 ENVIRONMENT
-
-=over 4
-
-=item CDDEV
-
-B<fa-rip> uses this to rip audio and save the cuesheet for a CD.  It
-makes some effort to check some common device names for FreeBSD,
-Linux, and NetBSD by default.
-
-=back
+the "log" file.  Finally, B<fa-flacd> moves the "cue" and "log" files
+to the artist directory (named by album) and removes the temporary
+directory.
 
 =head1 AUTHORS
 
diff --git a/fa-rip b/fa-rip
index 4755822..252c2b5 100755 (executable)
--- a/fa-rip
+++ b/fa-rip
-#! /usr/bin/env zsh
+#! /usr/bin/env perl
 
 # $Id$
+# $URL$
 
-set -e
+=head1 NAME
 
-function get_cddev {
-    typeset raw
-    raw=$(sysctl -n kern.rawpartition > /dev/null | awk '{printf "%c",97+$0}')
+B<fa-rip> - rip a CD for B<fa-flacd>
 
-    if [[ -n ${ZSH_VERSION} ]]; then
-        setopt NULL_GLOB
-    fi
+=head1 SYNOPSIS
 
-    for CDDEV in /dev/{cdroms/cdrom*,cdrom*,rcd*${raw},{a,}cd*c}; do
-        [[ -e ${CDDEV} ]] && return 0
-    done
+B<fa-rip> [B<-d> I<device>] [B<-t> I<track-count>]
 
-    return 1
+=cut
+
+use strict;
+use warnings;
+
+use Env qw(
+           CDDEV
+);
+
+use File::Temp;
+use Getopt::Long;
+use POSIX ':sys_wait_h';
+use Pod::Usage;
+
+use MusicBrainz::Client::Simple;
+
+sub run_or_die {
+    my $command = shift;
+    my $status;
+
+    system($command);
+
+    if (WIFEXITED($?)) {
+        $status = WEXITSTATUS($?);
+        if ($status != 0) {
+            die("$command exited $status");
+        }
+
+    } elsif (WIFSIGNALED($?)) {
+        $status = WTERMSIG($?);
+        die("$command signalled $status");
+
+    } elsif (WIFSTOPPED($?)) {
+        $status = WSTOPSIG($?);
+        die("$command stopped $status");
+
+    } else {
+        die("Major horkage on system($command): \$? = $? \$! = $!");
+    }
+}
+
+sub mkcue {
+    my $device = shift;
+    my $trackcount = shift;
+    my @command;
+
+    push(@command, 'mkcue');
+
+    if (defined($trackcount)) {
+        push(@command, "-t $trackcount");
+    }
+
+    if (defined($device)) {
+        push(@command, $device);
+    }
+
+    push(@command, '> cue');
+    run_or_die(join(' ', @command));
+
+    if (not defined($trackcount)) {
+        open(F, 'cue') or die("open(cue): $!");
+        $trackcount = grep(/TRACK.*AUDIO/, <F>);
+        close(F);
+    }
+
+    return $trackcount;
+}
+
+sub tags {
+    my $device = shift;
+    my $trackcount = shift;
+    my $mb;
+    my @results;
+    my $album;
+    my $i;
+    my @tracks;
+    my $name;
+    my $track;
+    my $j;
+
+    if (defined($device)) {
+        $mb = new MusicBrainz::Client::Simple (device=>$device);
+    } else {
+        $mb = new MusicBrainz::Client::Simple;
+    }
+
+    @results = $mb->lookup_cd;
+    if (not $mb->success) {
+        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'): $!");
+
+    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 = '';
+            }
+            print(F "TITLE=$name\n");
+        }
+
+        close(F) or die("close(>candidate-tags-$i): $!");
+    }
+}
+
+sub rip {
+    my $device = shift;
+    my $trackcount = shift;
+
+    $device ||= '/dev/cdrom';
+
+    print"$_\n" for ('cdparanoia', '-d', $device, "1-$trackcount", 'wav');
+    exec('cdparanoia', '-d', $device, "1-$trackcount", 'wav');
+    # exec prints its own error message so just
+    die;
+}
+
+MAIN: {
+    my $trackcount;
+    my $help;
+    my $tempdir;
+
+    GetOptions(
+               'device|d=s' => \$CDDEV,
+               'tracks|t=i' => \$trackcount,
+               'help|h|?' => \$help,
+              ) or pod2usage();
+    $help and pod2usage(-exitstatus=>0, -verbose=>1);
+
+    # File::Temp::tempdir calls die on error.
+    $tempdir = File::Temp::tempdir('flac-archive.XXXXXXXXXX');
+    chdir($tempdir) or die("chdir($tempdir): $!");
+
+    $trackcount = mkcue($CDDEV, $trackcount);
+    tags($CDDEV, $trackcount);
+    rip($CDDEV, $trackcount);
 }
 
-trackcount=
-while getopts 'd:t:' ch; do
-    case ${ch} in
-        d)
-            CDDEV=${OPTARG}
-            export CDDEV
-            ;;
-        t)
-            trackcount=${OPTARG}
-            ;;
-        ?)
-            echo 'fa-rip [-t track-count]' >&2
-            exit 2
-            ;;
-    esac
-done
-shift $((${OPTIND} - 1))
-
-if [[ -z ${CDDEV} ]]; then
-    if ! get_cddev; then
-        echo 'CDDEV environment variable not set, defaults did not work' >&2
-        exit 2
-    fi
-    export CDDEV
-fi
-
-dir=$(mktemp -d flac-archive.XXXXXXXXXX)
-cd ${dir}
-
-if [[ -z ${trackcount} ]]; then
-    mkcue ${CDDEV} > cue
-    trackcount=$(grep -c 'TRACK.*AUDIO' cue)
-else
-    mkcue -t ${trackcount} ${CDDEV} > cue
-fi
-
-fa-tags ${trackcount}
-
-exec cdparanoia -d ${CDDEV} 1-${trackcount} wav
+\f
+__END__
+
+=head1 DESCRIPTION
+
+B<fa-rip> creates a temporary directory for storage of its
+intermediate files, runs C<mkcue(1)> to create the "cue" file, uses
+MusicBrainz to generate candidate tags files, and runs
+C<cdparanoia(1)> to rip the CD to the "wav" file.
+
+In order for this CD to be processed by B<fa-flacd>, you must create a
+"tags" file.  This is usually done by renaming one of the
+candidate-tags files and deleting the others.  Don't forget to fill in
+the DATE tag in the selected candidate before renaming it.  If
+B<fa-rip> could not find any tag information from MusicBrainz, you'll
+have to fill out the candidate-tags-0 template.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-d> [B<--device>] I<device>
+
+Use I<device> as the CD-ROM device, instead of the default
+"/dev/cdrom" or the environment variable CDDEV.
+
+=item B<-t> [B<--tracks>] I<track-count>
+
+Archive only the first I<track-count> tracks.  This is handy for
+ignoring data tracks.
+
+=back
+
+=head1 ENVIRONMENT
+
+=over 4
+
+=item CDDEV
+
+B<fa-rip> uses this to rip audio and save the cuesheet for a CD.  It
+makes some effort to check some common device names for FreeBSD,
+Linux, and NetBSD by default.
+
+=back
+
+=head1 AUTHORS
+
+Written by Eric Gillespie <epg@pretzelnet.org>.
+
+flac-archive is free software; you may redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+# Local variables:
+# cperl-indent-level: 4
+# perl-indent-level: 4
+# indent-tabs-mode: nil
+# End:
+
+# vi: set tabstop=4 expandtab:
diff --git a/fa-tags b/fa-tags
deleted file mode 100755 (executable)
index 7d023ec..0000000
--- a/fa-tags
+++ /dev/null
@@ -1,66 +0,0 @@
-#! /usr/bin/env perl
-
-# $Id$
-
-# See fa-flacd for documentation.
-
-use strict;
-use warnings;
-
-use Env qw(
-           CDDEV
-);
-
-use Getopt::Long;
-use Pod::Usage;
-
-use MusicBrainz::Client::Simple;
-
-my $help;
-GetOptions(
-           'help|h|?' => \$help,
-          ) or pod2usage();
-$help and pod2usage(-exitstatus=>0, -verbose=>1);
-
-my $trackcount = shift or pod2usage();
-
-my $mb;
-if (defined($CDDEV)) {
-    $mb = new MusicBrainz::Client::Simple (device=>$CDDEV);
-} else {
-    $mb = new MusicBrainz::Client::Simple;
-}
-
-my @result = $mb->lookup_cd;
-die($mb->get_error) unless $mb->success;
-
-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'): $!");
-
-my $i;
-for my $album (@result) {
-    $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");
-
-    my @tracks = $album->get_tracks;
-    my $name;
-    my $track;
-    for my $j (1 .. $trackcount) {
-        if ($track = shift(@tracks)) {
-            $name = $track->get_name;
-        } else {
-            $name = '';
-        }
-        print(F "TITLE=$name\n");
-    }
-
-    close(F) or die("close('>candidate-tags-$i'): $!");
-}