Exemplo n.º 1
0
    def handleOptions(self, options):
        options.track_template = options.track_template.decode('utf-8')
        options.disc_template = options.disc_template.decode('utf-8')

        if options.offset is None:
            info = drive.getDeviceInfo(self.parentCommand.options.device)
            if info:
                try:
                    options.offset = self.getRootCommand(
                    ).config.getReadOffset(*info)
                    self.stdout.write("Using configured read offset %d\n" %
                                      options.offset)
                except KeyError:
                    pass

        if options.offset is None:
            options.offset = 0
            self.stdout.write("""WARNING: using default offset %d.
Install pycdio and run 'rip offset find' to detect your drive's offset.
""" % options.offset)
        if self.options.output_directory is None:
            self.options.output_directory = os.getcwd()

        if self.options.logger:
            try:
                klazz = result.getLoggers()[self.options.logger]
            except KeyError:
                self.stderr.write("No logger named %s found!\n" %
                                  (self.options.logger))
                raise command.CommandError("No logger named %s" %
                                           self.options.logger)

            self.logger = klazz()
Exemplo n.º 2
0
    def do(self, args):
        runner = task.SyncRunner()
        t = cdparanoia.AnalyzeTask(self.options.device)
        runner.run(t)

        if t.defeatsCache is None:
            self.stdout.write(
                'Cannot analyze the drive.  Is there a CD in it?\n')
            return
        if not t.defeatsCache:
            self.stdout.write(
                'cdparanoia cannot defeat the audio cache on this drive.\n')
        else:
            self.stdout.write(
                'cdparanoia can defeat the audio cache on this drive.\n')

        info = drive.getDeviceInfo(self.options.device)
        if not info:
            return

        self.stdout.write(
            'Adding drive cache behaviour to configuration file.\n')

        self.getRootCommand().config.setDefeatsCache(info[0], info[1], info[2],
            t.defeatsCache)
Exemplo n.º 3
0
Arquivo: cd.py Projeto: tuomo/morituri
    def handleOptions(self, options):
        options.track_template = options.track_template.decode('utf-8')
        options.disc_template = options.disc_template.decode('utf-8')

        if options.offset is None:
            info = drive.getDeviceInfo(self.parentCommand.options.device)
            if info:
                try:
                    options.offset = self.getRootCommand(
                        ).config.getReadOffset(*info)
                    self.stdout.write("Using configured read offset %d\n" %
                        options.offset)
                except KeyError:
                    pass

        if options.offset is None:
            options.offset = 0
            self.stdout.write("""WARNING: using default offset %d.
Install pycdio and run 'rip offset find' to detect your drive's offset.
""" %
                        options.offset)
        if self.options.output_directory is None:
            self.options.output_directory = os.getcwd()

        if self.options.logger:
            try:
                klazz = result.getLoggers()[self.options.logger]
            except KeyError:
                self.stderr.write("No logger named %s found!\n" % (
                    self.options.logger))
                raise command.CommandError("No logger named %s" %
                    self.options.logger)

            self.logger = klazz()
Exemplo n.º 4
0
    def do(self, args):
        runner = task.SyncRunner()
        t = cdparanoia.AnalyzeTask(self.options.device)
        runner.run(t)

        if t.defeatsCache is None:
            self.stdout.write(
                'Cannot analyze the drive.  Is there a CD in it?\n')
            return
        if not t.defeatsCache:
            self.stdout.write(
                'cdparanoia cannot defeat the audio cache on this drive.\n')
        else:
            self.stdout.write(
                'cdparanoia can defeat the audio cache on this drive.\n')

        info = drive.getDeviceInfo(self.options.device)
        if not info:
            self.stdout.write(
                'Drive caching behaviour not saved: could not get device info (requires pycdio).\n'
            )
            return

        self.stdout.write(
            'Adding drive cache behaviour to configuration file.\n')

        self.getRootCommand().config.setDefeatsCache(info[0], info[1], info[2],
                                                     t.defeatsCache)
