]> diplodocus.org Git - flac-archive/blobdiff - fa-flacd
hack out my ancient shitty util library
[flac-archive] / fa-flacd
index bef49542aef9d1aa945bf58f2af94ed5d087b1f4..8166b945b2845101bc9cd4e0ad8b0a9e0f1f2159 100755 (executable)
--- a/fa-flacd
+++ b/fa-flacd
@@ -1,6 +1,6 @@
-#! /usr/bin/env python2.4
+#! /usr/bin/python
 
 
-'''
+"""
 =head1 NAME
 
 B<fa-flacd> - archive CDs to single FLAC files
 =head1 NAME
 
 B<fa-flacd> - archive CDs to single FLAC files
@@ -74,7 +74,7 @@ it under the same terms as Perl itself.
 
 =cut
 
 
 =cut
 
-''' #' # python-mode is sucks
+"""
 
 import os
 import re
 
 import os
 import re
@@ -85,10 +85,19 @@ from errno import EEXIST, ENOENT
 from glob import glob
 from optparse import OptionParser
 
 from glob import glob
 from optparse import OptionParser
 
-import org.diplodocus.jobs
-from org.diplodocus.structures import ListDictDict
-from org.diplodocus.util import die, flatten, nothing
-from org.diplodocus.util import catch_EnvironmentError as c
+from flac_archive.tags import Tags
+
+def c(f, *args):
+    try:
+        return f(*args)
+    except EnvironmentError, error:
+        error.msg = '%s.%s(%s): ' % (f.__module__, f.__name__,
+                                     ', '.join(map(str, args)))
+        raise
+
+def die(e, *args):
+    sys.stderr.write(''.join(args))
+    sys.exit(e)
 
 def spew(*args):
     if verbose:
 
 def spew(*args):
     if verbose:
@@ -107,7 +116,8 @@ def run_flac(infile, cue, outfile, tags):
         argv.extend(['-T', i])
     argv.append(infile)
     # flac 1.1.3 PICTURE support
         argv.extend(['-T', i])
     argv.append(infile)
     # flac 1.1.3 PICTURE support
-    #argv.extend(['--picture', '3|image/jpeg|||cover.front'])
+    if os.path.exists('cover.front'):
+        argv.extend(['--picture', '3|image/jpeg|||cover.front'])
 
     spew('Running flac\n')
     status = os.spawnvp(os.P_WAIT, argv[0], argv)
 
     spew('Running flac\n')
     status = os.spawnvp(os.P_WAIT, argv[0], argv)
@@ -118,11 +128,18 @@ def run_flac(infile, cue, outfile, tags):
 
     c(os.rename, outfile + '.flac-tmp', outfile + '.flac')
 
 
     c(os.rename, outfile + '.flac-tmp', outfile + '.flac')
 
-def flac(dir, artist, album, discnum, tracknum, track_tags, disc_artist, tags):
-    '''Encode a single wav file to a single flac file, whether the wav and
-    flac files represent individual tracks or whole discs.'''
+def flac(dir, tracknum, tags):
+    """Encode a single wav file to a single flac file, whether the wav and
+    flac files represent individual tracks or whole discs."""
 
 
-    (artist, album) = [x.replace('/', '_') for x in (artist, album)]
+    separator = ' '
+    if len(tags.get('ALBUMARTIST')) > 0:
+        artist_tag = tags.gets('ALBUMARTIST', separator=', ')
+    else:
+        artist_tag = tags.gets('ARTIST', separator=', ')
+    artist = (artist_tag or '').replace('/', '_')
+    album = (tags.gets('ALBUM', separator=separator) or '').replace('/', '_')
+    discnum = tags.gets('DISCNUMBER')
 
     spew('mkdir(%s)\n' % (artist,))
     try:
 
     spew('mkdir(%s)\n' % (artist,))
     try:
@@ -145,36 +162,25 @@ def flac(dir, artist, album, discnum, tracknum, track_tags, disc_artist, tags):
         outfile = album
         if discnum != None:
             outfile = ''.join([discnum, ' ', outfile])
         outfile = album
         if discnum != None:
             outfile = ''.join([discnum, ' ', outfile])
-        run_flac('wav', 'cue', '/'.join(['..', artist, outfile]), tags)
+        run_flac('wav', 'cue', '/'.join(['..', artist, outfile]), tags.all())
         files = ['%s/%s.flac' % (artist, outfile)]
 
         c(os.unlink, 'cue')
         outlog = '/'.join(['..', artist, outfile + '.log'])
         c(os.rename, 'log', outlog)
     else:
         files = ['%s/%s.flac' % (artist, outfile)]
 
         c(os.unlink, 'cue')
         outlog = '/'.join(['..', artist, outfile + '.log'])
         c(os.rename, 'log', outlog)
     else:
-        title = []
-        for i in track_tags['TITLE']:
-            title.extend(i.split())
-        title = ' '.join(title).replace('/', '_')
+        title = tags.gets('TITLE', tracknum, separator).replace('/', '_')
         tmp = []
         if discnum != None:
             tmp.append('%02d' % (int(discnum),))
         tmp.extend(['%02d' % (tracknum,), title])
         tmp = []
         if discnum != None:
             tmp.append('%02d' % (int(discnum),))
         tmp.extend(['%02d' % (tracknum,), title])
+        part = tags.gets('PART', tracknum)
+        if part != None:
+            tmp.extend(['-', part])
         outfile = '/'.join([outdir, ' '.join(tmp)])
 
         outfile = '/'.join([outdir, ' '.join(tmp)])
 
-        tags = tags[:]
-        # If we have ARTIST[n] tags for this track, they'll go in with
-        # the other [n] tags.  Else, prepend disc_artist to tags.
-        if 'ARTIST' not in track_tags:
-            for i in disc_artist:
-                tags.insert(0, i)
-
-        tags.append('TRACKNUMBER=%d' % (tracknum,))
-        tags.extend(flatten([['='.join([key, x]) for x in track_tags[key]]
-                             for key in track_tags]))
-
         run_flac('track%02d.cdda.wav' % (tracknum,), None,
         run_flac('track%02d.cdda.wav' % (tracknum,), None,
-                 '../' + outfile, tags)
+                 '../' + outfile, tags.track(tracknum))
         outlog = ''.join(['../', outfile, '.log'])
         files = [outfile + '.flac']
 
         outlog = ''.join(['../', outfile, '.log'])
         files = [outfile + '.flac']
 
@@ -195,7 +201,10 @@ def flac(dir, artist, album, discnum, tracknum, track_tags, disc_artist, tags):
     ld = os.listdir(dir)
     if ld == ['using-tags'] or sorted(ld) == ['cover.front', 'using-tags']:
         try:
     ld = os.listdir(dir)
     if ld == ['using-tags'] or sorted(ld) == ['cover.front', 'using-tags']:
         try:
-            os.unlink(dir + '/cover.front')
+            try:
+                os.unlink(dir + '/cover.front')
+            except OSError:
+                pass
             os.unlink(dir + '/using-tags')
             os.rmdir(dir)
         except EnvironmentError:
             os.unlink(dir + '/using-tags')
             os.rmdir(dir)
         except EnvironmentError:
@@ -207,30 +216,18 @@ def flac(dir, artist, album, discnum, tracknum, track_tags, disc_artist, tags):
 # The master process
 
 def get_tags(fn):
 # The master process
 
 def get_tags(fn):
-    '''Return the ARTIST, ALBUM, and DATE followed by a list of all the
-    lines in the file FN.'''
-
-    artist = album = discnum = None
-    tags = []
+    """Return the ARTIST, ALBUM, and DATE followed by a list of all the
+    lines in the file FN."""
 
 
+    tags = Tags()
     spew('Opening tags file %s\n' % (fn,))
     spew('Opening tags file %s\n' % (fn,))
-    fp = file(fn)
-    for line in (x.rstrip() for x in fp):
-        tags.append(line)
+    tags.load(open(fn))
 
 
-        (tag, value) = line.split('=', 1)
+    spew('ARTIST %s from %s\n' % (tags.gets('ARTIST'), fn))
+    spew('ALBUM %s from %s\n' % (tags.gets('ALBUM'), fn))
+    spew('DISCNUMBER %s from %s\n' % (tags.gets('DISCNUMBER'), fn))
 
 
-        if re.match(r'ARTIST=', line, re.IGNORECASE):
-            artist = value
-            spew('ARTIST %s from %s\n' % (artist, fn))
-        elif re.match(r'ALBUM=', line, re.IGNORECASE):
-            album = value
-            spew('ALBUM %s from %s\n' % (album, fn))
-        elif re.match(r'DISCNUMBER=', line, re.IGNORECASE):
-            discnum = value
-            spew('DISCNUMBER %s from %s\n' % (discnum, fn))
-
-    return (artist, album, discnum, tags)
+    return tags
 
 def flacloop(maxjobs):
     dir = [None]       # [str] instead of str for lame python closures
 
 def flacloop(maxjobs):
     dir = [None]       # [str] instead of str for lame python closures
@@ -251,11 +248,10 @@ def flacloop(maxjobs):
                     spew("Renaming %s/tags\n" % (dir[0],))
                     c(os.rename, dir[0] + '/tags', dir[0] + '/using-tags')
 
                     spew("Renaming %s/tags\n" % (dir[0],))
                     c(os.rename, dir[0] + '/tags', dir[0] + '/using-tags')
 
-                    (artist, album, discnum, tags) = get_tags(dir[0] + '/using-tags')
+                    tags = get_tags(dir[0] + '/using-tags')
                     if os.path.exists(dir[0] + '/wav'):
                         # single-file
                     if os.path.exists(dir[0] + '/wav'):
                         # single-file
-                        jobs.append([dir[0], artist, album, discnum,
-                                     None, None, None, tags])
+                        jobs.append((dir[0], None, tags))
                     else:
                         # multi-file
                         # Don't need cue file.
                     else:
                         # multi-file
                         # Don't need cue file.
@@ -265,27 +261,8 @@ def flacloop(maxjobs):
                             if error.errno != ENOENT:
                                 raise error
 
                             if error.errno != ENOENT:
                                 raise error
 
-                        # Go over @tags, store all [n] tags in a list keyed by
-                        # n in %tracks_to_tags, store all ARTIST (not
-                        # ARTIST[n]) tags in @disc_artist, and leave the rest
-                        # in @tags.
-                        tracks_to_tags = ListDictDict()
-                        disc_artist = []
-                        tmp = []
-                        for tag in tags:
-                            m = re.match(r'([^[]+)\[(\d+)]=(.*)', tag)
-                            if m != None:
-                                tracks_to_tags.append(int(m.group(2)), m.group(1), m.group(3))
-                            elif re.match(r'ARTIST=', tag, re.IGNORECASE):
-                                disc_artist.append(tag)
-                            else:
-                                tmp.append(tag)
-                        tags = tmp
-
-                        jobs.extend([[dir[0], artist, album, discnum, x,
-                                      tracks_to_tags[x], disc_artist, tags]
-                                     for x in sorted(map(int,
-                                                         tracks_to_tags.keys()))])
+                        jobs.extend([(dir[0], x, tags)
+                                     for x in xrange(1, len(tags) + 1)])
                 except Exception, error:
                     sys.stderr.write(getattr(error, 'msg', ''))
                     traceback.print_exc()
                 except Exception, error:
                     sys.stderr.write(getattr(error, 'msg', ''))
                     traceback.print_exc()
@@ -302,8 +279,8 @@ def flacloop(maxjobs):
 
             def lamb():
                 log = '/'.join([job[0],
 
             def lamb():
                 log = '/'.join([job[0],
-                                job[4] == None and 'log' or str(job[4])
-                                + '.log'])
+                                job[1] == None and 'log'
+                                or str(job[1]) + '.log'])
                 try:
                     c(os.dup2, c(os.open, log, os.O_CREAT | os.O_WRONLY), 2)
                     return flac(*job)
                 try:
                     c(os.dup2, c(os.open, log, os.O_CREAT | os.O_WRONLY), 2)
                     return flac(*job)
@@ -313,11 +290,8 @@ def flacloop(maxjobs):
                     return 1
             return lamb
 
                     return 1
             return lamb
 
-    def notify_start(pid, jobs):
-        # make this print '2 jobs; start 378 for Artist/01 Title.flac'
-        spew('%d jobs; start %d for %s\n' % (len(jobs), pid, dir[0]))
-
-    def notify_finish(pid, status, jobs):
+    while True:
+        status = getjob(lambda *a,**k: None)()
         spew('%d jobs; %d finished (' % (len(jobs), pid))
         if os.WIFEXITED(status):
             spew('exited with status ', str(os.WEXITSTATUS(status)))
         spew('%d jobs; %d finished (' % (len(jobs), pid))
         if os.WIFEXITED(status):
             spew('exited with status ', str(os.WEXITSTATUS(status)))
@@ -327,12 +301,6 @@ def flacloop(maxjobs):
             spew('stopped with signal ', str(os.WSTOPSIG(status)))
         spew(')\n')
 
             spew('stopped with signal ', str(os.WSTOPSIG(status)))
         spew(')\n')
 
-    # Never returns (see getjob comment).
-    org.diplodocus.jobs.run(maxjobs=maxjobs, debug=debug,
-                            get_job=getjob,
-                            notify_start=notify_start,
-                            notify_finish=notify_finish)
-
 def main(argv):
     # Control the exit code for any uncaught exceptions.
     try:
 def main(argv):
     # Control the exit code for any uncaught exceptions.
     try: