#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2006  Jonas Häggqvist <rasher_AT_rasher_DOT_dk>
#
# This script will read replaygain information from APEv2 tags and write it
# to an ID3v2.4 tag. The information will be added ass both TXXX frames
# for compatibility with applications such as foobar and Rockbox, and to
# RVA2 frames, for standards compliance.
# If an ID3v2.3 tag exists, it will be converted to ID3v2.4 (this means
# among other things, that TYER will be converted to TDRC)
# The APEv2 tag will be removed, so any other info that might be there
# will be LOST.
#
# Known bugs: none yet, only basic testing has been done
#
# My use for this is to run the mp3gain utility and instruct it not to
# modify the file(s). This way, it will still write an APEv2 tag, which
# I can then convert to something less crazy with this script.
#
# Requirements: mutagen, which is a part of Quod Libet & Ex Falso.
# On Debian, apt-get instal python-mutagen works, other distros may be
# similar. Otherwise, you can find mutagen on the following URL:
# http://www.sacredchao.net/quodlibet/wiki/Development/Mutagen

import sys
import locale
import mutagen

def readape(file):
    from mutagen.apev2 import APEv2
    try: ape = APEv2(file)
    except mutagen.apev2.APENoHeaderError:
        ape = None
    return ape
    
def addrgid3(file, rg):
    from mutagen import id3
    if rg == None:
        return 0
    try: id3 = id3.ID3(file)
    except mutagen.id3.ID3NoHeaderError:
        print "No ID3 header found; creating a new tag"
        id3 = mutagen.id3.ID3()
    except Exception, err:
        print str(err)
        return 0 
    
    if 'REPLAYGAIN_ALBUM_GAIN' in rg:
        frame = mutagen.id3.Frames["TXXX"](encoding=3, desc="replaygain_album_gain", text=rg["REPLAYGAIN_ALBUM_GAIN"][0])
        id3.loaded_frame(frame)
        albumgain = float(rg["REPLAYGAIN_ALBUM_GAIN"][0].split(' ')[0])
        if 'REPLAYGAIN_ALBUM_PEAK' in rg:
            frame = mutagen.id3.Frames["TXXX"](encoding=3, desc="replaygain_album_peak", text=rg["REPLAYGAIN_ALBUM_PEAK"][0])
            id3.loaded_frame(frame)
            albumpeak = float(rg["REPLAYGAIN_ALBUM_PEAK"][0])
            frame = mutagen.id3.Frames["RVA2"](desc="album", channel=1, gain=albumgain, peak=albumpeak)
            id3.loaded_frame(frame)
        else:
            frame = mutagen.id3.Frames["RVA2"](desc="album", channel=1, gain=albumgain)
            id3.loaded_frame(frame)

    if 'REPLAYGAIN_TRACK_GAIN' in rg:
        frame = mutagen.id3.Frames["TXXX"](encoding=3, desc="replaygain_track_gain", text=rg["REPLAYGAIN_TRACK_GAIN"][0])
        id3.loaded_frame(frame)
        trackgain = float(rg["REPLAYGAIN_TRACK_GAIN"][0].split(' ')[0])
        if 'REPLAYGAIN_TRACK_PEAK' in rg:
            frame = mutagen.id3.Frames["TXXX"](encoding=3, desc="replaygain_track_peak", text=rg["REPLAYGAIN_TRACK_PEAK"][0])
            id3.loaded_frame(frame)
            trackpeak = float(rg["REPLAYGAIN_TRACK_PEAK"][0])
            frame = mutagen.id3.Frames["RVA2"](desc="track", channel=1, gain=trackgain, peak=trackpeak)
            id3.loaded_frame(frame)
        else:
            frame = mutagen.id3.Frames["RVA2"](desc="track", channel=1, gain=trackgain)
            id3.loaded_frame(frame)
        
    try: id3.save(file)
    except Exception, err:
        print str(err)
        return 0
    return 1
    
def removeape(file):
    mutagen.apev2.delete(file)
    
def main(argv):
    for file in argv:
        print "Processing %s" % file
        if addrgid3(file, readape(file)):
            removeape(file)

if __name__ == "__main__":
    main(sys.argv[1:])