Exemplo n.º 5
0
    def do(self):
        runner = task.SyncRunner()
        t = cdparanoia.AnalyzeTask(self.options.device)
        runner.run(t)

        if t.defeatsCache is None:
            sys.stdout.write(
                'Cannot analyze the drive.  Is there a CD in it?\n')
            return
        if not t.defeatsCache:
            sys.stdout.write(
                'cdparanoia cannot defeat the audio cache on this drive.\n')
        else:
            sys.stdout.write(
                'cdparanoia can defeat the audio cache on this drive.\n')

        info = drive.getDeviceInfo(self.options.device)
        if not info:
            sys.stdout.write('Drive caching behaviour not saved: could not get device info (requires pycdio).\n')
            return

        sys.stdout.write(
            'Adding drive cache behaviour to configuration file.\n')

        config.Config().setDefeatsCache(info[0], info[1], info[2],
            t.defeatsCache)
Exemplo n.º 6
0
    def _foundOffset(self, device, offset):
        self.stdout.write("\nRead offset of device is: %d.\n" % offset)

        info = drive.getDeviceInfo(device)
        if not info:
            self.stdout.write("Offset not saved: could not get device info (requires pycdio).\n")
            return

        self.stdout.write("Adding read offset to configuration file.\n")

        self.getRootCommand().config.setReadOffset(info[0], info[1], info[2], offset)
Exemplo n.º 7
0
    def _foundOffset(self, device, offset):
        self.stdout.write('\nRead offset of device is: %d.\n' %
            offset)

        info = drive.getDeviceInfo(device)
        if not info:
            return

        self.stdout.write('Adding read offset to configuration file.\n')

        self.getRootCommand().config.setReadOffset(info[0], info[1], info[2],
            offset)
Exemplo n.º 8
0
    def _foundOffset(self, device, offset):
        self.stdout.write('\nRead offset of device is: %d.\n' %
            offset)

        info = drive.getDeviceInfo(device)
        if not info:
            return

        self.stdout.write('Adding read offset to configuration file.\n')

        self.getRootCommand().config.setReadOffset(info[0], info[1], info[2],
            offset)
Exemplo n.º 9
0
    def _foundOffset(self, device, offset):
        sys.stdout.write('\nRead offset of device is: %d.\n' %
            offset)

        info = drive.getDeviceInfo(device)
        if not info:
            sys.stdout.write('Offset not saved: could not get device info (requires pycdio).\n')
            return

        sys.stdout.write('Adding read offset to configuration file.\n')

        config.Config().setReadOffset(info[0], info[1], info[2],
            offset)
Exemplo n.º 10
0
    def add_arguments(self):
        loggers = result.getLoggers().keys()
        default_offset = None
        info = drive.getDeviceInfo(self.opts.device)
        if info:
            try:
                default_offset = config.Config().getReadOffset(*info)
                sys.stdout.write("Using configured read offset %d\n" %
                                  default_offset)
            except KeyError:
                pass

        _CD.add_arguments(self.parser)

        self.parser.add_argument('-L', '--logger',
            action="store", dest="logger", default='morituri',
            help="logger to use (choose from '" + "', '".join(loggers) + "')")
        # FIXME: get from config
        self.parser.add_argument('-o', '--offset',
            action="store", dest="offset", default=default_offset,
            help="sample read offset")
        self.parser.add_argument('-x', '--force-overread',
            action="store_true", dest="overread", default=False,
            help="Force overreading into the lead-out portion of the disc. "
                "Works only if the patched cdparanoia package is installed "
                "and the drive supports this feature. ")
        self.parser.add_argument('-O', '--output-directory',
            action="store", dest="output_directory",
            default=os.path.relpath(os.getcwd()),
            help="output directory; will be included in file paths in log")
        self.parser.add_argument('-W', '--working-directory',
            action="store", dest="working_directory",
            help="working directory; morituri will change to this directory "
                "and files will be created relative to it when not absolute")
        self.parser.add_argument('--track-template',
            action="store", dest="track_template",
            default=DEFAULT_TRACK_TEMPLATE,
            help="template for track file naming (default default)")
        self.parser.add_argument('--disc-template',
            action="store", dest="disc_template",
            default=DEFAULT_DISC_TEMPLATE,
            help="template for disc file naming (default default)")
        self.parser.add_argument('-U', '--unknown',
            action="store_true", dest="unknown",
            help="whether to continue ripping if the CD is unknown",
            default=False)
