#!/usr/bin/python # coding=utf-8 ''' rip2ogg (c) 2007-2008, IƱaki Silanes LICENSE This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (version 2), as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details (http://www.gnu.org/licenses/gpl.txt). DESCRIPTION It rips a CD (after querying FreeDB) into OGG, in a format suitable for my music collection. USAGE Insert CD and execute: % rip2ogg.py This generates a file "rip2ogg.txt" with data of the CD. You can manually edit this file, if you wish. Then, execute: % rip2ogg.py again, to use info in rip2ogg.txt to rip and encode tracks from CD. VERSION svn_revision = r4 (2008-02-13 00:08:48) ''' import sys import re import os import optparse import CDDB import DiscID as D import System as S import DataManipulation as DM import FileManipulation as FM # Read arguments: parser = optparse.OptionParser() parser.add_option("-d", "--device", dest="device", help="device CD is at (default=/dev/cdrom)", metavar="DEV", default='/dev/cdrom') parser.add_option("-q", "--quality", dest="quality", help="quality of output Ogg file (default=6)", metavar="Q", default='6') (o,args) = parser.parse_args() def read_cd(device='/dev/cdrom'): ''' Returns cd_id to query FreeDB with it. ''' cd = D.open(device) cd_id = D.disc_id(cd) cd.close() return cd_id def query_cddb(id=None): ''' Uses cd_id to query FreeDB. Returns category and disc_id ''' if id == None: sys.exit('query_cddb: I need a CD id number!') (status, info) = CDDB.query(id) if status == 210 or status == 211: # multiple results: just pick first info = info[0] elif status != 200: sys.exit('Error: exit status of CDDB query was '+str(status)) return info['category'],info['disc_id'] def read_cddb(cat=None, id=None): ''' Uses category and disc_id to read FreeDB info. Returns info dictionary. ''' if cat == None or id == None: sys.exit('read_cddb: I need a category and a disc_id as input!') (status, info) = CDDB.read(cat,id) return info # Info file: dorip = 0 ifile = 'rip2ogg.txt' if os.path.exists(ifile): dorip = 1 print '\n#' print '# Warning: '+ifile+' already exists! (this is probably what you want)' print '#\n' resp = raw_input('Rip CD according to it? (Y/n): ') if resp == 'n': sys.exit('\nQuitting, as prompted by user...') # Rip or get info (depending on above): if dorip == 0: # Read info in CD: print "Reading CD info..." cd_id = read_cd(o.device) # Query DB: print "Querying FreeDB database..." cat,id = query_cddb(cd_id) # Get info: print "Getting info for CD from FreeDB..." info = read_cddb(cat,id) # Build data string: string = 'CDTITLE: ' try: (a,t) = info['DTITLE'].split(' / ') string += t+'\nARTIST: '+a except: string += 'unknown' string += '\nYEAR: ' try: string += info['DYEAR'] except: string += 'unknown' string += '\nGENRE: ' try: string += info['DGENRE'] except: string += 'unknown' string += '\nTRACKS:\n' track = 0 while 1: try: nn = "%02i " % (track+1) nn += DM.mk_proper_utf(info['TTITLE'+str(track)]) string += nn+'\n' track += 1 except: break # Print data: print "\nThe following info found (and written to file):\n" print string # Save to file: FM.w2file(ifile,string) # Closing notification: print 'The above info was written to file '+ifile print 'Open it, and modify to your heart\'s content.' print 'Then, run rip2ogg.py again to actually rip the CD' else: print "\nRipping the whole CD..." if os.path.exists('tmp'): print 'Dir "tmp" already exists. Skipping ripping of CD...' else: os.mkdir('tmp'); S.cli("cd tmp/ && icedax -x -s -D "+ o.device +" -B") print "\nEncoding the WAVs..." album = 'unknown' artist = 'unknown' tt = 0 f = open(ifile,'r') for l in f.readlines(): ll = l.split() if ll[0] == 'CDTITLE:': album = ' '.join(ll[1:]) elif ll[0] == 'ARTIST:': artist = ' '.join(ll[1:]) elif ll[0] == 'GENRE:': genre = ' '.join(ll[1:]) elif ll[0] == 'YEAR:': year = ll[1] elif ll[0] == 'TRACKS:': tt = 1 elif tt == 1: tnum = ll[0] # Fix track name for ID3 tag: tname = ' '.join(ll[1:]) tname = re.sub('"','\'',tname) # convert double quotes in track names to single quotes # Fix track name for filename: ptname = DM.mk_proper_fn(tname) oggname = "%s-%s.ogg" % (tnum,ptname) # Fix album name for dirname: palbum = DM.mk_proper_fn(album) outdir = year+'-'+palbum if not os.path.exists(outdir): os.mkdir(outdir) if not os.path.exists(outdir+'/'+oggname): command = "oggenc tmp/audio_%s.wav -q %s -o %s/%s -l '%s' -a '%s' -d %s -G '%s' -t \"%s\" -N %s" % (tnum,o.quality,outdir,oggname,album,artist,year,genre,tname,tnum) S.cli(command) f.close()