Code:
#!/usr/bin/python
import os
import re
import sys
import string
import commands
import CDDB, DiscID
# Some buffers to hold information we'll need
artist = ""
title = ""
tracks = []
nullLookup = 0
startDir = os.getcwd()
# get a single character from STDIN
def getch ():
# from ASPN
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
def queryCDDB():
# get info from CD
cdrom = DiscID.open()
disc_id = DiscID.disc_id(cdrom)
# query CDDB
(query_status, query_info) = CDDB.query(disc_id)
os.system("clear")
# single match
if query_status == 200:
char = ""
(read_status, read_info) = CDDB.read(query_info['category'], query_info['disc_id'])
for i in range(disc_id[1]):
print "Track %.02d: %s" % (i+1, read_info['TTITLE' + `i`])
print "\nPress [Enter] to continue, 'q' to quit: "
while char != '\r':
char = getch()
if char == 'q':
print "\n"
sys.exit(0)
elif char == '\r':
for i in range(disc_id[1]):
tracks.append("%.02d_____%s" % (i+1, read_info['TTITLE' + `i`]))
s = re.match("(.+?)\s+/\s+(.+)", query_info['title'])
global artist
artist = s.group(1)
global title
title = s.group(2)
# multiple matches
elif query_status == 210 or query_status == 211:
char = ""
while char != '\r':
entryString = ""
print "Multiple CDDB Entries Found.\n"
print "ID:\tArtist / Album\n"
for i in range(len(query_info)):
printStr = "%s:\t" % str(i)
printStr += query_info[i]['title']
print printStr
print "\nEnter ID, and press 'Enter' to select this entry, or 'v' to view the track listing\n\n\
eg. '0v' or '1[Enter]' or 'q' to quit\n"
sys.stdout.write("Selection: ")
char = ""
# construct the id number...ignore everything except digits, "v", and "[Enter]"
while ( char != 'v' and char != '\r' ):
if re.match("^[0-9]$", char):
sys.stdout.write(char)
entryString += char
elif re.match("^q$", char):
print "\n"
sys.exit(0)
char = getch()
# immediately store a copy of the user's selected option and free char for later use
option = char
char = ""
# do not permit null entries or invalid numbers
if (entryString == "" or int(entryString) > len(query_info)-1):
os.system("clear")
continue
# regardless of whether "v" or "[Enter]" was pressed, print out the chosen album info
(read_status, read_info) = CDDB.read(query_info[int(entryString)]['category'],\
query_info[int(entryString)]['disc_id'])
print "\n"
print query_info[int(entryString)]['title']+"\n"
for i in range(disc_id[1]):
print "Track %.02d: %s" % (i+1, read_info['TTITLE' + `i`])
print "\nPress [Enter] to continue, 'q' to quit. "
while ( char != "\r" ):
char = getch()
if char == 'q':
sys.exit(0)
os.system("/usr/bin/clear")
# if the user selected the option to choose the specified track, grab the info
if option == '\r':
s = re.match("(.+?)\s+/\s+(.+)", query_info[int(entryString)]['title'])
global artist
artist = s.group(1)
global title
title = s.group(2)
for i in range(disc_id[1]):
tracks.append("%.02d_____%s" % (i+1, read_info['TTITLE' + `i`]))
elif query_status == 202 or query_status == 403:
# no match found :(
char = ""
if query_status == 403:
print "ERROR: Database entry is corrupt! Cannot obtain disc info.\n"
print "No matches found :(\n"
print "Press [Enter] to continue or 'q' to quit"
while char != '\r' and char != 'q':
char = getch()
if char == 'q':
sys.exit(0)
if char == '\r':
global nullLookup,artist,title
artist = "Unknown Artist"
title = "Unknown Title"
nullLookup = 1
os.system("clear")
elif query_status == 409:
raise RuntimeError, "ERROR: No handshake with CDDB server. Possible client-side error.\n"
def ripTracks():
# grab the output of cdparanoia query so that we can make sure we have the right number of tracks
data = commands.getoutput("cdparanoia -Q")
array = string.split(data, "\n")
i = 0
# count the number of lines that start with a few spaces, and a number followed by a period...these are tracks
for line in array:
if re.match("\s+\d+\..+", line):
i = i+1
if i != len(tracks) and nullLookup == 0:
raise RuntimeError, "Number of tracks on CD does not match CDDB info!\nCD: %s, CDDB: %s\n"\
% (str(i),str(len(tracks)))
else:
# Numbers match up. Create the destination directory and cwd to it
if os.path.exists("%s/%s" % (artist,title)):
print "Path '%s/%s' already exists!\n\nPress [Enter] to remove it, or 'q' to quit\n" % (artist,title)
char = getch()
if char == "\r":
os.system("rm -rf \"%s\"" % artist)
elif char == 'q':
sys.exit(0)
os.makedirs("%s/%s/%s" % (startDir,artist,title))
os.chdir("%s/%s/%s" % (startDir,artist,title))
os.system("clear")
# begin cd extraction
print "Starting Extraction from CD...\n"
syscall = os.system("cdparanoia -B --never-skip=40")
if syscall != 0:
raise RuntimeError, "cdparanoia returned non-zero exit status! %s" % syscall
def encodeMP3s():
os.chdir("%s/%s/%s" % (startDir,artist,title))
files = os.listdir(".")
for file in files:
s = re.match("track(\d+).cdda\.wav", file)
trackNumberCD = s.group(1)
#temporarily store the ##_____Title format in trackTitle
if nullLookup == 1:
trackTitle = str(trackNumberCD)+"_____Track"+str(trackNumberCD)
else:
trackTitle = tracks[int(trackNumberCD)-1]
# ensure cdparanoia and cddb track numbers match
# also extract actual trackTitle
(trackNumberCDDB,trackTitle) = string.split(trackTitle, "_____")
if trackNumberCDDB != trackNumberCD:
raise RuntimeError, "CDDB track number: %s\nCD track number: %s\n" \
% (tracknumberCDDB,tracknumberCD)
mp3file = '"'+trackNumberCDDB+" - "+trackTitle+'.mp3"'
cmd = 'lame --ta "%s" --tl "%s" --tn "%s" --tt "%s" --preset standard %s %s' % (artist,title,trackNumberCDDB,trackTitle,file,mp3file)
print "Beginning conversion...%s\n" % file
print "Artist: %s" % artist
print "Album: %s" % title
print "Track Number: %s" % trackNumberCDDB
print "Track Title: %s\n" % trackTitle
print 'Command: %s\n' % cmd
syscall = os.system(cmd)
if syscall != 0:
raise RuntimeError, "lame returned non-zero exit status! %" % syscall
os.system("clear")
queryCDDB()
ripTracks()
encodeMP3s()
os.chdir("%s/%s/%s" % (startDir,artist,title))
os.system("rm *.wav")
EDIT: Fixed broken case where only one match found. Sorry
Bookmarks