Exemplo n.º 11
0
    def do(self):
        paths = drive.getAllDevicePaths()
        self.config = config.Config()

        if not paths:
            sys.stdout.write('No drives found.\n')
            sys.stdout.write('Create /dev/cdrom if you have a CD drive, \n')
            sys.stdout.write('or install pycdio for better detection.\n')

            return

        try:
            import cdio as _
        except ImportError:
            sys.stdout.write(
                'Install pycdio for vendor/model/release detection.\n')
            return

        for path in paths:
            vendor, model, release = drive.getDeviceInfo(path)
            sys.stdout.write(
                "drive: %s, vendor: %s, model: %s, release: %s\n" % (
                path, vendor, model, release))

            try:
                offset = self.config.getReadOffset(
                    vendor, model, release)
                sys.stdout.write(
                    "       Configured read offset: %d\n" % offset)
            except KeyError:
                sys.stdout.write(
                    "       No read offset found.  Run 'whipper offset find'\n")

            try:
                defeats = self.config.getDefeatsCache(
                    vendor, model, release)
                sys.stdout.write(
                    "       Can defeat audio cache: %s\n" % defeats)
            except KeyError:
                sys.stdout.write(
                    "       Unknown whether audio cache can be defeated. "
                    "Run 'whipper drive analyze'\n")


        if not paths:
            sys.stdout.write('No drives found.\n')
Exemplo n.º 12
0
    def do(self, args):
        paths = drive.getAllDevicePaths()

        if not paths:
            self.stdout.write('No drives found.\n')
            self.stdout.write('Create /dev/cdrom if you have a CD drive, \n')
            self.stdout.write('or install pycdio for better detection.\n')

            return

        try:
            import cdio as _
        except ImportError:
            self.stdout.write(
                'Install pycdio for vendor/model/release detection.\n')
            return

        for path in paths:
            vendor, model, release = drive.getDeviceInfo(path)
            self.stdout.write(
                "drive: %s, vendor: %s, model: %s, release: %s\n" % (
                path, vendor, model, release))

            try:
                offset = self.getRootCommand().config.getReadOffset(
                    vendor, model, release)
                self.stdout.write(
                    "       Configured read offset: %d\n" % offset)
            except KeyError:
                self.stdout.write(
                    "       No read offset found.  Run 'rip offset find'\n")

            try:
                defeats = self.getRootCommand().config.getDefeatsCache(
                    vendor, model, release)
                self.stdout.write(
                    "       Can defeat audio cache: %s\n" % defeats)
            except KeyError:
                self.stdout.write(
                    "       Unknown whether audio cache can be defeated. "
                    "Run 'rip drive analyze'\n")


        if not paths:
            self.stdout.write('No drives found.\n')
