Home | History | Annotate | Download | only in plat-irix6
      1 # This file implements a class which forms an interface to the .cddb
      2 # directory that is maintained by SGI's cdman program.
      3 #
      4 # Usage is as follows:
      5 #
      6 # import readcd
      7 # r = readcd.Readcd()
      8 # c = Cddb(r.gettrackinfo())
      9 #
     10 # Now you can use c.artist, c.title and c.track[trackno] (where trackno
     11 # starts at 1).  When the CD is not recognized, all values will be the empty
     12 # string.
     13 # It is also possible to set the above mentioned variables to new values.
     14 # You can then use c.write() to write out the changed values to the
     15 # .cdplayerrc file.
     16 from warnings import warnpy3k
     17 warnpy3k("the cddb module has been removed in Python 3.0", stacklevel=2)
     18 del warnpy3k
     19 
     20 import string, posix, os
     21 
     22 _cddbrc = '.cddb'
     23 _DB_ID_NTRACKS = 5
     24 _dbid_map = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ@_=+abcdefghijklmnopqrstuvwxyz'
     25 def _dbid(v):
     26     if v >= len(_dbid_map):
     27         return string.zfill(v, 2)
     28     else:
     29         return _dbid_map[v]
     30 
     31 def tochash(toc):
     32     if type(toc) == type(''):
     33         tracklist = []
     34         for i in range(2, len(toc), 4):
     35             tracklist.append((None,
     36                       (int(toc[i:i+2]),
     37                        int(toc[i+2:i+4]))))
     38     else:
     39         tracklist = toc
     40     ntracks = len(tracklist)
     41     hash = _dbid((ntracks >> 4) & 0xF) + _dbid(ntracks & 0xF)
     42     if ntracks <= _DB_ID_NTRACKS:
     43         nidtracks = ntracks
     44     else:
     45         nidtracks = _DB_ID_NTRACKS - 1
     46         min = 0
     47         sec = 0
     48         for track in tracklist:
     49             start, length = track
     50             min = min + length[0]
     51             sec = sec + length[1]
     52         min = min + sec / 60
     53         sec = sec % 60
     54         hash = hash + _dbid(min) + _dbid(sec)
     55     for i in range(nidtracks):
     56         start, length = tracklist[i]
     57         hash = hash + _dbid(length[0]) + _dbid(length[1])
     58     return hash
     59 
     60 class Cddb:
     61     def __init__(self, tracklist):
     62         if os.environ.has_key('CDDB_PATH'):
     63             path = os.environ['CDDB_PATH']
     64             cddb_path = path.split(',')
     65         else:
     66             home = os.environ['HOME']
     67             cddb_path = [home + '/' + _cddbrc]
     68 
     69         self._get_id(tracklist)
     70 
     71         for dir in cddb_path:
     72             file = dir + '/' + self.id + '.rdb'
     73             try:
     74                 f = open(file, 'r')
     75                 self.file = file
     76                 break
     77             except IOError:
     78                 pass
     79         ntracks = int(self.id[:2], 16)
     80         self.artist = ''
     81         self.title = ''
     82         self.track = [None] + [''] * ntracks
     83         self.trackartist = [None] + [''] * ntracks
     84         self.notes = []
     85         if not hasattr(self, 'file'):
     86             return
     87         import re
     88         reg = re.compile(r'^([^.]*)\.([^:]*):[\t ]+(.*)')
     89         while 1:
     90             line = f.readline()
     91             if not line:
     92                 break
     93             match = reg.match(line)
     94             if not match:
     95                 print 'syntax error in ' + file
     96                 continue
     97             name1, name2, value = match.group(1, 2, 3)
     98             if name1 == 'album':
     99                 if name2 == 'artist':
    100                     self.artist = value
    101                 elif name2 == 'title':
    102                     self.title = value
    103                 elif name2 == 'toc':
    104                     if not self.toc:
    105                         self.toc = value
    106                     if self.toc != value:
    107                         print 'toc\'s don\'t match'
    108                 elif name2 == 'notes':
    109                     self.notes.append(value)
    110             elif name1[:5] == 'track':
    111                 try:
    112                     trackno = int(name1[5:])
    113                 except ValueError:
    114                     print 'syntax error in ' + file
    115                     continue
    116                 if trackno > ntracks:
    117                     print 'track number %r in file %s out of range' % (trackno, file)
    118                     continue
    119                 if name2 == 'title':
    120                     self.track[trackno] = value
    121                 elif name2 == 'artist':
    122                     self.trackartist[trackno] = value
    123         f.close()
    124         for i in range(2, len(self.track)):
    125             track = self.track[i]
    126             # if track title starts with `,', use initial part
    127             # of previous track's title
    128             if track and track[0] == ',':
    129                 try:
    130                     off = self.track[i - 1].index(',')
    131                 except ValueError:
    132                     pass
    133                 else:
    134                     self.track[i] = self.track[i-1][:off] \
    135                                     + track
    136 
    137     def _get_id(self, tracklist):
    138         # fill in self.id and self.toc.
    139         # if the argument is a string ending in .rdb, the part
    140         # upto the suffix is taken as the id.
    141         if type(tracklist) == type(''):
    142             if tracklist[-4:] == '.rdb':
    143                 self.id = tracklist[:-4]
    144                 self.toc = ''
    145                 return
    146             t = []
    147             for i in range(2, len(tracklist), 4):
    148                 t.append((None, \
    149                           (int(tracklist[i:i+2]), \
    150                            int(tracklist[i+2:i+4]))))
    151             tracklist = t
    152         ntracks = len(tracklist)
    153         self.id = _dbid((ntracks >> 4) & 0xF) + _dbid(ntracks & 0xF)
    154         if ntracks <= _DB_ID_NTRACKS:
    155             nidtracks = ntracks
    156         else:
    157             nidtracks = _DB_ID_NTRACKS - 1
    158             min = 0
    159             sec = 0
    160             for track in tracklist:
    161                 start, length = track
    162                 min = min + length[0]
    163                 sec = sec + length[1]
    164             min = min + sec / 60
    165             sec = sec % 60
    166             self.id = self.id + _dbid(min) + _dbid(sec)
    167         for i in range(nidtracks):
    168             start, length = tracklist[i]
    169             self.id = self.id + _dbid(length[0]) + _dbid(length[1])
    170         self.toc = string.zfill(ntracks, 2)
    171         for track in tracklist:
    172             start, length = track
    173             self.toc = self.toc + string.zfill(length[0], 2) + \
    174                       string.zfill(length[1], 2)
    175 
    176     def write(self):
    177         import posixpath
    178         if os.environ.has_key('CDDB_WRITE_DIR'):
    179             dir = os.environ['CDDB_WRITE_DIR']
    180         else:
    181             dir = os.environ['HOME'] + '/' + _cddbrc
    182         file = dir + '/' + self.id + '.rdb'
    183         if posixpath.exists(file):
    184             # make backup copy
    185             posix.rename(file, file + '~')
    186         f = open(file, 'w')
    187         f.write('album.title:\t' + self.title + '\n')
    188         f.write('album.artist:\t' + self.artist + '\n')
    189         f.write('album.toc:\t' + self.toc + '\n')
    190         for note in self.notes:
    191             f.write('album.notes:\t' + note + '\n')
    192         prevpref = None
    193         for i in range(1, len(self.track)):
    194             if self.trackartist[i]:
    195                 f.write('track%r.artist:\t%s\n' % (i, self.trackartist[i]))
    196             track = self.track[i]
    197             try:
    198                 off = track.index(',')
    199             except ValueError:
    200                 prevpref = None
    201             else:
    202                 if prevpref and track[:off] == prevpref:
    203                     track = track[off:]
    204                 else:
    205                     prevpref = track[:off]
    206             f.write('track%r.title:\t%s\n' % (i, track))
    207         f.close()
    208