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 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 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 get_device(params): # if user specified device parameter: use user specified device try: device = params["device"] print(messages.user_param("device")) # if no device parameter specified: detect default device except KeyError: print(messages.default_param("device")) device = get_default_device() # output device to be used before returning it print(messages.selected_param("device", device)) return (device)
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 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 gather_isrcs(disc, backend, device): """read the disc in the device with the backend and extract the ISRCs """ backend_output = [] devnull = open(os.devnull, "w") if backend == "libdiscid": pattern = r'[A-Z]{2}[A-Z0-9]{3}\d{2}\d{5}' for track in disc.tracks: if track.isrc: match = re.match(pattern, track.isrc) if match is None: print("no valid ISRC: %s" % track.isrc) else: backend_output.append((track.number, track.isrc)) # redundant to "libdiscid", but this might be handy for prerelease testing elif backend == "discisrc": pattern = \ r'Track\s+([0-9]+)\s+:\s+([A-Z]{2})-?([A-Z0-9]{3})-?(\d{2})-?(\d{5})' try: if sys.platform == "darwin": device = get_real_mac_device(device) proc = Popen([backend, device], stdout=PIPE) isrcout = proc.stdout except OSError as err: backend_error(err) for line in isrcout: line = decode(line) # explicitely decode from pipe ext_logger = logging.getLogger("discisrc") ext_logger.debug(line.rstrip()) # rstrip newline if line.startswith("Track") and len(line) > 12: match = re.search(pattern, line) if match is None: print("can't find ISRC in: %s" % line) continue track_number = int(match.group(1)) isrc = ("%s%s%s%s" % (match.group(2), match.group(3), match.group(4), match.group(5))) backend_output.append((track_number, isrc)) # media_info is a preview version of mediatools, both are for Windows # this does some kind of raw read elif backend in ["mediatools", "media_info"]: pattern = \ r'ISRC\s+([0-9]+)\s+([A-Z]{2})-?([A-Z0-9]{3})-?(\d{2})-?(\d{5})' if backend == "mediatools": args = [backend, "drive", device, "isrc"] else: args = [backend, device] try: proc = Popen(args, stdout=PIPE) isrcout = proc.stdout except OSError as err: backend_error(err) for line in isrcout: line = decode(line) # explicitely decode from pipe ext_logger = logging.getLogger("mediatools") ext_logger.debug(line.rstrip()) # rstrip newline if line.startswith("ISRC") and not line.startswith("ISRCS"): match = re.search(pattern, line) if match is None: print("can't find ISRC in: %s" % line) continue track_number = int(match.group(1)) isrc = ("%s%s%s%s" % (match.group(2), match.group(3), match.group(4), match.group(5))) backend_output.append((track_number, isrc)) # cdrdao will create a temp file and we delete it afterwards # cdrdao is also available for windows # this will also fetch ISRCs from CD-TEXT elif backend == "cdrdao": # no byte pattern, file is opened as unicode pattern = r'[A-Z]{2}[A-Z0-9]{3}\d{2}\d{5}' tmpname = "cdrdao-%s.toc" % datetime.now() tmpname = tmpname.replace(":", "-") # : is invalid on windows tmpfile = os.path.join(tempfile.gettempdir(), tmpname) logger.info("Saving toc in %s..", tmpfile) if os.name == "nt": if device != discid.get_default_device(): logger.warning("cdrdao uses the default device") args = [backend, "read-toc", "-v", "0", tmpfile] else: args = [backend, "read-toc", "--device", device, "-v", "0", tmpfile] try: if options.debug: proc = Popen(args, stdout=devnull) else: proc = Popen(args, stdout=devnull, stderr=devnull) if proc.wait() != 0: print_error("%s returned with %i" % (backend, proc.returncode)) sys.exit(1) except OSError as err: backend_error(err) else: # that file seems to be opened in Unicode mode in Python 3 with open(tmpfile, "r") as toc: track_number = None for line in toc: ext_logger = logging.getLogger("cdrdao") ext_logger.debug(line.rstrip()) # rstrip newline words = line.split() if words: if words[0] == "//": track_number = int(words[2]) elif words[0] == "ISRC" and track_number is not None: isrc = "".join(words[1:]).strip('"- ') match = re.match(pattern, isrc) if match is None: print("no valid ISRC: %s" % isrc) else: backend_output.append((track_number, isrc)) # safeguard against missing trackNumber lines # or duplicated ISRC tags (like in CD-Text) track_number = None finally: try: os.unlink(tmpfile) except OSError: pass devnull.close() return backend_output
def gather_options(argv): global options if sys.platform == "darwin": # That is the device drutil expects and stable # /dev/rdisk1 etc. change with multiple hard disks, dmgs mounted etc. # libdiscid < 0.6.0 can't handle drive numbers default_device = "1" else: default_device = discid.get_default_device() config = ConfigParser() config.read(config_path()) parser = OptionParser(version=script_version(), add_help_option=False) parser.set_usage( "{prog} [options] [user] [device]\n {prog} -h".format( prog=SCRIPTNAME)) parser.add_option("-h", action="callback", callback=print_usage, help="Short usage help") parser.add_option("--help", action="callback", callback=print_help, help="Complete help for the script") parser.add_option("-u", "--user", metavar="USERNAME", help="MusicBrainz username, if not given as argument.") # note that -d previously stand for debug parser.add_option("-d", "--device", metavar="DEVICE", help="CD device with a loaded audio cd, if not given as argument." + " The default is %s." % default_device) parser.add_option("--release-id", metavar="RELEASE_ID", help="Optional MusicBrainz ID of the release." + " This will be gathered if not given.") parser.add_option("-b", "--backend", choices=BACKENDS, metavar="PROGRAM", help="Force using a specific backend to extract ISRCs from the" + " disc. Possible backends are: %s." % ", ".join(BACKENDS) + " They are tried in this order otherwise.") parser.add_option("--browser", metavar="BROWSER", help="Program to open URLs. This will be automatically detected" " for most setups, if not chosen manually.") parser.add_option("--force-submit", action="store_true", default=False, help="Always open TOC/disc ID in browser.") parser.add_option("--server", metavar="SERVER", help="Server to send ISRCs to. Default: %s" % DEFAULT_SERVER) parser.add_option("--debug", action="store_true", default=False, help="Show debug messages." + " Currently shows some backend messages.") parser.add_option("--keyring", action="store_true", dest="keyring", help="Use keyring if available.") parser.add_option("--no-keyring", action="store_false", dest="keyring", help="Disable keyring.") (options, args) = parser.parse_args(argv[1:]) print("%s" % script_version()) # assign positional arguments to options if options.user is None and args: options.user = args[0] args = args[1:] if options.device is None and args: options.device = args[0] args = args[1:] if args: logger.warning("Superfluous arguments: %s", ", ".join(args)) # If an option is set in the config and not overriden on the command line, # assign them to options. if options.keyring is None and config.has_option("general", "keyring"): options.keyring = config.getboolean("general", "keyring") if options.backend is None and config.has_option("general", "backend"): options.backend = config.get("general", "backend") if options.backend not in BACKENDS: print_error("Backend given in config file is not a valid choice.", "Choose a backend from %s" % ", ".join(BACKENDS)) sys.exit(-1) if options.browser is None and config.has_option("general", "browser"): options.browser = config.get("general", "browser") if options.device is None and config.has_option("general", "device"): options.device = config.get("general", "device") if options.server is None and config.has_option("musicbrainz", "server"): options.server = config.get("musicbrainz", "server") if options.user is None and config.has_option("musicbrainz", "user"): options.user = config.get("musicbrainz", "user") # assign remaining options automatically if options.device is None: options.device = default_device options.sane_which = test_which() if options.browser is None: options.browser = find_browser() if options.server is None: options.server = DEFAULT_SERVER if options.keyring is None: options.keyring = True if options.backend and not has_program(options.backend, strict=True): print_error("Chosen backend not found. No ISRC extraction possible!", "Make sure that %s is installed." % options.backend) sys.exit(-1) elif not options.backend: options.backend = find_backend() return options
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 gather_isrcs(disc, backend, device): """read the disc in the device with the backend and extract the ISRCs """ backend_output = [] devnull = open(os.devnull, "w") if backend == "libdiscid": pattern = r'[A-Z]{2}[A-Z0-9]{3}\d{2}\d{5}' for track in disc.tracks: if track.isrc: match = re.match(pattern, track.isrc) if match is None: print("no valid ISRC: %s" % track.isrc) else: backend_output.append((track.number, track.isrc)) # redundant to "libdiscid", but this might be handy for prerelease testing elif backend == "discisrc": pattern = \ r'Track\s+([0-9]+)\s+:\s+([A-Z]{2})-?([A-Z0-9]{3})-?(\d{2})-?(\d{5})' try: if sys.platform == "darwin": device = get_real_mac_device(device) proc = Popen([backend, device], stdout=PIPE) isrcout = proc.stdout except OSError as err: backend_error(err) for line in isrcout: line = decode(line) # explicitely decode from pipe ext_logger = logging.getLogger("discisrc") ext_logger.debug(line.rstrip()) # rstrip newline if line.startswith("Track") and len(line) > 12: match = re.search(pattern, line) if match is None: print("can't find ISRC in: %s" % line) continue track_number = int(match.group(1)) isrc = ("%s%s%s%s" % (match.group(2), match.group(3), match.group(4), match.group(5))) backend_output.append((track_number, isrc)) # media_info is a preview version of mediatools, both are for Windows # this does some kind of raw read elif backend in ["mediatools", "media_info"]: pattern = \ r'ISRC\s+([0-9]+)\s+([A-Z]{2})-?([A-Z0-9]{3})-?(\d{2})-?(\d{5})' if backend == "mediatools": args = [backend, "drive", device, "isrc"] else: args = [backend, device] try: proc = Popen(args, stdout=PIPE) isrcout = proc.stdout except OSError as err: backend_error(err) for line in isrcout: line = decode(line) # explicitely decode from pipe ext_logger = logging.getLogger("mediatools") ext_logger.debug(line.rstrip()) # rstrip newline if line.startswith("ISRC") and not line.startswith("ISRCS"): match = re.search(pattern, line) if match is None: print("can't find ISRC in: %s" % line) continue track_number = int(match.group(1)) isrc = ("%s%s%s%s" % (match.group(2), match.group(3), match.group(4), match.group(5))) backend_output.append((track_number, isrc)) # cdrdao will create a temp file and we delete it afterwards # cdrdao is also available for windows # this will also fetch ISRCs from CD-TEXT elif backend == "cdrdao": # no byte pattern, file is opened as unicode pattern = r'[A-Z]{2}[A-Z0-9]{3}\d{2}\d{5}' tmpname = "cdrdao-%s.toc" % datetime.now() tmpname = tmpname.replace(":", "-") # : is invalid on windows tmpfile = os.path.join(tempfile.gettempdir(), tmpname) logger.info("Saving toc in %s..", tmpfile) if os.name == "nt": if device != discid.get_default_device(): logger.warning("cdrdao uses the default device") args = [backend, "read-toc", "--fast-toc", "-v", "0", tmpfile] else: args = [backend, "read-toc", "--fast-toc", "--device", device, "-v", "0", tmpfile] try: proc = Popen(args, stdout=devnull, stderr=devnull) if proc.wait() != 0: print_error("%s returned with %i" % (backend, proc.returncode)) sys.exit(1) except OSError as err: backend_error(err) else: # that file seems to be opened in Unicode mode in Python 3 with open(tmpfile, "r") as toc: track_number = None for line in toc: ext_logger = logging.getLogger("cdrdao") ext_logger.debug(line.rstrip()) # rstrip newline words = line.split() if words: if words[0] == "//": track_number = int(words[2]) elif words[0] == "ISRC" and track_number is not None: isrc = "".join(words[1:]).strip('"- ') match = re.match(pattern, isrc) if match is None: print("no valid ISRC: %s" % isrc) else: backend_output.append((track_number, isrc)) # safeguard against missing trackNumber lines # or duplicated ISRC tags (like in CD-Text) track_number = None finally: try: os.unlink(tmpfile) except OSError: pass devnull.close() return backend_output
def test_default_device(self): # Can't be empty, in contrast to the test in TestModule device = discid.get_default_device() self.assertTrue(device, "No default device given")
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)
def test_default_device(self): device = discid.get_default_device() self.assertTrue(device is not None, "No default device given")
"python-musicbrainz-ngs-catalog", "0.1", "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)
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 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))