#!/usr/bin/env python

#***************************************************************************
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU General Public License as published by  *
#*   the Free Software Foundation; either version 2 of the License, or     *
#*   (at your option) any later version.                                   *
#*                                                                         *
#***************************************************************************

""" usage: m4b2ogg.py [options]

    -d  work with the provided directory
        [default: the current working directory]
    -h  this help
    -o  overwrite existins ogg files
    -r  remove the converted m4b files 

    This script goes through the provided path and all its
    subdirectories and converts all m4b files to ogg files.

    Written by Robert Penz <robert@penz.name>
"""

import sys
import os
import getopt
import subprocess

def convert(pathM4b, overwriteOggs, removeM4bs, workingDir = ""):
    pathOgg = os.path.splitext(pathM4b)[0] + ".ogg"
    if not overwriteOggs and os.path.exists(pathOgg):
        print "Info: %s already exists" % pathOgg[len(workingDir):]
        return
    print "converting: ",pathM4b[len(workingDir):]
    
    p1 = subprocess.Popen(["faad", "-q", "-o", "-", pathM4b], stdout=subprocess.PIPE)
    p2 = subprocess.Popen(["oggenc", "-Q", "-q6", "-", "-o", pathOgg], stdin=p1.stdout, stdout=subprocess.PIPE)
    output = p2.communicate()
    
    if output[0] or output[1]:
        print "error converting %s" % pathM4b[len(workingDir):]
        print output[0]
        print output[1]
        return
    else:
        if removeM4bs:
            os.unlink(pathM4b)
    
def convertRecursive(workingDir, overwriteOggs, removeM4bs):
    for root, dirs, files in os.walk(workingDir):
        for name in files:
            if os.path.splitext(name)[1].lower() == ".m4b":
                convert(os.path.join(root, name), overwriteOggs, removeM4bs, workingDir)

# Print usage message and exit
def usage(*args):
    sys.stdout = sys.stderr
    print __doc__
    print 50*"-"
    for msg in args: print msg
    sys.exit(2)

# Main program: parse command line and start processing
def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'd:hor')
    except getopt.error, msg:
        usage(msg)

    workingDir = os.getcwd()
    overwriteOggs = False
    removeM4bs = False

    for o, a in opts:
        if o == '-h':
            print __doc__
            sys.exit()
        if o == '-d':
            if os.path.isdir(a):
                workingDir = a
            else:
                print "Error: The provided path is no directory"
                sys.exit()
        if o == '-o':
            overwriteOggs = True
        if o == '-r':
            removeM4bs = True

    if workingDir[-1] != "/":
        workingDir += "/"
    convertRecursive(workingDir, overwriteOggs, removeM4bs)
            
if __name__ == '__main__':
    main()