Exemplo n.º 13
0
    def handleOptions(self, options):
        options.track_template = options.track_template.decode('utf-8')
        options.disc_template = options.disc_template.decode('utf-8')

        if options.offset is None:
            info = drive.getDeviceInfo(self.parentCommand.options.device)
            if info:
                try:
                    options.offset = self.getRootCommand(
                    ).config.getReadOffset(*info)
                    self.stdout.write("Using configured read offset %d\n" %
                                      options.offset)
                except KeyError:
                    pass

        if options.offset is None:
            raise ValueError("Drive offset is unconfigured.\n"
                             "Please install pycdio and run 'rip offset "
                             "find' to detect your drive's offset or set it "
                             "manually in the configuration file. It can "
                             "also be specified at runtime using the "
                             "'--offset=value' argument")

        if self.options.output_directory is None:
            self.options.output_directory = os.getcwd()
        else:
            self.options.output_directory = os.path.expanduser(
                self.options.output_directory)

        if self.options.working_directory is not None:
            self.options.working_directory = os.path.expanduser(
                self.options.working_directory)

        if self.options.logger:
            try:
                klazz = result.getLoggers()[self.options.logger]
            except KeyError:
                self.stderr.write("No logger named %s found!\n" %
                                  (self.options.logger))
                raise command.CommandError("No logger named %s" %
                                           self.options.logger)

            self.logger = klazz()
Exemplo n.º 14
0
    def handleOptions(self, options):
        options.track_template = options.track_template.decode('utf-8')
        options.disc_template = options.disc_template.decode('utf-8')

        if options.offset is None:
            info = drive.getDeviceInfo(self.parentCommand.options.device)
            if info:
                try:
                    options.offset = self.getRootCommand(
                        ).config.getReadOffset(*info)
                    self.stdout.write("Using configured read offset %d\n" %
                        options.offset)
                except KeyError:
                    pass

        if options.offset is None:
            options.offset = 0
            self.stdout.write("Using fallback read offset %d\n" %
                        options.offset)
        if self.options.output_directory is None:
            self.options.output_directory = os.getcwd()
Exemplo n.º 15
0
    def do(self):
        self.config = config.Config()
        self.program = program.Program(self.config,
            record=self.options.record,
            stdout=sys.stdout)
        self.runner = task.SyncRunner()

        # if the device is mounted (data session), unmount it
        #self.device = self.parentCommand.options.device
        self.device = self.options.device
        sys.stdout.write('Checking device %s\n' % self.device)

        self.program.loadDevice(self.device)
        self.program.unmountDevice(self.device)

        # first, read the normal TOC, which is fast
        self.ittoc = self.program.getFastToc(self.runner,
            self.options.toc_pickle,
            self.device)

        # already show us some info based on this
        self.program.getRipResult(self.ittoc.getCDDBDiscId())
        sys.stdout.write("CDDB disc id: %s\n" % self.ittoc.getCDDBDiscId())
        self.mbdiscid = self.ittoc.getMusicBrainzDiscId()
        sys.stdout.write("MusicBrainz disc id %s\n" % self.mbdiscid)

        sys.stdout.write("MusicBrainz lookup URL %s\n" %
            self.ittoc.getMusicBrainzSubmitURL())

        self.program.metadata = self.program.getMusicBrainz(self.ittoc,
            self.mbdiscid,
            release=self.options.release_id,
            country=self.options.country,
            prompt=self.options.prompt)

        if not self.program.metadata:
            # fall back to FreeDB for lookup
            cddbid = self.ittoc.getCDDBValues()
            cddbmd = self.program.getCDDB(cddbid)
            if cddbmd:
                sys.stdout.write('FreeDB identifies disc as %s\n' % cddbmd)

            # also used by rip cd info
            if not getattr(self.options, 'unknown', False):
                if self.eject:
                    self.program.ejectDevice(self.device)
                return -1

        # FIXME ?????
        # Hackish fix for broken commit
        offset = 0
        info = drive.getDeviceInfo(self.device)
        if info:
            try:
                offset = self.config.getReadOffset(*info)
            except KeyError:
                pass

        # now, read the complete index table, which is slower
        self.itable = self.program.getTable(self.runner,
            self.ittoc.getCDDBDiscId(),
            self.ittoc.getMusicBrainzDiscId(), self.device, offset)

        assert self.itable.getCDDBDiscId() == self.ittoc.getCDDBDiscId(), \
            "full table's id %s differs from toc id %s" % (
                self.itable.getCDDBDiscId(), self.ittoc.getCDDBDiscId())
        assert self.itable.getMusicBrainzDiscId() == \
            self.ittoc.getMusicBrainzDiscId(), \
            "full table's mb id %s differs from toc id mb %s" % (
            self.itable.getMusicBrainzDiscId(),
            self.ittoc.getMusicBrainzDiscId())
        assert self.itable.getAccurateRipURL() == \
            self.ittoc.getAccurateRipURL(), \
            "full table's AR URL %s differs from toc AR URL %s" % (
            self.itable.getAccurateRipURL(), self.ittoc.getAccurateRipURL())

        if self.program.metadata:
            self.program.metadata.discid = self.ittoc.getMusicBrainzDiscId()

        # result

        self.program.result.cdrdaoVersion = cdrdao.getCDRDAOVersion()
        self.program.result.cdparanoiaVersion = \
            cdparanoia.getCdParanoiaVersion()
        info = drive.getDeviceInfo(self.device)
        if info:
            try:
                self.program.result.cdparanoiaDefeatsCache = \
                    self.config.getDefeatsCache(*info)
            except KeyError, e:
                logger.debug('Got key error: %r' % (e, ))
