Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- import sys
- from optparse import OptionParser
- import mutagen
- from mutagen.apev2 import APEv2
- from mutagen.id3 import ID3, TXXX
- def convert_gain(gain):
- if gain[-3:] == " dB":
- gain = gain[:-3]
- try:
- gain = float(gain)
- except ValueError:
- raise ValueError, "invalid gain value"
- return "%.2f dB" % gain
- def convert_peak(peak):
- try:
- peak = float(peak)
- except ValueError:
- raise ValueError, "invalid peak value"
- return "%.6f" % peak
- REPLAYGAIN_TAGS = (
- ("replaygain_album_gain", convert_gain),
- ("replaygain_album_peak", convert_peak),
- ("replaygain_track_gain", convert_gain),
- ("replaygain_track_peak", convert_peak),
- )
- class Logger(object):
- def __init__(self, log_level, prog_name):
- self.log_level = log_level
- self.prog_name = prog_name
- self.filename = None
- def prefix(self, msg):
- if self.filename is None:
- return msg
- return "%s: %s" % (self.filename, msg)
- def debug(self, msg):
- if self.log_level >= 4:
- print self.prefix(msg)
- def info(self, msg):
- if self.log_level >= 3:
- print self.prefix(msg)
- def warning(self, msg):
- if self.log_level >= 2:
- print self.prefix("WARNING: %s" % msg)
- def error(self, msg):
- if self.log_level >= 1:
- sys.stderr.write("%s: %s\n" % (self.prog_name, msg))
- def critical(self, msg, retval=1):
- self.error(msg)
- sys.exit(retval)
- class Ape2Id3(object):
- def __init__(self, logger, force=False):
- self.log = logger
- self.force = force
- def convert_tag(self, name, value):
- pass
- def get_value(self, apev2, name):
- if apev2.has_key(name):
- return str(apev2[name])
- if apev2.has_key(name.upper()):
- return str(apev2[name.upper()])
- return None
- def copy_replaygain_tag(self, apev2, id3, name, converter=None):
- self.log.debug("processing '%s' tag" % name)
- if not self.force and id3.has_key("TXXX:%s" % name):
- self.log.info("ID3 '%s' tag already exists, skpping tag" % name)
- return False
- value = self.get_value(apev2, name)
- if value == None:
- self.log.warning("no APEv2 '%s' tag found, skipping tag" % name)
- return False
- if callable(converter):
- self.log.debug("converting APEv2 '%s' tag from '%s'" %
- (name, value))
- try:
- value = converter(value)
- except ValueError:
- self.log.warning("invalid value for APEv2 '%s' tag" % name)
- return False
- self.log.debug("converted APEv2 '%s' tag to '%s'" % (name, value))
- id3.add(TXXX(encoding=1, desc=name, text=value))
- self.log.info("added ID3 '%s' tag with value '%s'" % (name, value))
- return True
- def copy_replaygain_tags(self, filename):
- self.log.filename = filename
- self.log.debug("begin processing file")
- try:
- apev2 = APEv2(filename)
- except mutagen.apev2.error:
- self.log.info("no APEv2 tag found, skipping file")
- return
- except IOError:
- print "ioerror"
- e = sys.exc_info()
- self.log.error("%s" % e[1])
- return
- try:
- id3 = ID3(filename)
- except mutagen.id3.error:
- self.log.info("no ID3 tag found, creating one")
- id3 = ID3()
- modified = False
- for name, converter in REPLAYGAIN_TAGS:
- copied = self.copy_replaygain_tag(apev2, id3, name, converter)
- if copied:
- modified = True
- if modified:
- self.log.debug("saving modified ID3 tag")
- id3.save(filename)
- self.log.debug("done processing file")
- self.log.filename = None
- def main(prog_name, options, args):
- logger = Logger(options.log_level, prog_name)
- ape2id3 = Ape2Id3(logger, force=options.force)
- for filename in args:
- try:
- apev2 = APEv2(filename)
- for key in apev2.keys():
- print key, apev2[key]
- except mutagen.apev2.error:
- self.log.info("no APEv2 tag found, skipping file")
- return
- except IOError:
- print "ioerror"
- e = sys.exc_info()
- self.log.error("%s" % e[1])
- return
- ape2id3.copy_replaygain_tags(filename)
- if __name__ == "__main__":
- parser = OptionParser(version="0.1", usage="%prog [OPTION]... FILE...",
- description="Copy APEv2 ReplayGain tags on "
- "FILE(s) to ID3v2.")
- parser.add_option("-q", "--quiet", dest="log_level",
- action="store_const", const=0, default=1,
- help="do not output error messages")
- parser.add_option("-v", "--verbose", dest="log_level",
- action="store_const", const=3,
- help="output warnings and informational messages")
- parser.add_option("-d", "--debug", dest="log_level",
- action="store_const", const=4,
- help="output debug messages")
- parser.add_option("-f", "--force", dest="force",
- action="store_true", default=False,
- help="force overwriting of existing ID3v2 "
- "ReplayGain tags")
- prog_name = parser.get_prog_name()
- options, args = parser.parse_args()
- if len(args) < 1:
- parser.error("no files specified")
- try:
- main(prog_name, options, args)
- except KeyboardInterrupt:
- pass
- # vim: set expandtab shiftwidth=4 softtabstop=4 textwidth=79:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement