CD-rippaus ja freedb

moshe 20.01.06 17:08

Hakee CD:n biisilistan freedb.org:ista ja rippaa siltä biisit cdparanoian & lamen avulla

 Tekstiversio  Arvo: 5 (5 ääntä)  Äänestä: +  -
#!/usr/bin/python

import urllib
import re
import sys
import commands
import cddbid
import optparse

""" Convert audio CDs to mp3 files using cdparanoia & lame & freedb.
cdparanoia & lame must be correctly installed and within path.

Requires also cddbid.py. Get it from:
http://carey.geek.nz/code/python-cdrom/
"
""

def parse_options():
        """ Parse the program options using optparse and return
        (options, args)"
""
       
        parser = optparse.OptionParser()
        parser.add_option("--cdparanoia-args", dest="cdparanoia_args",
                help="command line arguments to be passed to cdparanoia",
                metavar="ARGS", default="")
        parser.add_option("--lame-args", dest="lame_args",
                help="command line arguments to be passed to lame",
                metavar="ARGS", default="")
        parser.add_option("-c", "--contents", dest="contents", action="store_true",
                help="return cd contents and exit")
        parser.add_option("-g", "--genre", dest="genre", default="rock",
                help="musical genre, for use in freedb (for example, rock)")
       
        return parser.parse_args()

def cdid():
        """ Calculate the id of CD in drive with cdparanoia"""
       
        # fetch CD contents with cdparanoia
        (status, output) = commands.getstatusoutput('cdparanoia -Q')
        if status:
                raise RuntimeError, "Failed to fetch TOC: \n%s" % output
               
        # strip unnecessary lines from it
        # (works at least with cdparanoia 9.8)
        lines = output.split("\n")[10:-1]
               
        # extract offsets from cdparanoia output
        # the +150 is because cdparanoia gives the offsets
        # from 150 and cddb from 0
        offsets = []
        for line in lines[:-1]:
                offset = int(re.findall(r'(\d*?) \[', line)[1]) + 150
                offsets.append(offset)
        offsets.append(int(re.findall(r'(\d*?) \[', lines[-1])[0]) + 150)
       
        # now calculate the final ID
        return cddbid.discid(offsets)[0]

def getinfo(genre, cdid):
        """ Fetch the album & track names from freedb.org,
        return (title, tracks)"
""
       
        title = ""
        tracks = []
       
        # get the definition file from freedb
        url = "http://freedb.org/freedb/%s/%s" % (genre, cdid)
        filelike = urllib.urlopen(url)
       
        # extract the track & title names
        for line in filelike:
                if "DTITLE" in line:
                        title = line.split("=")[1].rstrip("\n")
                if "TTITLE" in line:
                        tracks.append(line.split("=")[1].rstrip("\n"))
                if "404 Not Found" in line:
                        raise RuntimeError, "freedb entry not found."
       
        return title, tracks

def rip_n_convert(number, track, paranoia_args, lame_args):
        """ Do the actual work. Rip & convert a single track"""
       
        # pipe cdparanoia's output to lame's input
        status, output = commands.getstatusoutput(
                "cdparanoia %s %d - | lame - \"%02d - %s.mp3\" %s" %
                        (paranoia_args, number, number, track, lame_args))
        if status:
                raise RuntimeError, "Failed to rip/convert: \n%s" % output

def print_cdinfo(title, tracks):
        """ Print title and track names to stdout"""
       
        print "%s\n" % title
        for number, track in enumerate(tracks):
                print "%02d - %s" % (number + 1, track)

def main():
        """ Parse options, get cd info and print it or rip/convert cd"""
       
        (options, args) = parse_options()
        try:
                title, tracks = getinfo(options.genre, cdid())
                if options.contents:
                        print_cdinfo(title, tracks)
                else:
                        for number, track in enumerate(tracks):
                                rip_n_convert(number + 1, track,
                                options.cdparanoia_args, options.lame_args)
        except RuntimeError, message:
                print >> sys.stderr, message
                sys.exit(1)

if __name__=="__main__":
        main()