Exemplo n.º 16
0
    def do(self, args):
        self.program = program.Program(self.getRootCommand().config,
                                       record=self.getRootCommand().record,
                                       stdout=self.stdout)
        self.runner = task.SyncRunner()

        # if the device is mounted (data session), unmount it
        self.device = self.parentCommand.options.device
        self.stdout.write('Checking device %s\n' % self.device)

        self.program.loadDevice(self.device)
        self.program.unmountDevice(self.device)

        # first, read the normal TOC, which is fast
        self.ittoc = self.program.getFastToc(self.runner,
                                             self.options.toc_pickle,
                                             self.device)

        # already show us some info based on this
        self.program.getRipResult(self.ittoc.getCDDBDiscId())
        self.stdout.write("CDDB disc id: %s\n" % self.ittoc.getCDDBDiscId())
        self.mbdiscid = self.ittoc.getMusicBrainzDiscId()
        self.stdout.write("MusicBrainz disc id %s\n" % self.mbdiscid)

        self.stdout.write("MusicBrainz lookup URL %s\n" %
                          self.ittoc.getMusicBrainzSubmitURL())

        self.program.metadata = self.program.getMusicBrainz(
            self.ittoc,
            self.mbdiscid,
            release=self.options.release_id,
            country=self.options.country,
            prompt=self.options.prompt)

        if not self.program.metadata:
            # fall back to FreeDB for lookup
            cddbid = self.ittoc.getCDDBValues()
            cddbmd = self.program.getCDDB(cddbid)
            if cddbmd:
                self.stdout.write('FreeDB identifies disc as %s\n' % cddbmd)

            # also used by rip cd info
            if not getattr(self.options, 'unknown', False):
                if self.eject:
                    self.program.ejectDevice(self.device)
                return -1

        # Hackish fix for broken commit
        offset = 0
        info = drive.getDeviceInfo(self.parentCommand.options.device)
        if info:
            try:
                offset = self.getRootCommand().config.getReadOffset(*info)
            except KeyError:
                pass

        # now, read the complete index table, which is slower
        self.itable = self.program.getTable(self.runner,
                                            self.ittoc.getCDDBDiscId(),
                                            self.ittoc.getMusicBrainzDiscId(),
                                            self.device, offset)

        assert self.itable.getCDDBDiscId() == self.ittoc.getCDDBDiscId(), \
            "full table's id %s differs from toc id %s" % (
                self.itable.getCDDBDiscId(), self.ittoc.getCDDBDiscId())
        assert self.itable.getMusicBrainzDiscId() == \
            self.ittoc.getMusicBrainzDiscId(), \
            "full table's mb id %s differs from toc id mb %s" % (
            self.itable.getMusicBrainzDiscId(),
            self.ittoc.getMusicBrainzDiscId())
        assert self.itable.getAccurateRipURL() == \
            self.ittoc.getAccurateRipURL(), \
            "full table's AR URL %s differs from toc AR URL %s" % (
            self.itable.getAccurateRipURL(), self.ittoc.getAccurateRipURL())

        if self.program.metadata:
            self.program.metadata.discid = self.ittoc.getMusicBrainzDiscId()

        # result

        self.program.result.cdrdaoVersion = cdrdao.getCDRDAOVersion()
        self.program.result.cdparanoiaVersion = \
            cdparanoia.getCdParanoiaVersion()
        info = drive.getDeviceInfo(self.parentCommand.options.device)
        if info:
            try:
                self.program.result.cdparanoiaDefeatsCache = \
                    self.getRootCommand().config.getDefeatsCache(*info)
            except KeyError, e:
                self.debug('Got key error: %r' % (e, ))
