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