]> diplodocus.org Git - flac-archive/blobdiff - fa-flacd
s/ostream/iostream/; s/diag/file_diag/
[flac-archive] / fa-flacd
index 59b09c4ca47fba18a26155d06b8485f7e2d4e5bc..5e93e1f16965b7cb3f9bb1452b1e44324f925122 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
@@ -74,7 +74,7 @@ it under the same terms as Perl itself.
 
 =cut
 
-''' #' # python-mode is sucks
+"""
 
 import os
 import re
@@ -90,6 +90,8 @@ 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 spew(*args):
     if verbose:
         for i in args:
@@ -106,6 +108,9 @@ def run_flac(infile, cue, outfile, tags):
     for i in tags:
         argv.extend(['-T', i])
     argv.append(infile)
+    # flac 1.1.3 PICTURE support
+    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)
@@ -116,11 +121,18 @@ def run_flac(infile, cue, outfile, tags):
 
     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:
@@ -142,37 +154,26 @@ def flac(dir, artist, album, discnum, tracknum, track_tags, disc_artist, tags):
     if tracknum == None:
         outfile = album
         if discnum != None:
-            outfile = ''.join([outfile, ' (disc ', discnum, ')'])
-        run_flac('wav', 'cue', '/'.join(['..', artist, outfile]), tags)
+            outfile = ''.join([discnum, ' ', outfile])
+        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:
-        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])
+        part = tags.gets('PART', tracknum)
+        if part != None:
+            tmp.extend(['-', part])
         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,
-                 '../' + outfile, tags)
+                 '../' + outfile, tags.track(tracknum))
         outlog = ''.join(['../', outfile, '.log'])
         files = [outfile + '.flac']
 
@@ -190,8 +191,13 @@ def flac(dir, artist, album, discnum, tracknum, track_tags, disc_artist, tags):
     # Clean up if we're the last job for dir; for multi-file dirs,
     # it's possible for more than one job to run cleanup at once, so
     # don't fail if things are already clean.
-    if os.listdir(dir) == ['using-tags']:
+    ld = os.listdir(dir)
+    if ld == ['using-tags'] or sorted(ld) == ['cover.front', 'using-tags']:
         try:
+            try:
+                os.unlink(dir + '/cover.front')
+            except OSError:
+                pass
             os.unlink(dir + '/using-tags')
             os.rmdir(dir)
         except EnvironmentError:
@@ -203,30 +209,18 @@ def flac(dir, artist, album, discnum, tracknum, track_tags, disc_artist, tags):
 # 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,))
-    fp = file(fn)
-    for line in (x.rstrip() for x in fp):
-        tags.append(line)
-
-        (tag, value) = line.split('=', 1)
+    tags.load(open(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))
+    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))
 
-    return (artist, album, discnum, tags)
+    return tags
 
 def flacloop(maxjobs):
     dir = [None]       # [str] instead of str for lame python closures
@@ -247,11 +241,10 @@ def flacloop(maxjobs):
                     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
-                        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.
@@ -261,27 +254,8 @@ def flacloop(maxjobs):
                             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()
@@ -298,8 +272,8 @@ def flacloop(maxjobs):
 
             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)