Exemplo n.º 17
0
    def do(self, args):
        prog = program.Program(record=self.getRootCommand().record,
            stdout=self.stdout)
        runner = task.SyncRunner()

        def function(r, t):
            r.run(t)

        # if the device is mounted (data session), unmount it
        device = self.parentCommand.options.device
        self.stdout.write('Checking device %s\n' % device)

        prog.setWorkingDirectory(self.options.working_directory)
        prog.loadDevice(device)
        prog.unmountDevice(device)

        version = None

        # first, read the normal TOC, which is fast
        ptoc = cache.Persister(self.options.toc_pickle or None)
        if not ptoc.object:
            tries = 0
            while True:
                tries += 1
                t = cdrdao.ReadTOCTask(device=device)
                try:
                    function(runner, t)
                    break
                except:
                    if tries > 3:
                        raise
                    self.debug('failed to read TOC after %d tries, retrying' % tries)

            version = t.tasks[1].parser.version
            from pkg_resources import parse_version as V
            # we've built a cdrdao 1.2.3rc2 modified package with the patch
            if V(version) < V('1.2.3rc2p1'):
                self.stdout.write('Warning: cdrdao older than 1.2.3 has a '
                    'pre-gap length bug.\n'
                    'See http://sourceforge.net/tracker/?func=detail'
                    '&aid=604751&group_id=2171&atid=102171\n')
            ptoc.persist(t.table)
        ittoc = ptoc.object
        assert ittoc.hasTOC()

        # already show us some info based on this
        prog.getRipResult(ittoc.getCDDBDiscId())
        self.stdout.write("CDDB disc id: %s\n" % ittoc.getCDDBDiscId())
        mbdiscid = ittoc.getMusicBrainzDiscId()
        self.stdout.write("MusicBrainz disc id %s\n" % mbdiscid)

        self.stdout.write("MusicBrainz lookup URL %s\n" %
            ittoc.getMusicBrainzSubmitURL())

        prog.metadata = prog.getMusicBrainz(ittoc, mbdiscid,
            release=self.options.release_id)

        if not prog.metadata:
            # fall back to FreeDB for lookup
            cddbid = ittoc.getCDDBValues()
            cddbmd = prog.getCDDB(cddbid)
            if cddbmd:
                self.stdout.write('FreeDB identifies disc as %s\n' % cddbmd)

            if not self.options.unknown:
                prog.ejectDevice(device)
                return -1

        # now, read the complete index table, which is slower
        itable = prog.getTable(runner, ittoc.getCDDBDiscId(), device)

        assert itable.getCDDBDiscId() == ittoc.getCDDBDiscId(), \
            "full table's id %s differs from toc id %s" % (
                itable.getCDDBDiscId(), ittoc.getCDDBDiscId())
        assert itable.getMusicBrainzDiscId() == ittoc.getMusicBrainzDiscId(), \
            "full table's mb id %s differs from toc id mb %s" % (
            itable.getMusicBrainzDiscId(), ittoc.getMusicBrainzDiscId())
        assert itable.getAccurateRipURL() == ittoc.getAccurateRipURL(), \
            "full table's AR URL %s differs from toc AR URL %s" % (
            itable.getAccurateRipURL(), ittoc.getAccurateRipURL())

        prog.outdir = self.options.output_directory
        prog.outdir = prog.outdir.decode('utf-8')
        # here to avoid import gst eating our options
        from morituri.common import encode
        profile = encode.PROFILES[self.options.profile]()

        # result

        prog.result.cdrdaoVersion = version
        prog.result.cdparanoiaVersion = cdparanoia.getCdParanoiaVersion()
        info = drive.getDeviceInfo(self.parentCommand.options.device)
        if info:
            try:
                prog.result.cdparanoiaDefeatsCache = self.getRootCommand(
                    ).config.getDefeatsCache(*info)
            except KeyError, e:
                self.debug('Got key error: %r' % (e, ))
