def read_disc(self): try: # calculate disc ID from disc if self._backend == "libdiscid" and not options.force_submit: disc = discid.read(self._device, features=["mcn", "isrc"]) else: disc = discid.read(self._device) self._disc = disc except DiscError as err: print_error("DiscID calculation failed: %s" % err) sys.exit(1)
def get_disk_id(self): try: disc = discid.read(discid.get_default_device()) self.id = disc.id print(self.id) except discid.DiscError: logger.warning("No Disc Found")
def cmd_toc(self, argv): ''' Usage: {cmd} [disc_id] Print a table of contents for the current disc. ''' disc_id = None if argv: disc_id = argv.pop(0) if argv: raise GetoptError("extra arguments: %r" % (argv,)) options = self.options MB = options.mbdb if disc_id is None: try: dev_info = discid.read(device=options.device) except discid.disc.DiscError as e: error("disc error: %s", e) return 1 disc_id = dev_info.id with Pfx("discid %s", disc_id): disc = MB.discs[disc_id] print(disc.title) print(", ".join(disc.artist_names)) for tracknum, recording in enumerate(disc.recordings(), 1): print( tracknum, recording.title, '--', ", ".join(recording.artist_names) ) return 0
def read_disc_info(): while True: open_cd_door() input("Press enter to close the cd door\n\n") close_cd_door() print(f"Reading device: {discid.get_default_device()}\n") # reads from default device try: disc = discid.read() except discid.disc.DiscError as e: print(e) print("\n") read_disc_info() print(f"Disc cddb_id: {disc.freedb_id.upper()}") print(f"The number of tracks is {len(disc.tracks)}") print(f"The total duration in seconds is: {disc.seconds}") enter_shelfmark(disc) # https://www.tutorialspoint.com/How-to-get-Python-exception-text insert_disc(disc) if input("Press enter for the next disc or q to quit: ") == "q": break
def read_disc_id(): try: disc = discid.read(CD_DEVICE) logger.info('Disc identified as %s', disc.id) return disc.id except discid.disc.DiscError: logger.error('Could not identify disc.') return None
def get_disc_id(disc): """ Calculates the identifier of the disc return: identification object from discid package """ return read(disc.devpath)
def _read_disc(): try: disc = discid.read() except discid.DiscError as exception: print("[error] %s" % exception) sys.exit(1) return disc
def read_cd(self): cd_drive = self.wizard.scan_drives_page.combo.currentText() self.status_label.setText('Reading CD drive ' + cd_drive) try: disc = discid.read(str(cd_drive)) except discid.disc.DiscError: self.status_label.setText('Unable to read disc') return None return disc
def complex_example(): disc = discid.read("/dev/cdrom", ["mcn", "isrc"]) print("id:\t%s" % disc.id) print("MCN:\t%s" % disc.mcn) print("length:\t%s" % _length_str(disc.seconds, disc.sectors)) for track in disc.tracks: length = _length_str(track.seconds, track.sectors) print("{num:>2}: {offset:>6} {len}\tISRC: {isrc:13}".format( num=track.number, offset=track.offset, len=length, isrc=track.isrc))
def test_read_put(self): # a read followed with a put, which should clear the features disc = discid.read(features=["mcn", "isrc"]) # read from default drive test_disc = test_discs[0] disc = discid.put(test_disc["first"], test_disc["last"], test_disc["sectors"], test_disc["offsets"]) self.assertTrue(disc.mcn is None) for track in disc.tracks: self.assertTrue(track.isrc is None)
def musicbrainz_lookup(): """ Scans a folder for music files with metadata. Collects metadata information from all music files and assumes they belong to the same album. Produces a simple description of the album that it loads into a KLAP form. """ # Help the user if len(sys.argv) != 2: print "Usage: {} Drive".format(sys.argv[0]) sys.exit(1) tracks = [] musicbrainzngs.set_useragent("KLAP-CDDBAdd", "0.3", "*****@*****.**") disc = discid.read(sys.argv[1]) try: result = musicbrainzngs.get_releases_by_discid(disc.id, includes=["artists","recordings","release-groups"]) except musicbrainzngs.ResponseError: print "Couldn't find that disc in the online database, sorry!" return None else: print "Found disc {}".format(disc.id) subd = None if result.get("disc"): if len(result['disc']['release-list']) == 0: print "Found the disc id, but it didn't have any releases..." return None print "Found a musicbrainz release id" open_url(KLAP_MB_URL.format(result['disc']['release-list'][0]['id'])) sys.exit() elif result.get("cdstub"): artist = normalize(result["cdstub"]["artist"]) album = normalize(result["cdstub"]["title"]) subd = result["cdstub"] c = 1 for track in subd['track-list']: title = normalize(track['title']) tartist = normalize(track['artist']) d = {'number': c, 'title': title} if tartist != artist: d['artist'] = tartist tracks.append(d) c += 1 # Make sure the info is safe for KLAP artist = artist album = album # Make the dict obj = {'artist': artist, 'album': album, 'tracks': tracks, } return obj
def _fetch_disc_info(self): disc = discid.read(self._cdplayer.device_name, ['read', 'msn', 'isrc']) print("id: %s" % disc.id) print("mcn: %s" % disc.mcn) print("submission url:\n%s" % disc.submission_url) for track in disc.tracks: print("{:>2}: {:>4} {:13}".format(track.number, track.seconds, track.isrc)) return disc
def com_discid_default_device(): """ Determine default rom drive to use and grab the discid from inserted disc """ discid.get_default_device() disc = discid.read() common_global.es_inst.com_elastic_index('info', {"id": disc.id, "submission url": disc.submission_url}) return discid
def test_read_simple(self): disc = discid.read() # read from default drive self.assertEqual(len(disc.id), 28, "Invalid Disc ID") self.assertEqual(len(disc.freedb_id), 8, "Invalid FreeDB Disc ID") self.assertTrue(disc.submission_url, "Invalid submission url") self.assertTrue(disc.toc_string, "Invalid toc string") self.assertEqual(disc.last_track_num, len(disc.tracks), "Wrong amount of tracks") self.assertEqual(disc.sectors, disc.tracks[-1].offset + disc.tracks[-1].sectors) for track in disc.tracks: self.assertTrue(track.offset <= disc.sectors, "Invalid offset") if track.number > 1: previous_offset = disc.tracks[track.number - 2].offset self.assertTrue(track.offset >= previous_offset, "Invalid offset series") # additional features should be unset, not empty self.assertTrue(disc.mcn is None) for track in disc.tracks: self.assertTrue(track.isrc is None) # check idempotence (use output again as input to put) disc_id = disc.id freedb_id = disc.freedb_id submission_url = disc.submission_url toc_string = disc.toc_string first = disc.first_track_num last = disc.last_track_num sectors = disc.sectors track_sectors = [track.sectors for track in disc.tracks] track_offsets = [track.offset for track in disc.tracks] disc = discid.put(first, last, sectors, track_offsets) self.assertEqual(disc.id, disc_id, "different id after put") self.assertEqual(disc.freedb_id, freedb_id, "different freedb id after put") self.assertEqual(disc.submission_url, submission_url, "different submission_url after put") self.assertEqual(disc.toc_string, toc_string, "different toc_string after put") self.assertEqual(disc.first_track_num, first, "different first track after put") self.assertEqual(disc.last_track_num, last, "different last track after put") self.assertEqual(disc.sectors, sectors, "different sector count after put") new_offsets = [track.offset for track in disc.tracks] self.assertEqual(new_offsets, track_offsets, "different offsets after put") new_sectors = [track.sectors for track in disc.tracks] self.assertEqual(new_sectors, track_sectors, "different lengths after put")
def test_read_simple(self): disc = discid.read() # read from default drive self.assertEqual(len(disc.id), 28, "Invalid Disc ID") self.assertEqual(len(disc.freedb_id), 8, "Invalid FreeDB Disc ID") self.assertTrue(disc.submission_url, "Invalid submission url") self.assertTrue(disc.toc_string, "Invalid toc string") self.assertEqual(disc.last_track_num, len(disc.tracks), "Wrong amount of tracks") self.assertEqual(disc.sectors, disc.tracks[-1].offset + disc.tracks[-1].sectors) for track in disc.tracks: self.assertTrue(track.offset <= disc.sectors, "Invalid offset") if track.number > 1: previous_offset = disc.tracks[track.number-2].offset self.assertTrue(track.offset >= previous_offset, "Invalid offset series") # additional features should be unset, not empty self.assertTrue(disc.mcn is None) for track in disc.tracks: self.assertTrue(track.isrc is None) # check idempotence (use output again as input to put) disc_id = disc.id freedb_id = disc.freedb_id submission_url = disc.submission_url toc_string = disc.toc_string first = disc.first_track_num last = disc.last_track_num sectors = disc.sectors track_sectors = [track.sectors for track in disc.tracks] track_offsets = [track.offset for track in disc.tracks] disc = discid.put(first, last, sectors, track_offsets) self.assertEqual(disc.id, disc_id, "different id after put") self.assertEqual(disc.freedb_id, freedb_id, "different freedb id after put") self.assertEqual(disc.submission_url, submission_url, "different submission_url after put") self.assertEqual(disc.toc_string, toc_string, "different toc_string after put") self.assertEqual(disc.first_track_num, first, "different first track after put") self.assertEqual(disc.last_track_num, last, "different last track after put") self.assertEqual(disc.sectors, sectors, "different sector count after put") new_offsets = [track.offset for track in disc.tracks] self.assertEqual(new_offsets, track_offsets, "different offsets after put") new_sectors = [track.sectors for track in disc.tracks] self.assertEqual(new_sectors, track_sectors, "different lengths after put")
def complex_example(): device_name = discid.get_default_device() disc = discid.read(device_name, ["mcn", "isrc"]) print("device:\t%s" % device_name) print("id:\t%s" % disc.id) print("MCN:\t%s" % disc.mcn) print("length:\t%s" % _length_str(disc.seconds, disc.sectors)) for track in disc.tracks: length = _length_str(track.seconds, track.sectors) print("{num:>2}: {offset:>6} {len}\tISRC: {isrc:13}".format( num=track.number, offset=track.offset, len=length, isrc=track.isrc))
def test_read_features(self): disc = discid.read(features=["mcn", "isrc"]) # read from default drive self.assertEqual(len(disc.id), 28, "Invalid Disc ID") self.assertTrue(disc.submission_url, "Invalid submission url") if "mcn" in discid.FEATURES: self.assertTrue(disc.mcn is not None) else: self.assertTrue(disc.mcn is None) for track in disc.tracks: if "isrc" in discid.FEATURES: self.assertTrue(track.isrc is not None) else: self.assertTrue(track.isrc is None)
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) for track in self.disc.tracks: number = track.number duration = track.seconds name = 'Cdrom Track %s (%s)' % (number, time.strftime('%H:%M:%S', time.gmtime (duration))) self.tracks.append((number,name,duration))
def test_read_features(self): disc = discid.read(features=["mcn", "isrc"]) # read from default drive self.assertEqual(len(disc.id), 28, "Invalid Disc ID") self.assertTrue(disc.submission_url, "Invalid submission url") self.assertTrue(disc.toc_string, "Invalid toc string") if "mcn" in discid.FEATURES: self.assertTrue(disc.mcn is not None) else: self.assertTrue(disc.mcn is None) for track in disc.tracks: if "isrc" in discid.FEATURES: self.assertTrue(track.isrc is not None) else: self.assertTrue(track.isrc is None)
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) for track in self.disc.tracks: number = track.number duration = track.seconds name = 'Cdrom Track %s (%s)' % ( number, time.strftime('%H:%M:%S', time.gmtime(duration))) self.tracks.append((number, name, duration))
def read(self): try: disc_id = discid.read() logger.debug( 'Read disc: MusicBrainz DiscID %s, FreeDB ID %s, %d tracks', disc_id.id, disc_id.freedb_id, len(disc_id.tracks)) except (discid.DiscError, NotImplementedError) as e: logger.info('Error identifying disc: %s', e) self.disc = UNKNOWN_DISC return # use cached disc info if possible if self.disc.discid == disc_id.id: return try: mbrainz_info = musicbrainzngs.get_releases_by_discid( id=disc_id.id, toc=disc_id.toc_string, includes=['artist-credits', 'recordings'], cdstubs=False) # mbrainz_info is either # a {disc: {release-list: [...]}, ...} dict or # a {release-list: [...]} dict when matched by ToC release = mbrainz_info.get('disc', mbrainz_info)['release-list'][0] try: images = musicbrainzngs.get_image_list(release['id']) except musicbrainzngs.ResponseError as e: logger.debug('Error getting CD images from MusicBrainz: %s', e) images = {'images': ()} self.disc = Disc( id=release['id'], discid=disc_id.id, title=release['title'], discs=release['medium-count'], year=release['date'], images=CdRom._extract_images(images['images']), artists=CdRom._extract_artists(release['artist-credit']), tracks=CdRom._extract_tracks(disc_id, release['medium-list'])) except (LookupError, musicbrainzngs.WebServiceError) as e: logger.info('Error accessing MusicBrainz: %s', e) self.disc = UNKNOWN_DISC._replace( discid=disc_id.id, tracks=CdRom._extract_tracks(disc_id))
def loadTreeFromCD(self) -> Tree: self.log.info('Loading CD') disc = discid.read(config.DEV_CDROM) discName, trackNamesByPosition = self.__readNamesFromMB(disc) tree = Tree() rootID = self._idProvider.getNextID() tree.create_node(identifier=rootID, parent=None, data=RootItem(discName)) startsAtSecs = 0 for track in disc.tracks: # type: Track nodeID = self._idProvider.getNextID() position = track.number trackName = self.__getTrackName(position, trackNamesByPosition) lengthInSecs = track.seconds tree.create_node(identifier=nodeID, parent=rootID, data=TrackItem(trackName, position, lengthInSecs, startsAtSecs)) # startAtSecs for next track startsAtSecs += lengthInSecs return tree
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 askForDiscId(): """Asks the user for a CD-ROM device to use. :returns: Three-tuple of the *device*, *disc id*, and number of tracks. """ import discid device, ok = QtWidgets.QInputDialog.getText( mainwindow.mainWindow, translate('AudioCD Plugin', 'Select device'), translate('AudioCD Plugin', 'CDROM device:'), QtWidgets.QLineEdit.Normal, discid.get_default_device()) if not ok: return None try: with discid.read(device) as disc: disc.read() except discid.disc.DiscError as e: dialogs.warning(translate("AudioCD Plugin", "CDROM drive is empty"), str(e)) return None return device, disc.id, len(disc.tracks)
def main(): result = None musicbrainzngs.set_hostname(MUSICBRAINZ_HOST) musicbrainzngs.set_useragent('freedb2musicbrainz.py', __version__, contact='Freso') try: disc = discid.read(features=['mcn']) except discid.disc.DiscError as err: print("Error reading disc: %s" % (err)) exit(1) try: result = musicbrainzngs.get_releases_by_discid(disc.id) except musicbrainzngs.ResponseError as err: print('Disc not currently in MusicBrainz (or bad response): %s' % (err)) if result: if result.get('disc'): print('This release seems to already be in MusicBrainz.') print( 'Check %s to verify that it is the same or submit your specific copy' % (disc.submission_url)) elif result.get("cdstub"): print('There seems to be a CD stub of your disc.') print('Go to %s to add the stub fully into the database.' % (disc.submission_url)) else: print('The release seems to not be in MusicBrainz. Let’s try FreeDB…') freedb = Cddb.CddbServer() print(cddb_lookup_string(disc)) result = freedb.getDiscs(cddb_lookup_string(disc)) if result: for r in result: print(r.artist, "-", r.title) else: print('This release is non-existant! Add it to MB!!') print(disc.submission_url)
def read(self, path): if path != 'cdda://': return None try: import discid except: raise RuntimeError('Cannot import discid. Is it installed?') device_name = discid.get_default_device() disc = discid.read(device_name) tracks = [] for cdda_track in disc.tracks: track = Track() track.path = path track.title = 'CD Audio track' # TODO: read tags from FreeDB track.index = cdda_track.number track.length = cdda_track.seconds track.length_string, track.time_format = self._format_seconds_and_get_format_string( track.length) try: track.offset = tracks[-1].offset + tracks[-1].length except: pass tracks.append(track) return tracks
def rip( device, mbdb, *, output_dirpath, disc_id=None, fstags=None, no_action=False ): ''' Pull audio from `device` and save in `output_dirpath`. ''' if disc_id is None: dev_info = discid.read(device=device) disc_id = dev_info.id if fstags is None: fstags = FSTags() with Pfx("MB: discid %s", disc_id, print=True): disc = mbdb.discs[disc_id] level1 = ", ".join(disc.artist_names).replace(os.sep, '_') or "NO_ARTISTS" level2 = disc.title or "UNTITLED" if disc.medium_count > 1: level2 += f" ({disc.medium_position} of {disc.medium_count})" subdir = joinpath(output_dirpath, level1, level2) if not isdirpath(subdir): with Pfx("makedirs(%r)", subdir, print=True): os.makedirs(subdir) fstags[subdir].update( TagSet(discid=disc.id, title=disc.title, artists=disc.artist_names) ) for tracknum, recording_id in enumerate(disc.recordings, 1): recording = disc.ontology.metadata('recording', recording_id) track_fstags = TagSet( discid=disc.mbkey, artists=recording.artist_names, title=recording.title, track=tracknum ) track_artists = ", ".join(recording.artist_names) track_base = f"{tracknum:02} - {recording.title} -- {track_artists}".replace( os.sep, '-' ) wav_filename = joinpath(subdir, track_base + '.wav') mp3_filename = joinpath(subdir, track_base + '.mp3') if existspath(mp3_filename): warning("MP3 file already exists, skipping track: %r", mp3_filename) else: with NamedTemporaryFile(dir=subdir, prefix=f"cdparanoia--track{tracknum}--", suffix='.wav') as T: if existspath(wav_filename): info("using existing WAV file: %r", wav_filename) else: argv = ['cdparanoia', '-d', '1', '-w', str(tracknum), T.name] if no_action: print(*argv) else: with Pfx("+ %r", argv, print=True): subprocess.run(argv, stdin=subprocess.DEVNULL, check=True) with Pfx("%r => %r", T.name, wav_filename, print=True): os.link(T.name, wav_filename) if no_action: print("fstags[%r].update(%s)" % (wav_filename, track_fstags)) else: fstags[wav_filename].update(track_fstags) fstags[wav_filename].rip_command = argv argv = [ 'lame', '-q', '7', '-V', '0', '--tt', recording.title or "UNTITLED", '--ta', track_artists or "NO ARTISTS", '--tl', level2, ## '--ty',recording year '--tn', str(tracknum), ## '--tg', recording genre ## '--ti', album cover filename wav_filename, mp3_filename ] if no_action: print(*argv) else: with Pfx("+ %r", argv, print=True): subprocess.run(argv, stdin=subprocess.DEVNULL, check=True) fstags[mp3_filename].conversion_command = argv if no_action: print("fstags[%r].update(%s)" % (mp3_filename, track_fstags)) else: fstags[mp3_filename].update(track_fstags) if not no_action: subprocess.run(['ls', '-la', subdir]) os.system("eject")
def simple_example(): disc = discid.read() # use default device print("id: %s" % disc.id) print("used %s as device" % discid.get_default_device()) print("submit with:\n%s" % disc.submission_url)
import discid import pymysql import getpass db = pymysql.connect(host="localhost", user="******", passwd="nopassforyou", db="CD_Database", autocommit=True) cur = db.cursor() disc = discid.read("/dev/cdrom", features=["mcn"]) mcn = disc.mcn if mcn == "": print("DISC UPC NOT FOUND. MANUALLY ENTER") else: print("DISC UPC: %s" % mcn) user = getpass.getuser() sql = "INSERT INTO WeHave(UPC,AddedBy) VALUES ('" + str(mcn) + "','" + str( user) + "');" cur.execute(sql)
def main(): parser = optparse.OptionParser() parser.add_option("-u", "--user", type=str, help="Username") parser.add_option("-p", "--password", type=str, help="Password") parser.add_option("-d", "--device", type=str, default=discid.get_default_device(), help="Device name, the default is %s" % discid.get_default_device()) (args, options) = parser.parse_args() if not args.user: exit("No username given") if not args.password: password = getpass.getpass() else: password = args.password try: disc = discid.read(args.device) except discid.DiscError: exit("No discid could be calculated") musicbrainzngs.auth(args.user, password) musicbrainzngs.set_useragent("isrcsubmit-cdrdao", "0.2", "Mineo@Freenode") results = musicbrainzngs.get_releases_by_discid( disc.id, includes=["recordings", "isrcs", "artist-credits"])["disc"]["release-list"] if len(results) == 0: print "The disc is not in the database" print "Please submit it with: %s" % disc.submission_url exit(1) elif len(results) > 1: print "This Disc ID is ambiguous:" for i, release in enumerate(results): print str(i)+":", release["artist-credit-phrase"] print "-", release["title"] print release["id"] num = -1 while True: try: num = raw_input("Which one do you want? [0-%d] " % i) release = results[int(num)] except (IndexError, ValueError): continue break else: release = results[0] print 'Artist: %s' % release["artist-credit-phrase"] print 'Release: %s' % release["title"] real_medium = None for medium in release["medium-list"]: for mdisc in medium["disc-list"]: print mdisc if mdisc["id"] == disc.id: real_medium = medium break filename = "/tmp/cdrdao-%s.toc" % datetime.now() try: proc = subprocess.Popen(["cdrdao", "read-toc", "--fast-toc", "--device", args.device, "-v", "0", filename], stderr=subprocess.PIPE, stdout=subprocess.PIPE) proc.wait() except Exception, e: exit("Exception while calling cdrdao: %s" % str(e))
def find_disc(cddrive): import discid from lxml import etree root = etree.XML(u'<finddisc></finddisc>') try: disc = discid.read(cddrive, ["mcn", "isrc"]) id = disc.id toc = disc.toc_string except discid.DiscError as err: etree.SubElement(root, "error").text = "Failed to get discid ({})".format(str(err)) log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)) sys.exit(1) etree.SubElement(root, "discid").text = id etree.SubElement(root, "toc").text = toc try: # the "labels" include enables the cat#s we display result = musicbrainzngs.get_releases_by_discid(id, includes=["labels"], toc=toc, cdstubs=False) except musicbrainzngs.ResponseError as err: if err.cause.code == 404: etree.SubElement(root, "error").text = "Disc not found" log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)) sys.exit(1) else: etree.SubElement(root, "error").text = "Received bad response from the MB server" log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)) sys.exit(1) # The result can either be a "disc" or a "cdstub" if result.get('disc'): discnode = etree.SubElement(root, "disc") etree.SubElement(discnode, "sectors").text = result['disc']['sectors'] if "offset-list" in result['disc']: offsets = None for offset in result['disc']['offset-list']: if offsets == None: offsets = str(offset) else: offsets += " " + str(offset) etree.SubElement(discnode, "offsets").text = offsets etree.SubElement(discnode, "tracks").text = str(result['disc']['offset-count']) for release in result['disc']['release-list']: relnode = etree.SubElement(discnode, "release") etree.SubElement(relnode, "title").text = release['title'] etree.SubElement(relnode, "musicbrainzid").text = release['id'] if release.get('barcode'): etree.SubElement(relnode, "barcode").text = release['barcode'] for info in release['label-info-list']: if info.get('catalog-number'): etree.SubElement(relnode, "catalog-number").text = info['catalog-number'] elif result.get('cdstub'): stubnode = etree.SubElement(root, "cdstub") etree.SubElement(stubnode, "artist").text = result['cdstub']['artist'] etree.SubElement(stubnode, "title").text = result['cdstub']['title'] if result['cdstub'].get('barcode'): etree.SubElement(stubnode, "barcode").text = result['cdstub']['barcode'] else: etree.SubElement(root, "error").text = "No valid results" log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)) sys.exit(1) log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)) sys.exit(0)
def find_disc(cddrive): import discid from lxml import etree root = etree.XML(u'<finddisc></finddisc>') try: disc = discid.read(cddrive, ["mcn", "isrc"]) id = disc.id toc = disc.toc_string except discid.DiscError as err: etree.SubElement(root, "error").text = "Failed to get discid ({})".format( str(err)) log( True, convert_etree( etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))) sys.exit(1) etree.SubElement(root, "discid").text = id etree.SubElement(root, "toc").text = toc try: # the "labels" include enables the cat#s we display result = musicbrainzngs.get_releases_by_discid(id, includes=["labels"], toc=toc, cdstubs=False) except musicbrainzngs.ResponseError as err: if err.cause.code == 404: etree.SubElement(root, "error").text = "Disc not found" log( True, convert_etree( etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))) sys.exit(1) else: etree.SubElement( root, "error").text = "Received bad response from the MB server" log( True, convert_etree( etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))) sys.exit(1) # The result can either be a "disc" or a "cdstub" if result.get('disc'): discnode = etree.SubElement(root, "disc") etree.SubElement(discnode, "sectors").text = result['disc']['sectors'] if "offset-list" in result['disc']: offsets = None for offset in result['disc']['offset-list']: if offsets is None: offsets = str(offset) else: offsets += " " + str(offset) etree.SubElement(discnode, "offsets").text = offsets etree.SubElement(discnode, "tracks").text = str( result['disc']['offset-count']) for release in result['disc']['release-list']: relnode = etree.SubElement(discnode, "release") etree.SubElement(relnode, "title").text = release['title'] etree.SubElement(relnode, "musicbrainzid").text = release['id'] if release.get('barcode'): etree.SubElement(relnode, "barcode").text = release['barcode'] for info in release['label-info-list']: if info.get('catalog-number'): etree.SubElement( relnode, "catalog-number").text = info['catalog-number'] elif result.get('cdstub'): stubnode = etree.SubElement(root, "cdstub") etree.SubElement(stubnode, "artist").text = result['cdstub']['artist'] etree.SubElement(stubnode, "title").text = result['cdstub']['title'] if result['cdstub'].get('barcode'): etree.SubElement(stubnode, "barcode").text = result['cdstub']['barcode'] else: etree.SubElement(root, "error").text = "No valid results" log( True, convert_etree( etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))) sys.exit(1) log( True, convert_etree( etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))) sys.exit(0)
def identify(self): """Drrn drrn """ try: disc = discid.read(DEVICE) except discid.disc.DiscError as e: logger.error('[FAIL] %s' % e) logger.error(''.join(traceback.format_exception(*sys.exc_info()))) self.interface.queue_to_identify_interface.send('FAILED_IDENTIFY') return logger.info('[URL] %s' % disc.submission_url) logger.info('[SUCCESS] Identified disc as: %s' % disc.id) ## XXX: The library doesn't understand a tuple here includes = ['artist-credits', 'labels', 'release-rels', 'recordings'] try: data = musicbrainzngs.get_releases_by_discid(disc.id, includes=includes) except musicbrainzngs.ResponseError as e: ## Fake response to make flow easier if e.cause.code == 404: data = { 'disc': { 'id': disc.id, 'release-list': [] } } else: raise except Exception as e: logger.error('[FAIL] %s' % e) logger.error(''.join(traceback.format_exception(*sys.exc_info()))) self.interface.queue_to_identify_interface.send('FAILED_IDENTIFY') return else: if not data: logger.error('[FAIL] No data returned. Check submission url') return try: releases = data['disc']['release-list'] except KeyError: if 'cdstub' in data: logger.warn('[DISC] This release is only a stub, fill it in at MusicBrainz') self.interface.queue_to_identify_interface.send('NO_DATA') return logger.info('[SUCCESS] Got %d releases' % len(releases)) if len(releases) == 0: self.interface.queue_to_identify_interface.send('NO_DATA') self.interface.queue_to_identify_interface.send(disc.submission_url) return elif len(releases) > 1: self.interface.queue_to_identify_interface.send('MULTIPLE_RELEASES') self.interface.queue_to_identify_interface.send(releases) rel_num = self.interface.queue_to_identify_interface.recv() else: rel_num = 0 ## Which release do we want? release = releases[rel_num] ## Disc title title = release['title'] disambiguation = release.get('disambiguation', None) is_remaster = False for rel_release in release.get('release-relation-list', ()): if rel_release.get('type', None) == 'remaster': is_remaster = True break extra_str = '' if disambiguation: extra_str = '%s' % disambiguation if is_remaster: extra_str = '%s remaster' % extra_str extra_str = extra_str.strip() if extra_str: title = '%s (%s)' % (title, extra_str) ## Require release date date = release['date'] if not date: self.interface.queue_to_identify_interface.send('NO_DATE') return year = date.split('-', 1)[0] ## 0th artist... if len(release['artist-credit']) > 1: self.interface.queue_to_identify_interface.send('TOO_MANY_ARTISTS') return artist_sort_name = release['artist-credit'][0]['artist']['sort-name'] artist_sort_name = artist_sort_name ## Media count and name disc_num = 1 if 'medium-count' not in release: disc_count = len(release['medium-list']) else: disc_count = release['medium-count'] medium_n = 0 media_name = None if disc_count > 1: for medium_n, medium in enumerate(release['medium-list']): if 'title' in medium: media_name = medium['title'] else: media_name = None if disc.id in [d['id'] for d in medium['disc-list']]: disc_num = medium_n + 1 break # Pass the media_name along if required, otherwise it's None if media_name is not None and media_name == title: media_name = None ## Unlike the mb example code, disregard different track artists track_tuples = [] for track in release['medium-list'][medium_n]['track-list']: formatted_track_num = '%02d' % int(track['number']) track_title = track['recording']['title'] track_tuple = TrackTuple( disc_id=disc.id, release_id=release['id'], artist=artist_sort_name, year=year, title=title, formatted_track_num=formatted_track_num, track_title=track_title, disc_num=disc_num, disc_count=disc_count, media_name=media_name) track_tuples.append(track_tuple) self.interface.queue_to_identify_interface.send('FINISHED_IDENTIFY') self.interface.queue_to_identify_interface.send(tuple(track_tuples))
def _do_disc(self, spec_device=None): """Read table of contents from a CD-ROM, search for a release, and optionally add to the catalog""" try: import discid except ImportError as e: raise Exception('Could not import discid') default_device = discid.get_default_device() if not spec_device: spec_device = raw_input('Device to read [empty for \'%s\']: ' % default_device) if not spec_device: spec_device = default_device try: disc = discid.read(spec_device) except discid.DiscError as e: raise Exception("DiscID calculation failed: " + str(e)) print('DiscID: %s' % disc.id) print('Submisson URL: %s' % disc.submission_url) try: print("Querying MusicBrainz...") result = mb.get_releases_by_discid(disc.id, includes=["artists"]) print('OK') except mb.ResponseError: _log.warning('Disc not found or bad MusicBrainz response.') self.askBrowseSubmission(disc.submission_url) return else: if result.get("disc"): oneInCatalog = self.printDiscQueryResults(result) elif result.get("cdstub"): for label, key in [('CD Stub', 'id'), ('Artist', 'artist'), ('Title', 'title'), ('Barcode', 'barcode')]: if key in result['cdstub']: print('%10s: %s' % (label, result['cdstub'][key])) # TODO this is broken, needs argument self.askBrowseSubmission() raise Exception('There was only a CD stub.') if len(result['disc']['release-list']) == 0: raise Exception("There were no matches for disc ID: %s" % disc.id) elif len(result['disc']['release-list']) == 1: print("There was one match. " + ('It is already in the catalog. ' if oneInCatalog else '')) if not oneInCatalog: return self.addResultToCatalog(result, 0) else: return oneInCatalog[0] else: print("There were %d matches." % len(result['disc']['release-list'])) choice = raw_input('Choose one result to add (empty for none): ') if not choice.isdigit(): raise Exception('Input was not a number') choice = int(choice) if choice < 0 or choice >= len(result['disc']['release-list']): raise Exception('Input was out of range') return self.addResultToCatalog(result, choice)
def __init__(self, drive): self.disc = discid.read(drive)
def musicbrainz_info(): try: # Read the disc disc_read = discid.read() # Get the disc ID from the read object disc_id = disc_read.id # Also get the submission URL in case of an accident disc_submission = disc_read.submission_url except: print("Please insert a compact disc") sys.exit(0) musicbrainzngs.set_useragent("Tedm ripper", "0.0.1", "*****@*****.**") try: result = musicbrainzngs.get_releases_by_discid(disc_id, includes=['artists', 'labels', 'recordings']) release_list = result['disc']['release-list'][0] number_of_discs = release_list['medium-count'] disc_number_list = list(range(1, (number_of_discs + 1))) disc_string = ', '.join(map(str, disc_number_list)) if number_of_discs > 1: print('This disc is part of a set. You can choose from %s' % disc_string) choice = input('Please enter the proper disc number: ') if not int(choice) in disc_number_list: print("Invalid disc number") sys.exit(0) pretty_disc_number = choice raw_disc_number = int(pretty_disc_number) - 1 else: pretty_disc_number = '1' raw_disc_number = 0 except musicbrainzngs.ResponseError: print("Disc was not found in database, check if available on musicbrainz.org") print(disc_submission) sys.exit(0) except musicbrainzngs.musicbrainz.NetworkError: print("You do not seem to be connected to the internet") sys.exit(0) else: # Define metadata for the entire album album_info_dict = { 'album': release_list['title'], 'album_artist': release_list['artist-credit'][0]['artist']['name'], 'artist': release_list['artist-credit'][0]['artist']['name'], 'date': release_list['date'], 'disc': pretty_disc_number, 'disc_id': result['disc']['id'], 'total_discs': str(number_of_discs), 'total_tracks': release_list['medium-list'][raw_disc_number]['track-count'], } try: album_info_dict['label'] = release_list['label-info-list'][0]['label']['name'] except IndexError: album_info_dict['label'] = '' track_dict = {} for track in release_list['medium-list'][raw_disc_number]['track-list']: title = track['recording']['title'] track_number = track['position'] track_dict[track_number] = title return album_info_dict, track_dict
return data['key'] except KeyError: return default def printIfSet (prefix, key, data, default): "Print the line only if the data is not null" data = getIfSet(key, data, default) if data != default: print prefix, data # get Audio CD details try: disc = discid.read() # reads from default device except discid.DiscError, e: if str(e) == u'cannot read table of contents': print 'Could not read CD.' sys.exit(1) # try to find Audio CD match on MusicBrainz print "\nFetching release data for CD ..." musicbrainzngs.set_useragent(scriptName, scriptVersion, scriptURL) try: discReleases = musicbrainzngs.get_releases_by_discid(disc.id, ['artist-credits', 'recordings'], disc.toc_string, False) except: print sys.exc_info()
#!/usr/bin/env python3 import sys try: import discid except ImportError: print("You have to install discid") print("Maybe run 'pip install discid'?") sys.exit(1) import cddb if __name__ == "__main__": c = cddb.CDDBClient(discid.read()) r = c.query() print(r) for i in r.tracks: print(i)
"https://github.com/rlhelinski/musicbrainz-catalog/", ) c = Catalog() io = InputSplitter() while not io.nextLine('Press enter to read the disc or \'q\' to quit... ').startswith('q'): try: # Read the disc in the default disc drive. If necessary, you can pass # the 'deviceName' parameter to select a different drive. # dev = sys.argv[1] if len(sys.argv) > 1 else discid.get_default_device() io.write ('Reading from %s\n' % dev) disc = discid.read(dev) except discid.DiscError as e: print ("DiscID calculation failed: " + str(e)) continue if (not os.path.isdir('disc-id')): os.mkdir('disc-id') if (not os.path.isdir(os.path.join('disc-id', disc.id))): os.mkdir(os.path.join('disc-id', disc.id)) with open(os.path.join('disc-id', disc.id, 'toc.txt'), 'a') as tocf: print ('DiscID :', disc.id, file=tocf) print ('First Track :', disc.first_track_num, file=tocf) print ('Last Track :', disc.last_track_num, file=tocf) print ('Length :', disc.sectors, 'sectors', file=tocf)
cdda2wav_args = [] if parser.has_option('ripper', 'cdda2wavArgs'): cdda2wav_args = parser.get('ripper', 'cdda2wavArgs').split() ffmpeg_path = parser.get('ripper', 'ffmpegPath') print('Music dir: %s' % music_dir) print('cdda2wav: %s' % cdda2wav_path) print('cdda2wav args: %s' % cdda2wav_args) print('ffmpeg: %s' % ffmpeg_path) # Retrieve information from Musicbrainz print('-' * 79) print('Searching Musicbrainz...') try: disc_id = discid.read().id except Exception as ex: print('Error while searching Musicbrainz: %s' % str(ex)) sys.exit(1) print('Disc id: %s' % disc_id) #call([internet_program_path, mbdisc.getSubmissionUrl(disc)]) #sys.exit(1) try: release = get_release(disc_id) except Exception as ex: print(ex) sys.exit(1) # Release information
def read_disc_metadata(device=CDROM_DEVICE): def simple_md(disc): """ For disc not found, we can derive the tracks and tracks length from the 'disc' object properties. """ print( f'(cdda.py) {disc.last_track_num} tracks found on discid \'{disc.id}\'' ) # https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2#discid # The toc consists of the following: # First track (always 1) # total number of tracks # sector offset of the leadout (end of the disc # a list of sector offsets for each track, beginning with track 1 (generally 150 sectors) # # Example of TOC for a 7 tracks disc: # disc.toc_string: '1 7 235745 150 40742 77847 108042 118682 154277 191952' toc = disc.toc_string.split() # A second of CD-AUDIO has 75 frames (or sectors) -wikipedia- track_sectors = toc[3:] + [toc[2]] track_sectors = [int(x) for x in track_sectors] for i in range(len(track_sectors)): if i == 0: continue trackNum = i trackLen = (track_sectors[i] - track_sectors[i - 1]) / 75 md[str(trackNum)] = { 'title': 'track ' + f'{trackNum}'.zfill(2), 'length': msec2string(trackLen * 1e3) } return md # will complete md with info retrieved from musicbrainz md = CDDA_INFO_TEMPLATE.copy() mz.set_useragent('tmp', '0.1', 'dummy@mail') try: disc = discid.read(device) md['discid'] = disc.id global CDDA_DISCID CDDA_DISCID = disc.id except: print('(cdaa.py) not CDDA found') return md try: result = mz.get_releases_by_discid(disc.id, includes=['artists', 'recordings']) except mz.ResponseError: print('(cdda.py) disc not found or bad response') return simple_md(disc) # most of discs are 'disc' musicbrainz kinf of if result.get('disc'): print(f'(cdda.py) musicbrainz got \'disc\': {disc.id}') mz_md = result['disc']['release-list'][0] md['artist'] = mz_md['artist-credit-phrase'] md['album'] = mz_md['title'] track_list = mz_md['medium-list'][0]['track-list'] # but somo are 'cdstub' musicbrainz kind of elif result.get('cdstub'): print(f'(cdda.py) musicbrainz got \'cdstub\': {disc.id}') mz_md = result['cdstub'] if 'artist' in mz_md: md['artist'] = mz_md['artist'] elif 'artist-credit-phrase' in mz_md: md['artist'] = mz_md['artist-credit-phrase'] if 'title' in mz_md: md['album'] = mz_md['title'] # (!) pending on investigate more on tracks under 'cdstub' if 'track-list' in mz_md: track_list = mz_md['track-list'] else: track_list = [] # Lets complete our track list structure inside the 'md' template for pos, track in enumerate(track_list): # Retrieve track length # from normal 'disc': if 'recording' in track and 'length' in track['recording']: lengthStr = msec2string(float(track['recording']['length'])) # from some 'cdstub': elif 'length' in track: lengthStr = msec2string(float(track['length'])) # from some 'cdstub': elif 'track_or_recording_length' in track: lengthStr = msec2string(float(track['track_or_recording_length'])) else: lengthStr = msec2string(0.0) # Retrieve track title if 'recording' in track and 'title' in track['recording']: track_title = track['recording']['title'] elif 'title' in track: track_title = track['title'] # adding to our metadata disc structure md[str(pos + 1)] = {'title': track_title, 'length': lengthStr} return md
def _do_disc(self, spec_device=None): """Read table of contents from a CD-ROM, search for a release, and optionally add to the catalog""" try: import discid except ImportError as e: raise Exception('Could not import discid') default_device = discid.get_default_device() if not spec_device: spec_device = raw_input('Device to read [empty for \'%s\']: ' % default_device) if not spec_device: spec_device = default_device try: disc = discid.read(spec_device) except discid.DiscError as e: raise Exception("DiscID calculation failed: " + str(e)) print('DiscID: %s' % disc.id) print('Submisson URL: %s' % disc.submission_url) try: print("Querying MusicBrainz...") result = mb.get_releases_by_discid(disc.id, includes=["artists"]) print('OK') except mb.ResponseError: _log.warning('Disc not found or bad MusicBrainz response.') self.askBrowseSubmission(disc.submission_url) return else: if result.get("disc"): oneInCatalog = self.printDiscQueryResults(result) elif result.get("cdstub"): for label, key in [ ('CD Stub', 'id'), ('Artist', 'artist'), ('Title', 'title'), ('Barcode', 'barcode')]: if key in result['cdstub']: print('%10s: %s' % (label, result['cdstub'][key])) # TODO this is broken, needs argument self.askBrowseSubmission() raise Exception('There was only a CD stub.') if len(result['disc']['release-list']) == 0: raise Exception("There were no matches for disc ID: %s" % disc.id) elif len(result['disc']['release-list']) == 1: print("There was one match. " + ('It is already in the catalog. ' if oneInCatalog else '')) if not oneInCatalog: return self.addResultToCatalog(result, 0) else: return oneInCatalog[0] else: print("There were %d matches." % len(result['disc']['release-list'])) choice = raw_input( 'Choose one result to add (empty for none): ') if not choice.isdigit(): raise Exception('Input was not a number') choice = int(choice) if choice < 0 or choice >= len(result['disc']['release-list']): raise Exception('Input was out of range') return self.addResultToCatalog(result, choice)