]> diplodocus.org Git - flac-archive/blob - rewrite-tags
make the do_write stub actually work (missing imports and typos)
[flac-archive] / rewrite-tags
1 #! /usr/bin/python
2
3 import os, sys
4 from errno import EEXIST
5 from subprocess import Popen, PIPE
6
7 from flac_archive.tags import Tags
8
9 class SubprocessError(Exception):
10 def __init__(self, status, command=None, stderr=None):
11 if command is None:
12 command_msg = None
13 else:
14 command_msg = ': ' + ' '.join(command)
15 if status < 0:
16 msg = 'exited due to signal %d%s'
17 else:
18 msg = 'exit status %d%s'
19 Exception.__init__(self, msg % (abs(status), command_msg))
20 self.status = status
21 self.command = command
22 self.stderr = stderr
23
24 def get_tags(fn):
25 tags = Tags()
26
27 command = ['metaflac', '--no-utf8-convert', '--export-tags-to=-', fn]
28 p = Popen(command, stdout=PIPE)
29 tags.load(p.stdout)
30
31 status = p.wait()
32 if status != 0:
33 raise SubprocessError(status, command=command, stderr=p.stderr)
34
35 return tags
36
37 def do_read(filenames):
38 # Use this mapping of tag names to sets of tag values to detect global tags.
39 all_tags = {}
40 # Build the collated result in this Tags object.
41 coll_tags = Tags()
42 # XXX The Tags interface is horrible. It's gotta be almost 10 years since
43 # I wrote it, so not surprising...
44 for fn in filenames:
45 tags = get_tags(fn)
46 track_tags = tags.get('TRACKNUMBER')
47 # this check belongs in Tags
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 # Makes no sense to save TRACKNUMBER in coll_tags.
54 if tag == 'TRACKNUMBER':
55 continue
56 for value in values:
57 if tag in all_tags:
58 all_tags[tag].add(value)
59 else:
60 all_tags[tag] = set([value])
61 coll_tags.set(tag, value, track)
62 for tag, values in all_tags.iteritems():
63 if len(values) == 1:
64 # Only one value for this tag, so add it to global tags.
65 coll_tags.set(tag, list(values)[0])
66 # And now remove it from each track tags.
67 for track, tags in coll_tags._tracks.iteritems():
68 del tags[tag]
69 print '\n'.join(coll_tags.all())
70 return 0
71
72 def do_write(args):
73 tags = Tags()
74 tags.load(open(args.pop(0)))
75 if len(args) != len(tags):
76 sys.stderr.write('expected %d flac files, got %d\n'
77 % (len(tags), len(args)))
78 return 4
79 artist = tags.get_path_safe('ARTIST')
80 album = tags.get_path_safe('ALBUM')
81 try:
82 os.mkdir(artist)
83 except OSError, e:
84 if e.errno != EEXIST:
85 raise
86 album_path = artist + '/' + album
87 try:
88 os.mkdir(album_path)
89 except OSError, e:
90 if e.errno != EEXIST:
91 raise
92 for i, old_fn in enumerate(args):
93 track = i + 1
94 fn = '%s/%s/%s.flac' % (artist, album, tags.make_filename(track))
95 if fn != old_fn:
96 print tags.track(track)
97 #os.rename(old_fn, fn)
98
99 def main(args):
100 if len(args) < 3:
101 return usage()
102 if args[1] == 'read':
103 return do_read(args[2:])
104 if args[1] == 'write':
105 return do_write(args[2:])
106 return usage()
107
108 def usage():
109 return 2
110
111 if __name__ == '__main__':
112 sys.exit(main(sys.argv))
113