def flac2mp3(fn, title, artist, album, date, track, skip_until):
(title, artist, album, date) = [(x == None and 'unknown') or x
for x in (title, artist, album, date)]
- track = int(track) # XXX caller should int this
try:
(skip_arg, until_arg) = skip_until
except ValueError:
return args
+# XXX other things should usue this; flac files, for example, should
+# get PART as part of the filelname, same as mp3s.
+class Tags(object):
+ def __init__(self):
+ self._tags = {}
+ def __len__(self):
+ return len(self._tags)
+ def get(self, key, track=None):
+ key = key.upper()
+ try:
+ if track == None:
+ return self._tags[None][key]
+ try:
+ return self._tags[track][key]
+ except KeyError:
+ return self._tags[None][key]
+ except KeyError:
+ return None
+ def gets(self, key, track=None):
+ value = self.get(key, track)
+ if value == None:
+ return None
+ return '\n'.join(value)
+ def set(self, key, value, track=None):
+ if track not in self._tags:
+ self._tags[track] = {}
+ if key not in self._tags[track]:
+ self._tags[track][key] = []
+ self._tags[track][key].append(value)
+
def get_tags(fn):
'''Return the ARTIST, ALBUM, and DATE tags followed by the TITLE tags
in the file FN.'''
- date = discnum = track = None
- artists = []
- titles = []
+ tags = Tags()
p = Popen(['metaflac', '--export-vc-to=-', fn], stdout=PIPE)
for line in (x.rstrip() for x in p.stdout):
(tag, value) = line.split('=', 1)
- if re.match(r'ARTIST=', line, re.IGNORECASE):
- artist = value
- elif re.match(r'ALBUM=', line, re.IGNORECASE):
- album = value
- elif re.match(r'DATE=', line, re.IGNORECASE):
- date = value
- elif re.match(r'DISCNUMBER=', line, re.IGNORECASE):
- discnum = value
- elif re.match(r'TRACKNUMBER=', line, re.IGNORECASE):
- track = value
-
- # XXX Need to support per-track of everything but album and
- # discnum, not just TITLE... Also unify with fa-flacd get_tags.
- elif re.match(r'ARTIST\[', line, re.IGNORECASE):
- artists.append(value)
- elif re.match(r'TITLE', line, re.IGNORECASE):
- titles.append(value)
+ m = re.search(r'\[([0-9]+)]$', tag)
+ if m != None:
+ tag = tag[:m.start()]
+ track = int(m.group(1))
+ else:
+ track = None
+
+ tags.set(tag, value, track)
# XXX dataloss! check status
status = p.wait()
- # If no TITLEs, stick a dummy in here.
- if len(titles) == 0:
- titles.append(None)
-
- return (artist, album, date, discnum, track, artists, titles)
+ return tags
def main(argv):
# Control the exit code for any uncaught exceptions.
for fn in args:
try:
args = get_decode_args(fn)
- (artist, album, date, discnum, track,
- artists, titles) = get_tags(fn)
+
+ tags = get_tags(fn)
+ album = tags.gets('ALBUM')
+ discnum = tags.gets('DISCNUMBER')
+ track = tags.gets('TRACKNUMBER')
# lame doesn't seem to support disc number.
if discnum != None:
- album = '%s (disc %d)' % (album, discnum)
+ album = '%s (disc %s)' % (album, discnum)
# Stupid hack: only a single-track file should have the
# TRACKNUMBER tag, so use it if set for the first pass through
# next run, so this continues to work for multi-track files.
if track == None:
track = 1
-
- for i in range(len(titles)):
- if len(artists) > 0:
- artist = artists[i]
- jobs.append([fn, titles[i], artist, album,
- date, track, args[i]])
+ else:
+ track = int(track)
+
+ for i in range(len(tags)):
+ title = tags.gets('TITLE', track)
+ part = tags.gets('PART', track)
+ if part != None:
+ title = '%s - %s' % (title, part)
+ jobs.append([fn, title,
+ tags.gets('ARTIST', track),
+ album,
+ tags.gets('DATE', track),
+ track, args[i]])
track = i + 2
except Exception, error:
sys.stderr.write(getattr(error, 'msg', ''))