# This file implements a class which forms an interface to the .cddb
# directory that is maintained by SGI's cdman program.
#
# Usage is as follows:
#
# import readcd
# r = readcd.Readcd()
# c = Cddb(r.gettrackinfo())
#
# Now you can use c.artist, c.title and c.track[trackno] (where trackno
# starts at 1).  When the CD is not recognized, all values will be the empty
# string.
# It is also possible to set the above mentioned variables to new values.
# You can then use c.write() to write out the changed values to the
# .cdplayerrc file.

import string, posix, os

_cddbrc = '.cddb'
_DB_ID_NTRACKS = 5
_dbid_map = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ@_=+abcdefghijklmnopqrstuvwxyz'
def _dbid(v):
	if v >= len(_dbid_map):
		return string.zfill(v, 2)
	else:
		return _dbid_map[v]

def tochash(toc):
	if type(toc) == type(''):
		tracklist = []
		for i in range(2, len(toc), 4):
			tracklist.append((None,
				  (string.atoi(toc[i:i+2]),
				   string.atoi(toc[i+2:i+4]))))
	else:
		tracklist = toc
	ntracks = len(tracklist)
	hash = _dbid((ntracks >> 4) & 0xF) + _dbid(ntracks & 0xF)
	if ntracks <= _DB_ID_NTRACKS:
		nidtracks = ntracks
	else:
		nidtracks = _DB_ID_NTRACKS - 1
		min = 0
		sec = 0
		for track in tracklist:
			start, length = track
			min = min + length[0]
			sec = sec + length[1]
		min = min + sec / 60
		sec = sec % 60
		hash = hash + _dbid(min) + _dbid(sec)
	for i in range(nidtracks):
		start, length = tracklist[i]
		hash = hash + _dbid(length[0]) + _dbid(length[1])
	return hash
	
class Cddb:
	def __init__(self, tracklist):
		if os.environ.has_key('CDDB_PATH'):
			path = os.environ['CDDB_PATH']
			cddb_path = string.splitfields(path, ',')
		else:
			home = os.environ['HOME']
			cddb_path = [home + '/' + _cddbrc]

		self._get_id(tracklist)

		for dir in cddb_path:
			file = dir + '/' + self.id + '.rdb'
			try:
				f = open(file, 'r')
				self.file = file
				break
			except IOError:
				pass
		ntracks = string.atoi(self.id[:2], 16)
		self.artist = ''
		self.title = ''
		self.track = [None] + [''] * ntracks
		self.trackartist = [None] + [''] * ntracks
		self.notes = []
		if not hasattr(self, 'file'):
			return
		import re
		reg = re.compile(r'^([^.]*)\.([^:]*):[\t ]+(.*)')
		while 1:
			line = f.readline()
			if not line:
				break
			match = reg.match(line)
			if not match:
				print 'syntax error in ' + file
				continue
			name1, name2, value = match.group(1, 2, 3)
			if name1 == 'album':
				if name2 == 'artist':
					self.artist = value
				elif name2 == 'title':
					self.title = value
				elif name2 == 'toc':
					if not self.toc:
						self.toc = value
					if self.toc != value:
						print 'toc\'s don\'t match'
				elif name2 == 'notes':
					self.notes.append(value)
			elif name1[:5] == 'track':
				try:
					trackno = string.atoi(name1[5:])
				except strings.atoi_error:
					print 'syntax error in ' + file
					continue
				if trackno > ntracks:
					print 'track number ' + `trackno` + \
						  ' in file ' + file + \
						  ' out of range'
					continue
				if name2 == 'title':
					self.track[trackno] = value
				elif name2 == 'artist':
					self.trackartist[trackno] = value
		f.close()
		for i in range(2, len(self.track)):
			track = self.track[i]
			# if track title starts with `,', use initial part
			# of previous track's title
			if track and track[0] == ',':
				try:
					off = string.index(self.track[i - 1],
							   ',')
				except string.index_error:
					pass
				else:
					self.track[i] = self.track[i-1][:off] \
							+ track

	def _get_id(self, tracklist):
		# fill in self.id and self.toc.
		# if the argument is a string ending in .rdb, the part
		# upto the suffix is taken as the id.
		if type(tracklist) == type(''):
			if tracklist[-4:] == '.rdb':
				self.id = tracklist[:-4]
				self.toc = ''
				return
			t = []
			for i in range(2, len(tracklist), 4):
				t.append((None, \
					  (string.atoi(tracklist[i:i+2]), \
					   string.atoi(tracklist[i+2:i+4]))))
			tracklist = t
		ntracks = len(tracklist)
		self.id = _dbid((ntracks >> 4) & 0xF) + _dbid(ntracks & 0xF)
		if ntracks <= _DB_ID_NTRACKS:
			nidtracks = ntracks
		else:
			nidtracks = _DB_ID_NTRACKS - 1
			min = 0
			sec = 0
			for track in tracklist:
				start, length = track
				min = min + length[0]
				sec = sec + length[1]
			min = min + sec / 60
			sec = sec % 60
			self.id = self.id + _dbid(min) + _dbid(sec)
		for i in range(nidtracks):
			start, length = tracklist[i]
			self.id = self.id + _dbid(length[0]) + _dbid(length[1])
		self.toc = string.zfill(ntracks, 2)
		for track in tracklist:
			start, length = track
			self.toc = self.toc + string.zfill(length[0], 2) + \
				  string.zfill(length[1], 2)

	def write(self):
		import posixpath
		if os.environ.has_key('CDDB_WRITE_DIR'):
			dir = os.environ['CDDB_WRITE_DIR']
		else:
			dir = os.environ['HOME'] + '/' + _cddbrc
		file = dir + '/' + self.id + '.rdb'
		if posixpath.exists(file):
			# make backup copy
			posix.rename(file, file + '~')
		f = open(file, 'w')
		f.write('album.title:\t' + self.title + '\n')
		f.write('album.artist:\t' + self.artist + '\n')
		f.write('album.toc:\t' + self.toc + '\n')
		for note in self.notes:
			f.write('album.notes:\t' + note + '\n')
		prevpref = None
		for i in range(1, len(self.track)):
			if self.trackartist[i]:
				f.write('track'+`i`+'.artist:\t'+self.trackartist[i]+'\n')
			track = self.track[i]
			try:
				off = string.index(track, ',')
			except string.index_error:
				prevpref = None
			else:
				if prevpref and track[:off] == prevpref:
					track = track[off:]
				else:
					prevpref = track[:off]
			f.write('track' + `i` + '.title:\t' + track + '\n')
		f.close()
