home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / palmos / pippy-0.6beta-src.tar.gz / pippy-0.6beta-src.tar / pippy-0.6beta-src / src / Lib / plat-irix6 / cddb.py < prev    next >
Text File  |  2000-12-21  |  6KB  |  208 lines

  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 re
  85.         reg = re.compile(r'^([^.]*)\.([^:]*):[\t ]+(.*)')
  86.         while 1:
  87.             line = f.readline()
  88.             if not line:
  89.                 break
  90.             match = reg.match(line)
  91.             if not match:
  92.                 print 'syntax error in ' + file
  93.                 continue
  94.             name1, name2, value = match.group(1, 2, 3)
  95.             if name1 == 'album':
  96.                 if name2 == 'artist':
  97.                     self.artist = value
  98.                 elif name2 == 'title':
  99.                     self.title = value
  100.                 elif name2 == 'toc':
  101.                     if not self.toc:
  102.                         self.toc = value
  103.                     if self.toc != value:
  104.                         print 'toc\'s don\'t match'
  105.                 elif name2 == 'notes':
  106.                     self.notes.append(value)
  107.             elif name1[:5] == 'track':
  108.                 try:
  109.                     trackno = string.atoi(name1[5:])
  110.                 except strings.atoi_error:
  111.                     print 'syntax error in ' + file
  112.                     continue
  113.                 if trackno > ntracks:
  114.                     print 'track number ' + `trackno` + \
  115.                           ' in file ' + file + \
  116.                           ' out of range'
  117.                     continue
  118.                 if name2 == 'title':
  119.                     self.track[trackno] = value
  120.                 elif name2 == 'artist':
  121.                     self.trackartist[trackno] = value
  122.         f.close()
  123.         for i in range(2, len(self.track)):
  124.             track = self.track[i]
  125.             # if track title starts with `,', use initial part
  126.             # of previous track's title
  127.             if track and track[0] == ',':
  128.                 try:
  129.                     off = string.index(self.track[i - 1],
  130.                                ',')
  131.                 except string.index_error:
  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.                       (string.atoi(tracklist[i:i+2]), \
  150.                        string.atoi(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'+`i`+'.artist:\t'+self.trackartist[i]+'\n')
  196.             track = self.track[i]
  197.             try:
  198.                 off = string.index(track, ',')
  199.             except string.index_error:
  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' + `i` + '.title:\t' + track + '\n')
  207.         f.close()
  208.