Exemplo n.º 18
0
    def do(self, args):
        self.program = program.Program(record=self.getRootCommand().record,
            stdout=self.stdout)
        self.runner = task.SyncRunner()

        # if the device is mounted (data session), unmount it
        self.device = self.parentCommand.options.device
        self.stdout.write('Checking device %s\n' % self.device)

        self.program.loadDevice(self.device)
        self.program.unmountDevice(self.device)

        # first, read the normal TOC, which is fast
        self.ittoc, version = self.program.getFastToc(self.runner,
            self.options.toc_pickle,
            self.device)

        # already show us some info based on this
        self.program.getRipResult(self.ittoc.getCDDBDiscId())
        self.stdout.write("CDDB disc id: %s\n" % self.ittoc.getCDDBDiscId())
        self.mbdiscid = self.ittoc.getMusicBrainzDiscId()
        self.stdout.write("MusicBrainz disc id %s\n" % self.mbdiscid)

        self.stdout.write("MusicBrainz lookup URL %s\n" %
            self.ittoc.getMusicBrainzSubmitURL())

        self.program.metadata = self.program.getMusicBrainz(self.ittoc, self.mbdiscid,
            release=self.options.release_id)

        if not self.program.metadata:
            # fall back to FreeDB for lookup
            cddbid = self.ittoc.getCDDBValues()
            cddbmd = self.program.getCDDB(cddbid)
            if cddbmd:
                self.stdout.write('FreeDB identifies disc as %s\n' % cddbmd)

            if not self.options.unknown:
                self.program.ejectDevice(self.device)
                return -1

        # now, read the complete index table, which is slower

        self.itable = self.program.getTable(self.runner,
            self.ittoc.getCDDBDiscId(),
            self.ittoc.getMusicBrainzDiscId(), self.device)

        assert self.itable.getCDDBDiscId() == self.ittoc.getCDDBDiscId(), \
            "full table's id %s differs from toc id %s" % (
                self.itable.getCDDBDiscId(), self.ittoc.getCDDBDiscId())
        assert self.itable.getMusicBrainzDiscId() == self.ittoc.getMusicBrainzDiscId(), \
            "full table's mb id %s differs from toc id mb %s" % (
            self.itable.getMusicBrainzDiscId(), self.ittoc.getMusicBrainzDiscId())
        assert self.itable.getAccurateRipURL() == self.ittoc.getAccurateRipURL(), \
            "full table's AR URL %s differs from toc AR URL %s" % (
            self.itable.getAccurateRipURL(), self.ittoc.getAccurateRipURL())

        # result

        self.program.result.cdrdaoVersion = version
        self.program.result.cdparanoiaVersion = cdparanoia.getCdParanoiaVersion()
        info = drive.getDeviceInfo(self.parentCommand.options.device)
        if info:
            try:
                self.program.result.cdparanoiaDefeatsCache = self.getRootCommand(
                    ).config.getDefeatsCache(*info)
            except KeyError, e:
                self.debug('Got key error: %r' % (e, ))