def _lookup_cddb(self): """ returns a cdinfo() instance containing the information we found in cddb, or None if that doesn't work. This method doesn't intentionally throw any exceptions (unlike _lookup_mb) although I'm sure it's possible. """ import DiscID, CDDB if self.cddevice: dev = DiscID.open(self.cddevice) else: dev = DiscID.open() cdid = DiscID.disc_id(dev) tracks = cdid[1] (status, info) = CDDB.query(cdid) if status == 200: (status, info) = CDDB.read(info['category'], \ info['disc_id']) elif status == 210 or status == 211: (status, info) = CDDB.read(info[0]['category'], \ info[0]['disc_id']) else: return None ret = cdinfo() for key in info.keys(): if key.startswith('TTITLE'): n = int(re.findall("TTITLE([0-9]+)", key)[0]) ret.titles[n] = info[key].encode('ascii', errors='replace') elif key == 'DTITLE': (artist, album) = info[key].split('/') ret.artist = artist.strip() ret.album = album.strip() elif key == 'DYEAR': ret.releasedate = info[key] wx.LogMessage("cddb succeeded") return ret
def get_cddb(self): try: import CDDB, DiscID except ImportError: fatal('You need python-cddb (http://cddb-py.sf.net) to convert cds. Please install it.') disc_id = DiscID.disc_id(DiscID.open(self.dev)) query_info = CDDB.query(disc_id)[1] if not query_info: fatal('The disk is not listed in FreeDB, dir2ogg only supports disk listed in MusicBrainz or FreeDB') if isinstance(query_info, list): query_info = query_info[0] read_info = CDDB.read(query_info['category'], query_info['disc_id'])[1] for track in range(disc_id[1]): title = {} title['discid'] = query_info['disc_id'] title['artist'], title['album'] = (track.strip() for track in query_info['title'].split("/")) title['genre'] = read_info['DGENRE'] title['date'] = read_info['DYEAR'] title['title'] = read_info['TTITLE' + str(track)] title['tracktotal'] = str(len(range(disc_id[1])) + 1) title['ntracknumber'] = '0' * (len(title['tracktotal'] ) - len(str(track+1)) ) + str(track+1) title['tracknumber'] = str(track+1) for key, val in title.items(): title[key] = unicode(str(val), "ISO-8859-1") ConvertTrack(self.dev, self.conf, track+1, title)
def _query_cddb(self, disc_id): try: (query_status, query_info) = CDDB.query(disc_id) self.logger.debug("CDDB Query status: %s" % query_status) except Exception as e: self.logger.error(e) query_status = 0 query_info = {} # Exact match found try: if query_status == 200: (read_status, read_info) = CDDB.read(query_info["category"], query_info["disc_id"]) self.logger.debug("CDDB Read Status: %s" % read_status) # Multiple matches found - pick first elif query_status == 210 or query_status == 211: (read_status, read_info) = CDDB.read(query_info[0]["category"], query_info[0]["disc_id"]) self.logger.debug("CDDB Read Status: %s" % read_status) # No match found else: self.logger.info("CD query failed, status: %s " % query_status) except Exception as e: self.logger.error(e) read_status = 0 read_info = {} if read_status != 210: self.logger.info("CDDB read failed, status: %s" % read_status) return read_info
def get_cddb_info(self): try: disc = DiscID.open(self.device) self.info = DiscID.disc_id(disc) status, info = CDDB.query(self.info) except IOError: return if status in (210, 211): info = info[0] status = 200 if status != 200: return (status, info) = CDDB.read(info['category'], info['disc_id']) title = info['DTITLE'].split(" / ") for i in range(self.info[1]): tr = self[i] tr.set_tag_raw('title', info['TTITLE' + `i`].decode('iso-8859-15', 'replace')) tr.set_tag_raw('album', title[1].decode('iso-8859-15', 'replace')) tr.set_tag_raw('artist', title[0].decode('iso-8859-15', 'replace')) tr.set_tag_raw('year', info['EXTD'].replace("YEAR: ", "")) tr.set_tag_raw('genre', info['DGENRE']) self.name = title[1].decode('iso-8859-15', 'replace') event.log_event('cddb_info_retrieved', self, True)
def get_cddb_info(self): try: disc = DiscID.open(self.device) self.info = DiscID.disc_id(disc) status, info = CDDB.query(self.info) except IOError: return if status in (210, 211): info = info[0] status = 200 if status != 200: return (status, info) = CDDB.read(info['category'], info['disc_id']) title = info['DTITLE'].split(" / ") for i in range(self.info[1]): tr = self[i] tr.set_tag_raw( 'title', info['TTITLE' + ` i `].decode('iso-8859-15', 'replace')) tr.set_tag_raw('album', title[1].decode('iso-8859-15', 'replace')) tr.set_tag_raw('artist', title[0].decode('iso-8859-15', 'replace')) tr.set_tag_raw('year', info['EXTD'].replace("YEAR: ", "")) tr.set_tag_raw('genre', info['DGENRE']) self.name = title[1].decode('iso-8859-15', 'replace') event.log_event('cddb_info_retrieved', self, True)
def cddbRequest(self, discInfo): """ Return disc information from online CDDB, None if request fails """ import CDDB, socket # Make sure to not be blocked by the request socket.setdefaulttimeout(consts.socketTimeout) try: (status, info) = CDDB.query(discInfo) if status == 200: disc = info # Success elif status == 210: disc = info[0] # Exact multiple matches elif status == 211: disc = info[0] # Inexact multiple matches else: raise Exception, "Unknown disc (phase 1 returned %u)" % status (status, info) = CDDB.read(disc["category"], disc["disc_id"]) if status == 210: return info else: raise Exception, "Unknown disc (phase 2 returned %u)" % status except: logger.error("[%s] CDDB request failed\n\n%s" % (MOD_INFO[modules.MODINFO_NAME], traceback.format_exc())) return None
def get_cddb_info(self): try: disc = DiscID.open(self.device) self.info = DiscID.disc_id(disc) status, info = CDDB.query(self.info) except IOError: return if status in (210, 211): info = info[0] status = 200 if status != 200: return (status, info) = CDDB.read(info["category"], info["disc_id"]) title = info["DTITLE"].split(" / ") for i in range(self.info[1]): tr = self[i] tr.set_tag_raw("title", info["TTITLE" + str(i)].decode("iso-8859-15", "replace")) tr.set_tag_raw("album", title[1].decode("iso-8859-15", "replace")) tr.set_tag_raw("artist", title[0].decode("iso-8859-15", "replace")) tr.set_tag_raw("year", info["EXTD"].replace("YEAR: ", "")) tr.set_tag_raw("genre", info["DGENRE"]) self.name = title[1].decode("iso-8859-15", "replace") event.log_event("cddb_info_retrieved", self, True)
def cd_rip(self, device): self.log.debug(device.device_node) self.log.debug(device.device_path) if self.is_cd_ready(): try: # cddb cd_title = None cdrom = DiscID.open() disc_id = DiscID.disc_id(cdrom) (query_status, query_info) = CDDB.query(disc_id) if query_status == 200: cd_title = query_info['title'][:20] self.log.info("Starting CD ripping for %s" % cd_title) rip_workdir = get_config(self.args.conf, 'Ripping', 'workdir') ripper = Worker(rip_workdir) cd2cloud_cfg = get_config(self.args.conf, 'Ripping', 'abcde_conf') cmd = '/usr/bin/abcde -c %s -j 5 -N' % cd2cloud_cfg #ripper.thread(cmd) ripper.run_cmd(cmd) self.log.info("Complete CD ripping for %s" % cd_title) self.notify(cd_title) except: msg = 'FAILED %s' % cd_title self.notify(msg)
def __init__(self, disc_id): # Assume that no results will be found. self.artist = _("Unknown artist") self.length = 0 self.title = _("Unknown title") self.tracks = [] try: (query_status, query_info) = CDDB.query(disc_id) except IOError: # Set query_status to 0 to act like an unknown CD. query_status = 0 # See CDDB documentation for more information. # http://cddb-py.sourceforge.net/CDDB/README # query_info variable's type depends on query_status if query_status == 200: # On 200, a dictionary containing three items is returned self._get_information_from_result_element(query_info, disc_id) elif query_status == 210 or query_status == 211: # On 211 or 210, a list will be returned as the second item. # Each element of the list will be a dictionary containing # three items, exactly the same as a single 200 success return. self._get_information_from_result_element(query_info[0], disc_id) else: # No metadata found for this disc for i in range(disc_id[1]): self.tracks.append(CompactDiscTrack(i + 1, _("Unknown track %(num)s.") % {'num': str(i + 1)}, 0))
def query(category, discid, xcode='utf8:utf8'): #from quodlibet's cddb plugin by Michael Urman discinfo = {} tracktitles = {} read, info = CDDB.read(category, discid, **CLIENTINFO) if read != 210: return None xf, xt = xcode.split(':') for key, value in info.iteritems(): try: value = value.decode('utf-8', 'replace').strip().encode( xf, 'replace').decode(xt, 'replace') except AttributeError: pass if key.startswith('TTITLE'): try: tracktitles[int(key[6:])] = value except ValueError: pass elif key == 'DGENRE': discinfo['genre'] = value elif key == 'DTITLE': dtitle = value.strip().split(' / ', 1) if len(dtitle) == 2: discinfo['artist'], discinfo['title'] = dtitle else: discinfo['title'] = dtitle[0].strip() elif key == 'DYEAR': discinfo['year'] = value return discinfo, tracktitles
def read(self): try: device = DiscID.open() disc_info = DiscID.disc_id(device) (query_status, self.query_info) = CDDB.query(disc_info) except cdrom.error, e: raise cdrom.error, e
def __init__(self): cdaudio = DiscID.open() print "CD: ", cdaudio try: self.disc_id = DiscID.disc_id(cdaudio) print "disc_id: ", self.disc_id self.is_audio_cd = True except: print "No CD" disc_id = None self.is_audio_cd = False self.song_list = [] cdaudio.close() raise if self.is_audio_cd: try: self.query_status, self.query_info = CDDB.query(self.disc_id) print "query_status: ", self.query_status print "query_info: ", self.query_info except: print 'IOError' self.song_list = [] cdaudio.close() self.query_status = 409 self.query_info = {"disc_id": "", "category": "", "title":""} pass
def __init__(self): cdaudio = DiscID.open() print "CD: ", cdaudio try: self.disc_id = DiscID.disc_id(cdaudio) print "disc_id: ", self.disc_id self.is_audio_cd = True except: print "No CD" disc_id = None self.is_audio_cd = False self.song_list = [] cdaudio.close() raise if self.is_audio_cd: try: self.query_status, self.query_info = CDDB.query(self.disc_id) print "query_status: ", self.query_status print "query_info: ", self.query_info except: print 'IOError' self.song_list = [] cdaudio.close() self.query_status = 409 self.query_info = {"disc_id": "", "category": "", "title": ""} pass
def run(self): (status, info) = CDDB.query(self._disc_id, client_name="dmusic", client_version="1.0") if status in [200, 210, 211]: if status in [210, 211]: info = sorted(info, key=lambda w: w["category"]) info = info[0] else: self.logdebug('Unable to fetch CDDB info, status=%d', status) (status, info) = CDDB.read(info['category'], info['disc_id']) if status != 210: self.logdebug('Unable to fetch CDDB info, status=%d', status) return gobject.idle_add(self._cb, self._disc_id, info)
def extractAudioCdInfo(self): """ extract the CD info (album art + artist + tracks), and construct the UPnP items""" self.cdrom = DiscID.open(self.device_name) disc_id = DiscID.disc_id(self.cdrom) (query_status, query_info) = CDDB.query(disc_id) if query_status in (210, 211): query_info = query_info[0] (read_status, read_info) = CDDB.read(query_info['category'], query_info['disc_id']) # print query_info['title'] # print disc_id[1] # for i in range(disc_id[1]): # print "Track %.02d: %s" % (i, read_info['TTITLE' + `i`]) track_count = disc_id[1] disc_id = query_info['disc_id'] self.disc_title = query_info['title'].encode('utf-8') tracks = {} for i in range(track_count): tracks[i + 1] = read_info['TTITLE' + ` i `].decode('ISO-8859-1').encode('utf-8') self.name = self.disc_title root_item = Container(None, self.disc_title) # we will sort the item by "track_number" def childs_sort(x, y): return cmp(x.track_number, y.track_number) root_item.sorting_method = childs_sort self.set_root_item(root_item) for number, title in tracks.items(): item = TrackItem(self.device_name, number, "Unknown", title) external_id = "%s_%d" % (disc_id, number) root_item.add_child(item, external_id=external_id) self.info('Sharing audio CD %s' % self.disc_title) reactor.callLater(2, self.checkIfAudioCdStillPresent) self.init_completed()
def main(): dev = None cdrom = None if len(sys.argv) >= 2: dev = sys.argv[1] if dev: cdrom = DiscID.open(dev) else: cdrom = DiscID.open() print "Getting disc id in CDDB format...", disc_id = DiscID.disc_id(cdrom) print "Disc ID: %08lx Num tracks: %d" % (disc_id[0], disc_id[1]) print "Querying CDDB for info on disc...", (query_stat, query_info) = CDDB.query(disc_id) if query_stat == 200: print("success!\nQuerying CDDB for track info of `%s'... " % query_info['title']), (read_stat, read_info) = CDDB.read(query_info['category'], query_info['disc_id']) if read_stat == 210: print "success!" # Start from 0, not 1 # thanks to bgp for the fix! for i in range(0, disc_id[1]): print "Track %.02d: %s" % (i + 1, read_info['TTITLE' + repr(i)]) else: print "failure getting track info, status: %i" % read_stat elif query_stat == 210 or query_stat == 211: print "multiple matches found! Matches are:" for i in query_info: print "ID: %s Category: %s Title: %s" % \ (i['disc_id'], i['category'], i['title']) else: print "failure getting disc info, status %i" % query_stat
def get_CDDB_tag(self, query_status, query_info): if self.is_audio_cd: read_status, read_info = CDDB.read(query_info['category'], query_info['disc_id']) print "read status: ", read_status print "read info: ", read_info else: return self.song_list = [] if query_status in [200, 210]: self.is_audio_cd = True self.cddb_disc_id_b10 = self.disc_id[0] self.cddb_disc_id_b16 = query_info['disc_id'] self.total_tracks = self.disc_id[1] if read_status == 210: for i in range(self.disc_id[1]): n = "%.02d" %(i + 1) title = "%s" %(read_info['TTITLE' + `i`]) frame = self.disc_id[i+2] self.song_list.append({"track_number":int(n), "title":title, "num_frame":frame}) print "Song_list: ", self.song_list if read_info['DTITLE']: disc_title = read_info['DTITLE'] else: disc_title = query_info[0]['title'] self.artist, self.album = re.split(" / ", disc_title) if "," in self.artist: a, b = re.split(", ", self.artist) self.artist = b.title() + " " + a.title() try: self.disc_len = read_info['disc_len'] except: self.disc_len = self.disc_id[2+self.disc_id[1]] self.year = read_info['DYEAR'] if read_info['DGENRE']: self.cddb_genre = read_info['DGENRE'] else: self.cddb_genre = query_info[0]['category'] elif read_status in [401, 402, 403, 409, 417]: self.error = read_status else: return elif query_status in [211, 202, 403, 409]: self.error = query_status try: cdaudio.close() except: pass return self.error else: cdaudio.close() return
def query(category, discid, xcode='utf8:utf8'): discinfo = {} tracktitles = {} dump = path.join(path.expanduser("~"), '.cddb', category, discid) try: for line in file(dump): if line.startswith("TTITLE"): track, title = line.split("=", 1) try: track = int(track[6:]) except (ValueError): pass else: tracktitles[track] = \ title.decode('utf-8', 'replace').strip() elif line.startswith("DGENRE"): discinfo['genre'] = line.split('=', 1)[1].strip() elif line.startswith("DTITLE"): dtitle = line.split('=', 1)[1].strip().split(' / ', 1) if len(dtitle) == 2: discinfo['artist'], discinfo['title'] = dtitle else: discinfo['title'] = dtitle[0].strip() elif line.startswith("DYEAR"): discinfo['year'] = line.split('=', 1)[1].strip() except EnvironmentError: pass else: return discinfo, tracktitles read, info = CDDB.read(category, discid, **CLIENTINFO) if read != 210: return None try: os.makedirs(path.join(path.expanduser("~"), '.cddb')) except EnvironmentError: pass try: save = file(dump, 'w') keys = info.keys() keys.sort() for key in keys: print>>save, "%s=%s" % (key, info[key]) save.close() except EnvironmentError: pass xf, xt = xcode.split(':') for key, value in info.iteritems(): try: value = value.decode('utf-8', 'replace').strip().encode( xf, 'replace').decode(xt, 'replace') except AttributeError: pass if key.startswith('TTITLE'): try: tracktitles[int(key[6:])] = value except ValueError: pass elif key == 'DGENRE': discinfo['genre'] = value elif key == 'DTITLE': dtitle = value.strip().split(' / ', 1) if len(dtitle) == 2: discinfo['artist'], discinfo['title'] = dtitle else: discinfo['title'] = dtitle[0].strip() elif key == 'DYEAR': discinfo['year'] = value return discinfo, tracktitles
def set_category(self, cat): self._clear_md() cache_path = os.path.join(self.cache_dir, '{0}-{1}'.format(self.fingerprint, cat)) for k,v in cached(lambda:CDDB.read(cat, self.fingerprint)[1])(cache_path).items(): if not v or k[0] not in 'DTE': continue elif k == 'DTITLE': self.metadata[0]['artist'],_,self.metadata[0]['title'] = v.partition(' / ') elif k == 'DGENRE': self.metadata[0]['genre'] = v elif k == 'DYEAR': self.metadata[0]['year'] = v elif k.startswith('TTITLE'): self.metadata[int(k[6:])+1]['title'] = v
def query(self, device): cdromfd = cdrom.audiocd_open(device) disc_id = cdrom.audiocd_id(cdromfd) if kaa.metadata.USE_NETWORK: try: (query_stat, query_info) = CDDB.query(disc_id) except Exception, e: # Oops no connection query_stat = 404
def extractAudioCdInfo (self): """ extract the CD info (album art + artist + tracks), and construct the UPnP items""" self.cdrom = DiscID.open(self.device_name) disc_id = DiscID.disc_id(self.cdrom) (query_status, query_info) = CDDB.query(disc_id) if query_status in (210, 211): query_info = query_info[0] (read_status, read_info) = CDDB.read(query_info['category'], query_info['disc_id']) # print query_info['title'] # print disc_id[1] # for i in range(disc_id[1]): # print "Track %.02d: %s" % (i, read_info['TTITLE' + `i`]) track_count = disc_id[1] disc_id = query_info['disc_id'] self.disc_title = query_info['title'].encode('utf-8') tracks = {} for i in range(track_count): tracks[i + 1] = read_info['TTITLE' + `i`].decode('ISO-8859-1').encode('utf-8') self.name = self.disc_title root_item = Container(None, self.disc_title) # we will sort the item by "track_number" def childs_sort(x, y): return cmp(x.track_number, y.track_number) root_item.sorting_method = childs_sort self.set_root_item(root_item) for number, title in tracks.items(): item = TrackItem(self.device_name, number, "Unknown", title) external_id = "%s_%d" % (disc_id, number) root_item.add_child(item, external_id=external_id) self.info('Sharing audio CD %s', self.disc_title) reactor.callLater(2, self.checkIfAudioCdStillPresent) self.init_completed()
def refresh(self): self.tracks = [] try: self.disc = discid.read() except: logger.debug("Cdrom: Unable to read cd") return logger.debug("Cdrom: reading cd") self.n = len(self.disc.tracks) logger.debug('Cdrom: %d tracks found', self.n) read_info = {} try: self.disc_id = DiscID.disc_id(DiscID.open()) (query_status, query_info) = CDDB.query(self.disc_id) (read_status, read_info) = CDDB.read(query_info['category'], query_info['disc_id']) except: pass if 'DYEAR' in read_info: self.year = read_info['DYEAR'] else: self.year = '' if 'DGENRE' in read_info: self.genre = read_info['DGENRE'] else: self.genre = 'unknown' if 'DTITLE' in read_info: self.albumtitle = self.sanitizeString(read_info['DTITLE']) else: self.albumtitle = 'CD' for track in self.disc.tracks: number = track.number duration = track.seconds key = 'TTITLE' + repr((track.number - 1)) if key in read_info: name = self.sanitizeString(read_info[key]) else: name = 'Cdrom Track %s (%s)' % ( number, time.strftime('%H:%M:%S', time.gmtime(duration))) self.tracks.append((number, name, duration, self.albumtitle, self.genre, self.year))
def extractAudioCdInfo(self): ''' extract the CD info (album art + artist + tracks), and construct the UPnP items ''' self.cdrom = DiscID.open(self.device_name) disc_id = DiscID.disc_id(self.cdrom) (query_status, query_info) = CDDB.query(disc_id) if query_status in (210, 211): query_info = query_info[0] (read_status, read_info) = CDDB.read(query_info['category'], query_info['disc_id']) # print(query_info['title']) # print(disc_id[1]) # for i in range(disc_id[1]): # print(f'Track {i:.02d}: {read_info["TTITLE" + repr(i)]}') track_count = disc_id[1] disc_id = query_info['disc_id'] self.disc_title = query_info['title'].encode('utf-8') tracks = {} for i in range(track_count): tracks[i + 1] = (read_info[f'TTITLE{repr(i)}'].decode( 'ISO-8859-1').encode('utf-8')) self.name = self.disc_title root_item = Container(None, self.disc_title) root_item.sorting_method = 'track_number' self.set_root_item(root_item) for number, title in list(tracks.items()): item = TrackItem(self.device_name, number, 'Unknown', title) external_id = f'{disc_id}_{number:d}' root_item.add_child(item, external_id=external_id) self.info('Sharing audio CD %s', self.disc_title) reactor.callLater(2, self.checkIfAudioCdStillPresent) self.init_completed()
def cddb_query(discid, cache_dir=os.path.expanduser('~/.cache/cddb')): cache_path = os.path.join(cache_dir, '%08x' % discid[0]) query = cached(lambda:CDDB.query(discid)[1])(cache_path, discid) categories = {} if query is None: raise Exception('Server has no data for this disc') if isinstance(query, dict): query = [query] if isinstance(query, list): for q in query: categories[q['category']] = q['title'] return categories
def query(self): def fixchars(pathname): """Fixes characters that cause escaping problems in string constructions used to execute commands on the OS or in the DB""" pathname = pathname.replace(os.sep, "-") pathname = pathname.replace("\"", "") pathname = pathname.replace("?", "") return pathname def padNum(num): if int(num) < 10: return "0" + str(num) else: return str(num) delims = ("/", " - ") def findTitle(title, count): """Tries the delimiters in order until it finds the right one""" #print title #print len(delims) if count < len(delims): titleparts = title.split(delims[count]) #print titleparts if len(titleparts) == 2: self.artistName = fixchars(titleparts[0].strip()) self.albumName = fixchars(titleparts[1].strip()) return True else: return findTitle(title, count+1) return False self.category = fixchars(self.query_info["category"]) self.disc_id = self.query_info["disc_id"] self.title = fixchars(self.query_info["title"]) if not findTitle(self.title, 0): raise "Title not parsed: %s" % self.title (track_status, track_info) = CDDB.read(self.category, self.disc_id) self.genre = fixchars(track_info['DGENRE']) self.year = track_info['DYEAR'] if track_info.has_key('disc_len'): self.albumlength = str(float(track_info['disc_len']) / 60) + " min." else: self.albumlength = "" self.comments = fixchars(track_info['EXTD']) self.albumtitle = fixchars(track_info['DTITLE']) for (tracknum,trackname) in track_info.items(): if tracknum.find("TTITLE") != -1: num = int(tracknum[len("TTITLE"):]) + 1 self.tracks[padNum(num)] = fixchars(trackname)
def getCDDB(self, cddbdiscid): """ @param cddbdiscid: list of id, tracks, offsets, seconds @rtype: str """ # FIXME: convert to nonblocking? import CDDB code, md = CDDB.query(cddbdiscid) self.debug('CDDB query result: %r, %r', code, md) if code == 200: return md['title'] return None
def __init__(self): self.good = True cdrom = DiscID.open("/dev/sr0") self.disc_id = DiscID.disc_id(cdrom) self.disc_info = [] (status,info) = CDDB.query(self.disc_id) if status == 200: info = [info] elif status != 211 and status != 210: lnp("CDDB: No matches found") self.good = False return for i in info: (status, read_info) = (None,None) for j in range(3): (status,read_info) = CDDB.read(i['category'],i['disc_id']) if status != 210: continue else: break if status == 210: read_info['DISCID'] = i['disc_id'] self.disc_info.append(read_info)
def get_cd_info(): def check_status(status, success_values): cddb_status_msg = { 200: "Success", 211: "Multiple inexact matches were found", 210: "Multiple exact matches were found", 202: "No match found", 403: "Error: database entry is corrupt", 409: "Error: no handshake. (client-side error?)" } debug("CDDB status: %d (%s)"%(status, cddb_status_msg[status])) if status not in success_values: s = ", ".join(success_values) debug("CDDB status error: %d (success: %s)" % (status, s)) return False return True cdrom = DiscID.open() disc_id = DiscID.disc_id(cdrom) debug("CDDB: Tracks in CD: %d"%disc_id[1]) qstatus, qinfo = CDDB.query(disc_id) if not check_status(qstatus, (200, 210)): tracks = ["track%02d"%n for n in xrange(1, disc_id[1]+1)] return "Unknown - Unknown", tracks if isinstance(qinfo, list): qinfo = qinfo[0] debug("CDDB: CD-ID: %s" % qinfo["disc_id"]) status, info = CDDB.read(qinfo['category'], qinfo['disc_id']) check_status(status, (200, 210)) year = info.get("DYEAR") disc_title = year and "%s (%s)"%(qinfo["title"], year) or qinfo["title"] debug("CDDB: Disc title: %s"%disc_title) recode = lambda s: s.decode("iso8859-1").encode("utf-8") get = lambda num: recode(info['TTITLE%d'%num]).title() title = recode(disc_title).title() tracks = map(get, range(disc_id[1])) return title, tracks
def CDDB_lookup(): """ Queries the CDDB for the album """ devices = cdrdao.scan_devices() discid = cdrdao.get_discid(devices[0][0]) (query_status, query_info) = CDDB.query(discid) if query_status != 200: print "Couldn't find match on the freedb" return None (read_status, read_info) = CDDB.read(query_info['category'], query_info['disc_id']) tracks = [] for i in range(int(discid[1])): tracks.append({'number':i+1, 'title': cddb_normalize(read_info["TTITLE{}".format(i)])}) artist, album = read_info['DTITLE'].split('/',1) artist = cddb_normalize(artist.strip()) album = cddb_normalize(album.strip()) obj = {'artist': artist, 'album': album, 'tracks':tracks} return obj
def _lookup_cddb(self): """ returns a cdinfo() instance containing the information we found in cddb, or None if that doesn't work. This method doesn't intentionally throw any exceptions (unlike _lookup_mb) although I'm sure it's possible. """ import DiscID, CDDB if self.cddevice: dev = DiscID.open(self.cddevice) else: dev = DiscID.open() cdid = DiscID.disc_id(dev) tracks = cdid[1] (status, info) = CDDB.query(cdid) if status == 200: (status, info) = CDDB.read(info["category"], info["disc_id"]) elif status == 210 or status == 211: (status, info) = CDDB.read(info[0]["category"], info[0]["disc_id"]) else: return None ret = cdinfo() for key in info.keys(): if key.startswith("TTITLE"): n = int(re.findall("TTITLE([0-9]+)", key)[0]) ret.titles[n] = info[key].encode("ascii", errors="replace") elif key == "DTITLE": (artist, album) = info[key].split("/") ret.artist = artist.strip() ret.album = album.strip() elif key == "DYEAR": ret.releasedate = info[key] wx.LogMessage("cddb succeeded") return ret
def printDisc(disc_info): category = disc_info["category"] disc_id = disc_info["disc_id"] title = disc_info["title"] (track_status, track_info) = CDDB.read(category, disc_id) print "%s\t(%s)" % (title,category) tracks = {} for (k,v) in track_info.items(): if k.find("TTITLE") != -1: num = int(k[len("TTITLE"):]) + 1 tracks[num] = v tracks.items().sort() for (k,v) in tracks.items(): print "%s. %s" % (k,v)
def CDDB_info(CDINFO, DISCID): # Get some information cdrom = DiscID.open(CDINFO,) disc_id = DiscID.disc_id(cdrom) # Query CDDB print "Querying CDDB ... " (query_status, query_info) = CDDB.query(disc_id) info = False # Check for status messages if (query_status == 200): # 200: success print " success." info = True elif (query_status == 210): # 210: Multiple exact matches if (DISCID is not None): query_info = query_info[DISCID] info = True else: multiple_matches("Multiple exact matches found:", query_info) elif (query_status == 211): # 211: Multiple inexact matches if (DISCID > -1): query_info = query_info[DISCID] info = True else: multiple_matches("Multiple inexact matches found:", query_info) elif (query_status == 202): # 202: No match found print " failed. No match found." else: # Something else went horribly wrong print " failed with status "+str(query_status)+":\n" print "Using: " print query_info return (info, query_info, disc_id)
def CDDB_info(CDINFO, DISCID): # Get some information cdrom = DiscID.open(CDINFO, ) disc_id = DiscID.disc_id(cdrom) # Query CDDB print "Querying CDDB ... " (query_status, query_info) = CDDB.query(disc_id) info = False # Check for status messages if (query_status == 200): # 200: success print " success." info = True elif (query_status == 210): # 210: Multiple exact matches if (DISCID is not None): query_info = query_info[DISCID] info = True else: multiple_matches("Multiple exact matches found:", query_info) elif (query_status == 211): # 211: Multiple inexact matches if (DISCID > -1): query_info = query_info[DISCID] info = True else: multiple_matches("Multiple inexact matches found:", query_info) elif (query_status == 202): # 202: No match found print " failed. No match found." else: # Something else went horribly wrong print " failed with status " + str(query_status) + ":\n" print "Using: " print query_info return (info, query_info, disc_id)
def getCDDB(self, cddbdiscid): """ @param cddbdiscid: list of id, tracks, offsets, seconds @rtype: str """ # FIXME: convert to nonblocking? import CDDB try: code, md = CDDB.query(cddbdiscid) self.debug('CDDB query result: %r, %r', code, md) if code == 200: return md['title'] except IOError, e: # FIXME: for some reason errno is a str ? if e.errno == 'socket error': self._stdout.write("Warning: network error: %r\n" % (e, )) else: raise
def saveDisc(disc_info): category = disc_info["category"] disc_id = disc_info["disc_id"] title = disc_info["title"] (artistName, albumName) = disc_info["title"].split("/") artistName = artistName.strip() albumName = albumName.strip() #Search for existing artist artists = Artist.selectBy(name=artistName) if artists.count() == 0: #Create artist artist = Artist(name=artistName,category=category) else: #Use existing artist artist = artists[0] #Search for existing album albums = Album.selectBy(name=albumName) if albums.count() == 0: #Create album album = Album(disc_id=disc_id,name=albumName,artist=artist) #Create tracks (track_status, track_info) = CDDB.read(category, disc_id) tracks = {} for (k,v) in track_info.items(): if k.find("TTITLE") != -1: num = int(k[len("TTITLE"):]) + 1 tracks[num] = v tracks.items().sort() for (k,v) in tracks.items(): track = Track(num=k,name=v,album=album) print "***Saved in catalogue***" else: print "***Already catalogued***" printDisc(disc_info)
def _get_information_from_result_element(self, result, disc_id): """Catch any information from a CDDB result dictionnary""" title = unicode(result['title'], "iso-8859-1") category = unicode(result['category'], "iso-8859-1") disc = unicode(result['disc_id'], "iso-8859-1") self.artist = title[:title.index(' / ')] self.title = title[title.index(' / ') + 3:] # Get track titles info = CDDB.read(category, disc)[1] for i in range(disc_id[1]): if i + 4 == len(disc_id): # We must calculate last track length in a different way length = disc_id[len(disc_id) - 1] - self.length else: # Calculate track length in seconds length = (disc_id[i + 3] - disc_id[ i + 2]) / 75 self.length += length track_title = unicode(info['TTITLE' + str(i)], "iso-8859-1") self.tracks.append(CompactDiscTrack(i + 1, track_title, length))
def isDisc(self, device): if discinfo.DiscInfo.isDisc(self, device) != 1: return 0 disc_id = DiscID.disc_id(device) if mmpython.USE_NETWORK: try: (query_stat, query_info) = CDDB.query(disc_id) except: # Oops no connection query_stat = 404 else: query_stat = 404 if query_stat == 210 or query_stat == 211: # set this to success query_stat = 200 for i in query_info: if i['title'] != i['title'].upper(): query_info = i break else: query_info = query_info[0] elif query_stat != 200: _debug("failure getting disc info, status %i" % query_stat) if query_stat == 200: qi = query_info['title'].split('/') self.artist = qi[0].strip() self.title = qi[1].strip() for type in ('title', 'artist'): if getattr(self, type) and getattr(self, type)[0] in ('"', '\'') \ and getattr(self, type)[-1] in ('"', '\''): setattr(self, type, getattr(self, type)[1:-1]) (read_stat, read_info) = CDDB.read(query_info['category'], query_info['disc_id']) # id = disc_id + number of tracks #self.id = '%s_%s' % (query_info['disc_id'], disc_id[1]) if read_stat == 210: for i in range(0, disc_id[1]): mi = mediainfo.MusicInfo() mi.title = read_info['TTITLE' + `i`] mi.album = self.title mi.artist = self.artist mi.genre = query_info['category'] mi.codec = 'PCM' mi.samplerate = 44.1 mi.trackno = i+1 mi.trackof = disc_id[1] self.tracks.append(mi) for type in ('title', 'album', 'artist', 'genre'): if getattr(mi, type) and getattr(mi, type)[0] in ('"', '\'') \ and getattr(mi, type)[-1] in ('"', '\''): setattr(mi, type, getattr(mi, type)[1:-1]) else: _debug("failure getting track info, status: %i" % read_stat) # set query_stat to somthing != 200 query_stat = 400 if query_stat != 200: _debug("failure getting disc info, status %i" % query_stat) self.no_caching = 1 for i in range(0, disc_id[1]): mi = mediainfo.MusicInfo() mi.title = 'Track %s' % (i+1) mi.codec = 'PCM' mi.samplerate = 44.1 mi.trackno = i+1 mi.trackof = disc_id[1] self.tracks.append(mi) # read the tracks to generate the title list device = open(device) (first, last) = cdrom.toc_header(device) lmin = 0 lsec = 0 num = 0 for i in range(first, last + 2): if i == last + 1: min, sec, frames = cdrom.leadout(device) else: min, sec, frames = cdrom.toc_entry(device, i) if num: self.tracks[num-1].length = (min-lmin)*60 + (sec-lsec) num += 1 lmin, lsec = min, sec device.close() # correct bad titles for the tracks, containing also the artist for t in self.tracks: if not self.artist or not t.title.startswith(self.artist): break else: for t in self.tracks: t.title = t.title[len(self.artist):].lstrip('/ \t-_') # correct bad titles for the tracks, containing also the title for t in self.tracks: if not self.title or not t.title.startswith(self.title): break else: for t in self.tracks: t.title = t.title[len(self.title):].lstrip('/ \t-_') return 1
# -*- coding: utf-8 -*- # Convert CDROM content to WAV import subprocess import CDDB, DiscID cdrom = DiscID.open() disc_id = DiscID.disc_id(cdrom) (query_status, query_info) = CDDB.query(disc_id) (read_status, read_info) = CDDB.read(query_info["category"], query_info["disc_id"]) for i in range(disc_id[1]): name = "%s.wav" % (read_info["TTITLE" + ` i `]) name = name.replace("\xba", ".") name = name.replace('"', "'") name = name.replace(",", "") name = name.replace(":", "") if i < 9: mplayer_cmd = 'mplayer cdda://%d -ao pcm:file="0%d - %s" ' % (i + 1, i + 1, name) else: mplayer_cmd = 'mplayer cdda://%d -ao pcm:file="%d - %s" ' % (i + 1, i + 1, name) print mplayer_cmd # subprocess.call(mplayer_cmd,shell=True)
tracks.items().sort() for (k,v) in tracks.items(): track = Track(num=k,name=v,album=album) print "***Saved in catalogue***" else: print "***Already catalogued***" printDisc(disc_info) if __name__ == "__main__": device = DiscID.open() discid = DiscID.disc_id(device) (query_status, query_info) = CDDB.query(discid) if type(query_info) is not ListType: saveDisc(query_info) else: cmd = "" choice = 0 print "There is more than one entry." while cmd != "save" and cmd != "quit": print "Choose one:" choices = [] count = 1 for info in query_info: choices.append(count) print "%d) %s" % (count,info["category"]) count = count + 1
for line in fileinput.input(cddb_fullpath, inplace=1): if line != '.\n': print(line, end="") # reads local cddb file try: cddb_file = ConfigObj(cddb_fullpath) disk_title = info2['DTITLE'].split(' / ') for i in range(num_tracks): track_title[i] = track_prefix[i] + cddb_file['TTITLE%s' % (i)] print("Used local cddb data.") except (ConfigObjError): print("Error in local cddb file") cddb_local = False if not cddb_local: (status1, info1) = CDDB.query(disc_id) print("query status = %s" % status1) if status1 == 200: # Entry exist print(info1['title'] + " // " + info1['category']) (status2, info2) = CDDB.read(info1['category'], info1['disc_id']) print("read status = %s" % status2) readtracks = True elif status1 == 210: # Various entries exist, choose blindly the first print(info1[0]['title'] + " // " + info1[0]['category']) (status2, info2) = CDDB.read(info1[0]['category'], info1[0]['disc_id']) print("read status = %s" % status2) if status2 == 210: # Start reading tracks disk_title = info2['DTITLE'].split(' / ') for i in range(num_tracks): track_title[i] = track_prefix[i] + info2['TTITLE%s' % (i)]
if len(sys.argv) >= 2: dev = sys.argv[1] if dev: cdrom = DiscID.open(dev) else: cdrom = DiscID.open() print "Getting disc id in CDDB format...", disc_id = DiscID.disc_id(cdrom) print "Disc ID: %08lx Num tracks: %d" % (disc_id[0], disc_id[1]) print "Querying CDDB for info on disc...", (query_stat, query_info) = CDDB.query(disc_id) if query_stat == 200: print ("success!\nQuerying CDDB for track info of `%s'... " % query_info['title']), (read_stat, read_info) = CDDB.read(query_info['category'], query_info['disc_id']) if read_stat == 210: print "success!" # Start from 0, not 1 # thanks to bgp for the fix! for i in range(0, disc_id[1]): print "Track %.02d: %s" % (i+1, read_info['TTITLE' + `i`]) else: print "failure getting track info, status: %i" % read_stat
def get_CDDB_tag(self, query_status, query_info): if self.is_audio_cd: read_status, read_info = CDDB.read(query_info['category'], query_info['disc_id']) print "read status: ", read_status print "read info: ", read_info else: return self.song_list = [] if query_status in [200, 210]: self.is_audio_cd = True self.cddb_disc_id_b10 = self.disc_id[0] self.cddb_disc_id_b16 = query_info['disc_id'] self.total_tracks = self.disc_id[1] if read_status == 210: for i in range(self.disc_id[1]): n = "%.02d" % (i + 1) title = "%s" % (read_info['TTITLE' + ` i `]) frame = self.disc_id[i + 2] self.song_list.append({ "track_number": int(n), "title": title, "num_frame": frame }) print "Song_list: ", self.song_list if read_info['DTITLE']: disc_title = read_info['DTITLE'] else: disc_title = query_info[0]['title'] self.artist, self.album = re.split(" / ", disc_title) if "," in self.artist: a, b = re.split(", ", self.artist) self.artist = b.title() + " " + a.title() try: self.disc_len = read_info['disc_len'] except: self.disc_len = self.disc_id[2 + self.disc_id[1]] self.year = read_info['DYEAR'] if read_info['DGENRE']: self.cddb_genre = read_info['DGENRE'] else: self.cddb_genre = query_info[0]['category'] elif read_status in [401, 402, 403, 409, 417]: self.error = read_status else: return elif query_status in [211, 202, 403, 409]: self.error = query_status try: cdaudio.close() except: pass return self.error else: cdaudio.close() return
"utf-8").read().splitlines() except NameError: print "I can't find that file! Sure that's the one?" sys.exit() artist_name = track_names.pop(0) album_name = track_names.pop(0) tracks = len(track_names) info = True else: # Otherwise, we're going to get the read_info from CDDB (info, query_info, disc_id) = CDDB_info(CDINFO, options.DISCID) if (info): (read_status, read_info) = CDDB.read(query_info['category'], query_info['disc_id']) album_info = string.split(read_info['DTITLE'], ' / ', 1) artist_name = capcase(album_info[0]) if (len(album_info) <= 1): album_name = capcase(album_info[0]) else: album_name = capcase(album_info[1]) # If the "/" is absent, it is implied that the # artist and disc title are the same, although in this case the name # should rather be specified twice, separated by the delimiter. tracks = disc_id[1] track_names = [] if (options.DEBUG): print "CDDB read (status: %s)" % read_status print "Number of tracks: %d" % tracks
def plugin_album(self, album): discid = calculate_discid(album) try: stat, discs = CDDB.query(discid, **CLIENTINFO) except IOError: ErrorMessage(None, _("Timeout"),_( "Query could not be executed, connection timed out")).run() return info = None if stat in (200,211): xcode = 'utf8:utf8' dlg = gtk.Dialog(_('Select an album')) dlg.set_border_width(6) dlg.set_has_separator(False) dlg.set_resizable(False) dlg.add_buttons(gtk.STOCK_OK, gtk.RESPONSE_OK) dlg.vbox.set_spacing(6) dlg.set_default_response(gtk.RESPONSE_OK) model = gtk.ListStore(str, str, str, str, str, str) for disc in discs: model.append( [disc[s] for s in ('title','category','disc_id')] * 2) box = gtk.ComboBox(model) box.set_active(0) for i in range(3): crt = gtk.CellRendererText() box.pack_start(crt) box.set_attributes(crt, text=i) discinfo = gtk.Label() crosscode = gtk.ListStore(str) crosscode.append(['utf8:utf8']) crosscode.append(['latin1:latin2']) crosscode.append(['latin1:cp1251']) crosscode.append(['latin1:sjis']) crosscode.append(['latin1:euc-jp']) cbo = gtk.ComboBoxEntry(crosscode, column=0) cbo.set_active(0) def update_discinfo(combo): xcode = cbo.child.get_text() t,c,d, title, cat, discid = combo.get_model()[box.get_active()] info = query(cat, discid, xcode=xcode) discinfo.set_markup( make_info_label(info, album, discs[0]['disc_id'])) def crosscode_cddbinfo(combo): try: xf, xt = combo.child.get_text().split(':') for row in model: for show, store in zip(range(0,3), range(3,6)): row[show] = row[store].encode( xf, 'replace').decode(xt, 'replace') except: for row in model: for show, store in zip(range(0,3), range(3,6)): row[show] = row[store] update_discinfo(box) cbo.connect('changed', crosscode_cddbinfo) box.connect('changed', update_discinfo) update_discinfo(box) dlg.vbox.pack_start(gtk.Label( _("Select the album you wish to retrieve."))) dlg.vbox.pack_start(box) dlg.vbox.pack_start(discinfo) dlg.vbox.pack_start(cbo) dlg.vbox.show_all() resp = dlg.run() xcode = cbo.child.get_text() if resp == gtk.RESPONSE_OK: t,c,d, title, cat, discid = model[box.get_active()] (disc, track) = query(cat, discid, xcode=xcode) keys = track.keys() keys.sort() for key, song in zip(keys, album): if 'artist' in disc: song['artist'] = disc['artist'] if 'title' in disc: song['album'] = disc['title'] if 'year' in disc: song['date'] = disc['year'] if 'genre' in disc: song['genre'] = disc['genre'] s = track[key].split("/") if len(s) == 2: song['artist'] = s[0] song['title'] = s[1] else: song['title'] = track[key] song['tracknumber'] = '%d/%d' % (key+1, len(album)) dlg.destroy() else: n = len(album) albumname = album[0]('album') if not albumname: albumname = ngettext('%d track', '%d tracks', n) % n ErrorMessage(None, _("CDDB lookup failed (%s)" % stat), ngettext("%(title)s and %(count)d more...", "%(title)s and %(count)d more...", n-1) % { 'title': album[0]('~basename'), 'count': n-1}).run()
def query(category, discid, xcode='utf8:utf8'): discinfo = {} tracktitles = {} dump = path.join(expanduser("~"), '.cddb', category, discid) try: for line in file(dump): if line.startswith("TTITLE"): track, title = line.split("=", 1) try: track = int(track[6:]) except (ValueError): pass else: tracktitles[track] = \ title.decode('utf-8', 'replace').strip() elif line.startswith("DGENRE"): discinfo['genre'] = line.split('=', 1)[1].strip() elif line.startswith("DTITLE"): dtitle = line.split('=', 1)[1].strip().split(' / ', 1) if len(dtitle) == 2: discinfo['artist'], discinfo['title'] = dtitle else: discinfo['title'] = dtitle[0].strip() elif line.startswith("DYEAR"): discinfo['year'] = line.split('=', 1)[1].strip() except EnvironmentError: pass else: return discinfo, tracktitles read, info = CDDB.read(category, discid, **CLIENTINFO) if read != 210: return None try: os.makedirs(path.join(expanduser("~"), '.cddb')) except EnvironmentError: pass try: save = file(dump, 'w') keys = info.keys() keys.sort() for key in keys: print>>save, "%s=%s" % (key, info[key]) save.close() except EnvironmentError: pass xf, xt = xcode.split(':') for key, value in info.iteritems(): try: value = value.decode('utf-8', 'replace').strip().encode( xf, 'replace').decode(xt, 'replace') except AttributeError: pass if key.startswith('TTITLE'): try: tracktitles[int(key[6:])] = value except ValueError: pass elif key == 'DGENRE': discinfo['genre'] = value elif key == 'DTITLE': dtitle = value.strip().split(' / ', 1) if len(dtitle) == 2: discinfo['artist'], discinfo['title'] = dtitle else: discinfo['title'] = dtitle[0].strip() elif key == 'DYEAR': discinfo['year'] = value return discinfo, tracktitles
def plugin_album(self, album): discid = calculate_discid(album) try: stat, discs = CDDB.query(discid, **CLIENTINFO) except IOError: ErrorMessage(None, _("Timeout"), _( "Query could not be executed, connection timed out")).run() return if stat in (200, 211): xcode = 'utf8:utf8' dlg = Gtk.Dialog(title=_('Select an album')) dlg.set_border_width(6) dlg.set_resizable(False) dlg.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL) dlg.add_buttons(Gtk.STOCK_SAVE, Gtk.ResponseType.OK) dlg.vbox.set_spacing(6) dlg.set_default_response(Gtk.ResponseType.CANCEL) model = Gtk.ListStore(str, str, str, str, str, str) for disc in discs: model.append( [disc[s] for s in ('title', 'category', 'disc_id')] * 2) box = Gtk.ComboBox(model=model) box.set_active(0) for i in range(3): crt = Gtk.CellRendererText() box.pack_start(crt, True) box.add_attribute(crt, "text", i) discinfo = Gtk.Label() crosscode = Gtk.ListStore(str) crosscode.append(['utf8:utf8']) crosscode.append(['latin1:latin2']) crosscode.append(['latin1:cp1251']) crosscode.append(['latin1:sjis']) crosscode.append(['latin1:euc-jp']) cbo = Gtk.ComboBox( model=crosscode, entry_text_column=0, has_entry=True) cbo.set_active(0) def update_discinfo(combo): xcode = cbo.get_child().get_text() model = combo.get_model() t, c, d, title, cat, discid = model[box.get_active()] info = query(cat, discid, xcode=xcode) discinfo.set_markup( make_info_label(info, album, discs[0]['disc_id'])) def crosscode_cddbinfo(combo): try: xf, xt = combo.get_child().get_text().split(':') for row in model: for show, store in zip(range(0, 3), range(3, 6)): row[show] = row[store].encode( xf, 'replace').decode(xt, 'replace') except: for row in model: for show, store in zip(range(0, 3), range(3, 6)): row[show] = row[store] update_discinfo(box) cbo.connect('changed', crosscode_cddbinfo) box.connect('changed', update_discinfo) update_discinfo(box) dlg.vbox.pack_start(Gtk.Label( _("Select the album you wish to retrieve.")), True, True, 0) dlg.vbox.pack_start(box, True, True, 0) dlg.vbox.pack_start(discinfo, True, True, 0) dlg.vbox.pack_start(cbo, True, True, 0) dlg.vbox.show_all() resp = dlg.run() xcode = cbo.get_child().get_text() if resp == Gtk.ResponseType.OK: t, c, d, title, cat, discid = model[box.get_active()] (disc, track) = query(cat, discid, xcode=xcode) keys = track.keys() keys.sort() for key, song in zip(keys, album): if 'artist' in disc: song['artist'] = disc['artist'] if 'title' in disc: song['album'] = disc['title'] if 'year' in disc: song['date'] = disc['year'] if 'genre' in disc: song['genre'] = disc['genre'] s = track[key].split("/") if len(s) == 2: song['artist'] = s[0] song['title'] = s[1] else: song['title'] = track[key] song['tracknumber'] = '%d/%d' % (key + 1, len(album)) dlg.destroy() else: n = len(album) albumname = album[0]('album') if not albumname: albumname = ngettext('%d track', '%d tracks', n) % n ErrorMessage(None, _("CDDB lookup failed (%s)" % stat), ngettext(u"%(title)s and %(count)d more…", u"%(title)s and %(count)d more…", n - 1) % { 'title': album[0]('~basename'), 'count': n - 1}).run()
def search_by_id(discid): try: stat, discs = CDDB.query(discid, **CLIENTINFO) except EnvironmentError, e: raise RetrievalError(e.strerror)