]> diplodocus.org Git - flac-archive/blob - rewrite-tags
Oops, abs(status) in SubprocessError.
[flac-archive] / rewrite-tags
1 #! /usr/bin/python
2
3 import sys
4 from subprocess import Popen, PIPE
5
6 from org.diplodocus.util import run_or_die
7
8 from flac_archive.tags import Tags
9
10 class SubprocessError(Exception):
11 def __init__(self, status, stderr=None):
12 if status < 0:
13 msg = 'exited due to signal %d'
14 else:
15 msg = 'exit status %d'
16 Exception.__init__(self, msg % (abs(status),))
17 self.status = status
18 self.stderr = stderr
19
20 def get_tags(fn):
21 tags = Tags()
22 p = Popen(['metaflac', '--no-utf8-convert', '--export-tags-to=-', fn],
23 stdout=PIPE)
24 tags.load(p.stdout)
25
26 status = p.wait()
27 if status != 0:
28 raise SubprocessError(status, p.stderr)
29
30 return tags
31
32 def do_read(filenames):
33 # Use this mapping of tag names to sets of tag values to detect global tags.
34 all_tags = {}
35 # Build the collated result in this Tags object.
36 coll_tags = Tags()
37 # XXX The Tags interface is horrible. It's gotta be almost 10 years since
38 # I wrote it, so not surprising...
39 for fn in filenames:
40 tags = get_tags(fn)
41 track_tags = tags.get('TRACKNUMBER')
42 if len(track_tags) != 1:
43 raise Exception('bogus TRACKNUMBER %s for %s' % (track_tags, fn))
44 track = int(track_tags[0])
45 for tag, values in tags._global.iteritems():
46 for value in values:
47 if tag in all_tags:
48 all_tags[tag].add(value)
49 else:
50 all_tags[tag] = set([value])
51 coll_tags.set(tag, value, track)
52 for tag, values in all_tags.iteritems():
53 if len(values) == 1:
54 # Only one value for this tag, so add it to global tags.
55 coll_tags.set(tag, list(values)[0])
56 # And now remove it from each track tags.
57 for track, tags in coll_tags._tracks.iteritems():
58 del tags[tag]
59 print '\n'.join(coll_tags.all())
60
61 def main(args):
62 if len(args) < 3:
63 return usage()
64 if args[1] == 'read':
65 return do_read(args[2:])
66 if args[1] == 'write':
67 return do_write(args[2:])
68 return usage()
69
70 def usage():
71 return 2
72
73 if __name__ == '__main__':
74 sys.exit(main(sys.argv))
75