]> diplodocus.org Git - flac-archive/commitdiff
Start on a script to help rewrite tags en masse.
author <epg@pretzelnet.org> <>
Wed, 26 Dec 2012 09:26:44 +0000 (01:26 -0800)
committer <epg@pretzelnet.org> <>
Wed, 26 Dec 2012 09:26:44 +0000 (01:26 -0800)
Seems I screw up every time I get a CD with non-ascii titles, and I'm tired of
hacking up a fix with interactive shell-scripting...

rewrite-tags [new file with mode: 0755]

diff --git a/rewrite-tags b/rewrite-tags
new file mode 100755 (executable)
index 0000000..a4650cf
--- /dev/null
@@ -0,0 +1,73 @@
+#! /usr/bin/python
+
+import sys
+from subprocess import Popen, PIPE
+
+from org.diplodocus.util import run_or_die
+
+from flac_archive.tags import Tags
+
+class SubprocessError(Exception):
+    def __init__(self, status, stderr=None):
+        if status < 0:
+            msg = 'exited due to signal %d'
+        else:
+            msg = 'exit status %d'
+        Exception.__init__(self, msg % (status,))
+        self.status = status
+        self.stderr = stderr
+
+def get_tags(fn):
+    tags = Tags()
+    p = Popen(['metaflac', '--no-utf8-convert', '--export-tags-to=-', fn],
+              stdout=PIPE)
+    tags.load(p.stdout)
+
+    status = p.wait()
+    if status != 0:
+        raise SubprocessError(status, p.stderr)
+
+    return tags
+
+def do_read(filenames):
+    # Use this mapping of tag names to sets of tag values to detect global tags.
+    all_tags = {}
+    # Build the collated result in this Tags object.
+    coll_tags = Tags()
+    for fn in filenames:
+        tags = get_tags(fn)
+        track_tags = tags.get('TRACKNUMBER')
+        if len(track_tags) != 1:
+            raise Exception('bogus TRACKNUMBER %s for %s' % (track_tags, fn))
+        track = int(track_tags[0])
+        for tag, values in tags._global.iteritems():
+            for value in values:
+                if tag in all_tags:
+                    all_tags[tag].add(value)
+                else:
+                    all_tags[tag] = set([value])
+                coll_tags.set(tag, value, track)
+    for tag, values in all_tags.iteritems():
+        if len(values) == 1:
+            # Only one value for this tag, so add it to global tags.
+            coll_tags.set(tag, list(values)[0])
+            # And now remove it from each track tags.
+            for track, tags in coll_tags._tracks.iteritems():
+                del tags[tag]
+    print '\n'.join(coll_tags.all())
+
+def main(args):
+    if len(args) < 3:
+        return usage()
+    if args[1] == 'read':
+        return do_read(args[2:])
+    if args[1] == 'write':
+        return do_write(args[2:])
+    return usage()
+
+def usage():
+    return 2
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
+