home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Python 1.1 / Lib / irix5 / cddb.py < prev    next >
Encoding:
Python Source  |  1994-09-06  |  5.2 KB  |  198 lines  |  [TEXT/R*ch]

  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.  
  17. import string, posix, os
  18.  
  19. _cddbrc = '.cddb'
  20. _DB_ID_NTRACKS = 5
  21. _dbid_map = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ@_=+abcdefghijklmnopqrstuvwxyz'
  22. def _dbid(v):
  23.     if v >= len(_dbid_map):
  24.         return string.zfill(v, 2)
  25.     else:
  26.         return _dbid_map[v]
  27.  
  28. def tochash(toc):
  29.     if type(toc) == type(''):
  30.         tracklist = []
  31.         for i in range(2, len(toc), 4):
  32.             tracklist.append((None,
  33.                   (string.atoi(toc[i:i+2]),
  34.                    string.atoi(toc[i+2:i+4]))))
  35.     else:
  36.         tracklist = toc
  37.     ntracks = len(tracklist)
  38.     hash = _dbid((ntracks >> 4) & 0xF) + _dbid(ntracks & 0xF)
  39.     if ntracks <= _DB_ID_NTRACKS:
  40.         nidtracks = ntracks
  41.     else:
  42.         nidtracks = _DB_ID_NTRACKS - 1
  43.         min = 0
  44.         sec = 0
  45.         for track in tracklist:
  46.             start, length = track
  47.             min = min + length[0]
  48.             sec = sec + length[1]
  49.         min = min + sec / 60
  50.         sec = sec % 60
  51.         hash = hash + _dbid(min) + _dbid(sec)
  52.     for i in range(nidtracks):
  53.         start, length = tracklist[i]
  54.         hash = hash + _dbid(length[0]) + _dbid(length[1])
  55.     return hash
  56.     
  57. class Cddb:
  58.     def __init__(self, tracklist):
  59.         if os.environ.has_key('CDDB_PATH'):
  60.             path = os.environ['CDDB_PATH']
  61.             cddb_path = string.splitfields(path, ',')
  62.         else:
  63.             home = os.environ['HOME']
  64.             cddb_path = [home + '/' + _cddbrc]
  65.  
  66.         self._get_id(tracklist)
  67.  
  68.         for dir in cddb_path:
  69.             file = dir + '/' + self.id + '.rdb'
  70.             try:
  71.                 f = open(file, 'r')
  72.                 self.file = file
  73.                 break
  74.             except IOError:
  75.                 pass
  76.         ntracks = string.atoi(self.id[:2], 16)
  77.         self.artist = ''
  78.         self.title = ''
  79.         self.track = [None] + [''] * ntracks
  80.         if not hasattr(self, 'file'):
  81.             return
  82.         import regex
  83.         reg = regex.compile('^\\([^.]*\\)\\.\\([^:]*\\):\t\\(.*\\)')
  84.         while 1:
  85.             line = f.readline()
  86.             if not line:
  87.                 break
  88.             if reg.match(line) == -1:
  89.                 print 'syntax error in ' + file
  90.                 continue
  91.             name1 = line[reg.regs[1][0]:reg.regs[1][1]]
  92.             name2 = line[reg.regs[2][0]:reg.regs[2][1]]
  93.             value = line[reg.regs[3][0]:reg.regs[3][1]]
  94.             if name1 == 'album':
  95.                 if name2 == 'artist':
  96.                     self.artist = value
  97.                 elif name2 == 'title':
  98.                     self.title = value
  99.                 elif name2 == 'toc':
  100.                     if not self.toc:
  101.                         self.toc = value
  102.                     if self.toc != value:
  103.                         print 'toc\'s don\'t match'
  104.             elif name1[:5] == 'track':
  105.                 try:
  106.                     trackno = string.atoi(name1[5:])
  107.                 except strings.atoi_error:
  108.                     print 'syntax error in ' + file
  109.                     continue
  110.                 if trackno > ntracks:
  111.                     print 'track number ' + `trackno` + \
  112.                           ' in file ' + file + \
  113.                           ' out of range'
  114.                     continue
  115.                 self.track[trackno] = value
  116.         f.close()
  117.         for i in range(2, len(self.track)):
  118.             track = self.track[i]
  119.             # if track title starts with `,', use initial part
  120.             # of previous track's title
  121.             if track and track[0] == ',':
  122.                 try:
  123.                     off = string.index(self.track[i - 1],
  124.                                ',')
  125.                 except string.index_error:
  126.                     pass
  127.                 else:
  128.                     self.track[i] = self.track[i-1][:off] \
  129.                             + track
  130.  
  131.     def _get_id(self, tracklist):
  132.         # fill in self.id and self.toc.
  133.         # if the argument is a string ending in .rdb, the part
  134.         # upto the suffix is taken as the id.
  135.         if type(tracklist) == type(''):
  136.             if tracklist[-4:] == '.rdb':
  137.                 self.id = tracklist[:-4]
  138.                 self.toc = ''
  139.                 return
  140.             t = []
  141.             for i in range(2, len(tracklist), 4):
  142.                 t.append((None, \
  143.                       (string.atoi(tracklist[i:i+2]), \
  144.                        string.atoi(tracklist[i+2:i+4]))))
  145.             tracklist = t
  146.         ntracks = len(tracklist)
  147.         self.id = _dbid((ntracks >> 4) & 0xF) + _dbid(ntracks & 0xF)
  148.         if ntracks <= _DB_ID_NTRACKS:
  149.             nidtracks = ntracks
  150.         else:
  151.             nidtracks = _DB_ID_NTRACKS - 1
  152.             min = 0
  153.             sec = 0
  154.             for track in tracklist:
  155.                 start, length = track
  156.                 min = min + length[0]
  157.                 sec = sec + length[1]
  158.             min = min + sec / 60
  159.             sec = sec % 60
  160.             self.id = self.id + _dbid(min) + _dbid(sec)
  161.         for i in range(nidtracks):
  162.             start, length = tracklist[i]
  163.             self.id = self.id + _dbid(length[0]) + _dbid(length[1])
  164.         self.toc = string.zfill(ntracks, 2)
  165.         for track in tracklist:
  166.             start, length = track
  167.             self.toc = self.toc + string.zfill(length[0], 2) + \
  168.                   string.zfill(length[1], 2)
  169.  
  170.     def write(self):
  171.         import posixpath
  172.         if os.environ.has_key('CDDB_WRITE_DIR'):
  173.             dir = os.environ['CDDB_WRITE_DIR']
  174.         else:
  175.             dir = os.environ['HOME'] + '/' + _cddbrc
  176.         file = dir + '/' + self.id + '.rdb'
  177.         if posixpath.exists(file):
  178.             # make backup copy
  179.             posix.rename(file, file + '~')
  180.         f = open(file, 'w')
  181.         f.write('album.title:\t' + self.title + '\n')
  182.         f.write('album.artist:\t' + self.artist + '\n')
  183.         f.write('album.toc:\t' + self.toc + '\n')
  184.         prevpref = None
  185.         for i in range(1, len(self.track)):
  186.             track = self.track[i]
  187.             try:
  188.                 off = string.index(track, ',')
  189.             except string.index_error:
  190.                 prevpref = None
  191.             else:
  192.                 if prevpref and track[:off] == prevpref:
  193.                     track = track[off:]
  194.                 else:
  195.                     prevpref = track[:off]
  196.             f.write('track' + `i` + '.title:\t' + track + '\n')
  197.         f.close()
  198.