예제 #1
0
    def do(self):
        runner = ctask.SyncRunner()

        device = self.options.device

        # if necessary, load and unmount
        sys.stdout.write('Checking device %s\n' % device)

        utils.load_device(device)
        utils.unmount_device(device)

        # first get the Table Of Contents of the CD
        t = cdrdao.ReadTOCTask(device)
        table = t.table

        logger.debug("CDDB disc id: %r", table.getCDDBDiscId())
        url = table.getAccurateRipURL()
        logger.debug("AccurateRip URL: %s", url)

        # FIXME: download url as a task too
        responses = []
        import urllib2
        try:
            handle = urllib2.urlopen(url)
            data = handle.read()
            responses = accurip.getAccurateRipResponses(data)
        except urllib2.HTTPError, e:
            if e.code == 404:
                sys.stdout.write('Album not found in AccurateRip database.\n')
                return 1
            else:
                raise
예제 #2
0
    def getFastToc(self, runner, toc_pickle, device):
        """
        Retrieve the normal TOC table from a toc pickle or the drive.
        Also retrieves the cdrdao version

        @rtype: tuple of L{table.Table}, str
        """
        def function(r, t):
            r.run(t)

        ptoc = cache.Persister(toc_pickle or None)
        if not ptoc.object:
            from pkg_resources import parse_version as V
            version = cdrdao.getCDRDAOVersion()
            if V(version) < V('1.2.3rc2'):
                sys.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')
            t = cdrdao.ReadTOCTask(device)
            ptoc.persist(t.table)
        toc = ptoc.object
        assert toc.hasTOC()
        return toc
예제 #3
0
 def getFastToc(self, runner, device):
     """Retrieve the normal TOC table from the drive.
     Also warn about buggy cdrdao versions.
     """
     from pkg_resources import parse_version as V
     version = cdrdao.getCDRDAOVersion()
     if V(version) < V('1.2.3rc2'):
         logger.warning('cdrdao older than 1.2.3 has a pre-gap length bug.'
                        ' See http://sourceforge.net/tracker/?func=detail&aid=604751&group_id=2171&atid=102171')  # noqa: E501
     toc = cdrdao.ReadTOCTask(device).table
     assert toc.hasTOC()
     return toc
예제 #4
0
    def getTable(self, runner, cddbdiscid, mbdiscid, device, offset, toc_path):
        """
        Retrieve the Table either from the cache or the drive.

        :rtype: table.Table
        """
        tcache = cache.TableCache()
        ptable = tcache.get(cddbdiscid, mbdiscid)
        itable = None
        tdict = {}

        # Ignore old cache, since we do not know what offset it used.
        if isinstance(ptable.object, dict):
            tdict = ptable.object

            if offset in tdict:
                itable = tdict[offset]

        if not itable:
            logger.debug(
                'getTable: cddbdiscid %s, mbdiscid %s not in cache '
                'for offset %s, reading table', cddbdiscid, mbdiscid, offset)
            t = cdrdao.ReadTOCTask(device, toc_path=toc_path)
            t.description = "Reading table"
            runner.run(t)
            itable = t.toc.table
            tdict[offset] = itable
            ptable.persist(tdict)
            logger.debug('getTable: read table %r', itable)
        else:
            logger.debug(
                'getTable: cddbdiscid %s, mbdiscid %s in cache '
                'for offset %s', cddbdiscid, mbdiscid, offset)
            logger.debug('getTable: loaded table %r', itable)

        assert itable.hasTOC()

        self.result.table = itable

        logger.debug('getTable: returning table with mb id %s',
                     itable.getMusicBrainzDiscId())
        return itable
예제 #5
0
    def getTable(self, runner, cddbdiscid, mbdiscid, device, offset, toc_path):
        """
        Retrieve the Table from the drive.

        :rtype: table.Table
        """
        itable = None
        tdict = {}

        t = cdrdao.ReadTOCTask(device, toc_path=toc_path)
        t.description = "Reading table"
        runner.run(t)
        itable = t.toc.table
        tdict[offset] = itable
        logger.debug('getTable: read table %r', itable)

        assert itable.hasTOC()

        self.result.table = itable

        logger.debug('getTable: returning table with mb id %s',
                     itable.getMusicBrainzDiscId())
        return itable
예제 #6
0
파일: offset.py 프로젝트: tlc/whipper
    def do(self):
        runner = ctask.SyncRunner()

        device = self.options.device

        # if necessary, load and unmount
        logger.info('checking device %s', device)

        utils.load_device(device)
        utils.unmount_device(device)

        # first get the Table Of Contents of the CD
        t = cdrdao.ReadTOCTask(device)
        table = t.table

        logger.debug("CDDB disc id: %r", table.getCDDBDiscId())
        responses = None
        try:
            responses = accurip.get_db_entry(table.accuraterip_path())
        except accurip.EntryNotFound:
            logger.warning("AccurateRip entry not found: drive offset "
                           "can't be determined, try again with another disc")
            return

        if responses:
            logger.debug('%d AccurateRip responses found.', len(responses))
            if responses[0].cddbDiscId != table.getCDDBDiscId():
                logger.warning("AccurateRip response discid different: %s",
                               responses[0].cddbDiscId)

        # now rip the first track at various offsets, calculating AccurateRip
        # CRC, and matching it against the retrieved ones

        # archecksums is a tuple of accuraterip checksums: (v1, v2)
        def match(archecksums, track, responses):
            for i, r in enumerate(responses):
                for checksum in archecksums:
                    if checksum == r.checksums[track - 1]:
                        return checksum, i

            return None, None

        for offset in self._offsets:
            logger.info('trying read offset %d...', offset)
            try:
                archecksums = self._arcs(runner, table, 1, offset)
            except task.TaskException as e:

                # let MissingDependency fall through
                if isinstance(e.exception, common.MissingDependencyException):
                    raise e

                if isinstance(e.exception, cdparanoia.FileSizeError):
                    logger.warning('cannot rip with offset %d...', offset)
                    continue

                logger.warning("unknown task exception for offset %d: %s",
                               offset, e)
                logger.warning('cannot rip with offset %d...', offset)
                continue

            logger.debug('AR checksums calculated: %s %s', archecksums)

            c, i = match(archecksums, 1, responses)
            if c:
                count = 1
                logger.debug('matched against response %d', i)
                logger.info('offset of device is likely %d, confirming...',
                            offset)

                # now try and rip all other tracks as well, except for the
                # last one (to avoid readers that can't do overread
                for track in range(2, (len(table.tracks) + 1) - 1):
                    try:
                        archecksums = self._arcs(runner, table, track, offset)
                    except task.TaskException as e:
                        if isinstance(e.exception, cdparanoia.FileSizeError):
                            logger.warning('cannot rip with offset %d...',
                                           offset)
                            continue

                    c, i = match(archecksums, track, responses)
                    if c:
                        logger.debug('matched track %d against response %d',
                                     track, i)
                        count += 1

                if count == len(table.tracks) - 1:
                    self._foundOffset(device, offset)
                    return 0
                else:
                    logger.warning(
                        'only %d of %d tracks matched, '
                        'continuing...', count, len(table.tracks))

        logger.error('no matching offset found. '
                     'Consider trying again with a different disc')