#!/usr/bin/env python # Jouni Paulus, jouni.paulus@iki.fi, 23.11.2006 # # Based on cddb-info.py from: # Written 17 Nov 1999 by Ben Gertzfield # This work is released under the GNU GPL, version 2 or later. import DiscID, CDDB, sys, os, math, MySQLdb dev = None cdrom = None # MySQL db settings dbHost = "localhost" dbPort = 3306 dbUser = "user" dbPass = "password" strEncoding = "latin-1" # if True, the db inserts are skipped and just printed instead doDry = False #doDry = True if len(sys.argv) >= 2: dev = sys.argv[1] if dev: cdrom = DiscID.open(dev) else: cdrom = DiscID.open() print "Getting disc id in CDDB format...\n" disc_id = DiscID.disc_id(cdrom) print "Disc ID: %08lx Num tracks: %d\n" % (disc_id[0], disc_id[1]) print "Querying CDDB for info on disc...\n" print "Disc info:\n" for i in range(0, disc_id[1]): startF = disc_id[i+2] if i == disc_id[1] - 1: stopF = disc_id[i+3]*75.0 else: stopF = disc_id[i+3]-1 durF = stopF - startF + 1 durMin = int(math.floor(durF/75.0/60.0)) durSec = int(math.floor(durF/75.0 - durMin*60.0)) durFrac = int((durF/75.0 - durMin*60.0 - durSec*1.0)*100.0) print "Track %.02d: [%d:%s.%s]" % \ (i+1, durMin, str(durSec).zfill(2), str(durFrac).zfill(2)) (query_stat, query_info) = CDDB.query(disc_id) if query_stat == 202: # "No match found" print "No match found, insert the data yourself.\n" sys.exit("Bye...") elif query_stat == 403: # "Error, database entry corrupt" print "Failure getting disc info, status %i, meaning \"Database entry corrupt\".\n" % query_stat sys.exit("Bye...") elif query_stat == 409: # "Error, no handshake" print "Failure getting disc info, status %i, meaning \"No handshake\".\n" % query_stat sys.exit("Bye...") elif query_stat == 210 or query_stat == 211: # "Multiple exact matches found" or "Multiple inexact matches found" print "Query successfull. Found multiple (in)exact matches:" j = 0 for i in query_info: print "%d: Category: %s, Title: %s" % (j, i['category'], i['title']) j = j + 1 while (True): print "Please input the number of the matching disc." multiIdx = int(raw_input("#: ")) if multiIdx >= 0 and multiIdx < j: break qInfo = query_info[multiIdx] if query_stat == 200: # "Success" print ("Success!\nQuerying CDDB for track info of `%s'...\n" % query_info['title']) qInfo = query_info # Fetch more detailed info (read_stat, read_info) = CDDB.read(qInfo['category'], qInfo['disc_id']) if read_stat == 401: print "Error, specified entry not found in CDDB.\n" sys.exit("Bye...") elif read_stat == 402: print "Error, server error.\n" sys.exit("Bye...") elif read_stat == 403: print "Error, database entry is corrupt.\n" sys.exit("Bye...") elif read_stat == 409: print "Error, no handshake.\n" sys.exit("Bye...") elif read_stat == 417: print "Error, access limit exceeded.\n" sys.exit("Bye...") elif read_stat == 210: print "Query successfull.\n" discIdStr = hex(disc_id[0]) discIdStr = discIdStr[2:(len(discIdStr)-2)] # clip the 0x from the beginning titleStr = read_info['DTITLE'] tmpPair = titleStr.split('/',1) artistStr = tmpPair[0].lstrip().rstrip().decode(strEncoding) titleStr = tmpPair[1].lstrip().rstrip().decode(strEncoding) artistStr=artistStr.replace("'","\\'") titleStr=titleStr.replace("'","\\'") print "Disc genre %s, release year %s, id %s\n" % \ (read_info['DGENRE'], read_info['DYEAR'], discIdStr) for i in range(0, disc_id[1]): startF = disc_id[i+2] if i == disc_id[1] - 1: stopF = disc_id[i+3]*75.0 else: stopF = disc_id[i+3]-1 durF = stopF - startF + 1 durMin = int(math.floor(durF/75.0/60.0)) durSec = int(math.floor(durF/75.0 - durMin*60.0)) durFrac = int((durF/75.0 - durMin*60.0 - durSec*1.0)*100.0) print "Track %.02d: %s [%d:%s.%s]" % \ (i+1, read_info['TTITLE' + `i`], durMin, str(durSec).zfill(2), str(durFrac).zfill(2)) print "Do you want to insert this disc to the database? [y/N]" insChoise = raw_input("#: ") if (insChoise !="y") and (insChoise != "Y"): sys.exit("Bye..."); ### Ok, now ne have all the data collected, so let's insert it to the db. # connect to db db = MySQLdb.connect(host=dbHost, port=dbPort, user=dbUser, passwd=dbPass, db="myCDDB") # get a cursor to operate with dbCursor = db.cursor() # check if there is already a disc woth thos id in the db sqlCommand = "SELECT cddbid FROM cds WHERE cddbid = '%s'" % discIdStr dbCursor.execute(sqlCommand) resultRows = dbCursor.fetchall() if len(resultRows) != 0: # something found with this id print "There seems to be a CD in the db with the same id, so I'll stop here.\n" sys.exit("Bye...") # insert this disc yearStr = "%s" % read_info['DYEAR'] if len(yearStr) == 0: yearStr = "0000" genreStr = "%s" % read_info['DGENRE'] if len(genreStr) == 0: genreStr = qInfo['category'] sqlCommand = "INSERT INTO cds (cddbid, artist, title, category, year, comment) VALUES ('%s', '%s', '%s', '%s', '%s', '%s')" \ % (discIdStr, artistStr, titleStr, genreStr, yearStr, "") if doDry: print "%s\n" % (sqlCommand) else: dbCursor.execute(sqlCommand) # insert all tracks, one by one for i in range(0, disc_id[1]): startF = disc_id[i+2] if i == disc_id[1] - 1: stopF = disc_id[i+3]*75.0 else: stopF = disc_id[i+3]-1 durF = stopF - startF + 1 durHour = int(math.floor(durF/75.0/3600.0)) durMin = int(math.floor(durF/75.0/60.0 - durHour*60.0)) durSec = int(math.floor(durF/75.0 - durMin*60.0 - durHour*3600.0)) durFrac = int((durF/75.0 - durHour*3600.0 - durMin*60.0 - durSec*1.0)*100.0) timeStr = "%.2d:%.2d:%.2d.%.2d" % (durHour, durMin, durSec, durFrac) sqlCommand = "INSERT INTO tracks (cddbid, artist, title, trackno, time) VALUES ('%s', '%s', '%s', '%.02d', '%s')" \ % (discIdStr, artistStr, read_info['TTITLE' + `i`].replace("'","\\'").decode(strEncoding), i+1, timeStr); if doDry: print "%s\n" % (sqlCommand) else: dbCursor.execute(sqlCommand) print "All is done. Bye."