home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / Python 1.3 / source code / Lib / irix5 / cddb.py < prev    next >
Encoding:
Python Source  |  1995-12-17  |  5.6 KB  |  209 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.         self.trackartist = [None] + [''] * ntracks
  81.         self.notes = []
  82.         if not hasattr(self, 'file'):
  83.             return
  84.         import regex
  85.         reg = regex.compile('^\\([^.]*\\)\\.\\([^:]*\\):[\t ]+\\(.*\\)')
  86.         while 1:
  87.             line = f.readline()
  88.             if not line:
  89.                 break
  90.             if reg.match(line) == -1:
  91.                 print 'syntax error in ' + file
  92.                 continue
  93.             name1 = line[reg.regs[1][0]:reg.regs[1][1]]
  94.             name2 = line[reg.regs[2][0]:reg.regs[2][1]]
  95.             value = line[reg.regs[3][0]:reg.regs[3][1]]
  96.             if name1 == 'album':
  97.                 if name2 == 'artist':
  98.                     self.artist = value
  99.                 elif name2 == 'title':
  100.                     self.title = value
  101.                 elif name2 == 'toc':
  102.                     if not self.toc:
  103.                         self.toc = value
  104.                     if self.toc != value:
  105.                         print 'toc\'s don\'t match'
  106.                 elif name2 == 'notes':
  107.                     self.notes.append(value)
  108.             elif name1[:5] == 'track':
  109.                 try:
  110.                     trackno = string.atoi(name1[5:])
  111.                 except strings.atoi_error:
  112.                     print 'syntax error in ' + file
  113.                     continue
  114.                 if trackno > ntracks:
  115.                     print 'track number ' + `trackno` + \
  116.                           ' in file ' + file + \
  117.                           ' out of range'
  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 = string.index(self.track[i - 1],
  131.                                ',')
  132.                 except string.index_error:
  133.                     pass
  134.                 else:
  135.                     self.track[i] = self.track[i-1][:off] \
  136.                             + track
  137.  
  138.     def _get_id(self, tracklist):
  139.         # fill in self.id and self.toc.
  140.         # if the argument is a string ending in .rdb, the part
  141.         # upto the suffix is taken as the id.
  142.         if type(tracklist) == type(''):
  143.             if tracklist[-4:] == '.rdb':
  144.                 self.id = tracklist[:-4]
  145.                 self.toc = ''
  146.                 return
  147.             t = []
  148.             for i in range(2, len(tracklist), 4):
  149.                 t.append((None, \
  150.                       (string.atoi(tracklist[i:i+2]), \
  151.                        string.atoi(tracklist[i+2:i+4]))))
  152.             tracklist = t
  153.         ntracks = len(tracklist)
  154.         self.id = _dbid((ntracks >> 4) & 0xF) + _dbid(ntracks & 0xF)
  155.         if ntracks <= _DB_ID_NTRACKS:
  156.             nidtracks = ntracks
  157.         else:
  158.             nidtracks = _DB_ID_NTRACKS - 1
  159.             min = 0
  160.             sec = 0
  161.             for track in tracklist:
  162.                 start, length = track
  163.                 min = min + length[0]
  164.                 sec = sec + length[1]
  165.             min = min + sec / 60
  166.             sec = sec % 60
  167.             self.id = self.id + _dbid(min) + _dbid(sec)
  168.         for i in range(nidtracks):
  169.             start, length = tracklist[i]
  170.             self.id = self.id + _dbid(length[0]) + _dbid(length[1])
  171.         self.toc = string.zfill(ntracks, 2)
  172.         for track in tracklist:
  173.             start, length = track
  174.             self.toc = self.toc + string.zfill(length[0], 2) + \
  175.                   string.zfill(length[1], 2)
  176.  
  177.     def write(self):
  178.         import posixpath
  179.         if os.environ.has_key('CDDB_WRITE_DIR'):
  180.             dir = os.environ['CDDB_WRITE_DIR']
  181.         else:
  182.             dir = os.environ['HOME'] + '/' + _cddbrc
  183.         file = dir + '/' + self.id + '.rdb'
  184.         if posixpath.exists(file):
  185.             # make backup copy
  186.             posix.rename(file, file + '~')
  187.         f = open(file, 'w')
  188.         f.write('album.title:\t' + self.title + '\n')
  189.         f.write('album.artist:\t' + self.artist + '\n')
  190.         f.write('album.toc:\t' + self.toc + '\n')
  191.         for note in self.notes:
  192.             f.write('album.notes:\t' + note + '\n')
  193.         prevpref = None
  194.         for i in range(1, len(self.track)):
  195.             if self.trackartist[i]:
  196.                 f.write('track'+`i`+'.artist:\t'+self.trackartist[i]+'\n')
  197.             track = self.track[i]
  198.             try:
  199.                 off = string.index(track, ',')
  200.             except string.index_error:
  201.                 prevpref = None
  202.             else:
  203.                 if prevpref and track[:off] == prevpref:
  204.                     track = track[off:]
  205.                 else:
  206.                     prevpref = track[:off]
  207.             f.write('track' + `i` + '.title:\t' + track + '\n')
  208.         f.close()
  209.