コード例 #1
0
ファイル: table.py プロジェクト: Emgalai/whipper
    def cue(self, cuePath='', program='whipper'):
        """
        @param cuePath: path to the cue file to be written. If empty,
                        will treat paths as if in current directory.


        Dump our internal representation to a .cue file content.

        @rtype: C{unicode}
        """
        logger.debug('generating .cue for cuePath %r', cuePath)

        lines = []

        def writeFile(path):
            targetPath = common.getRelativePath(path, cuePath)
            line = 'FILE "%s" WAVE' % targetPath
            lines.append(line)
            logger.debug('writeFile: %r' % line)

        # header
        main = ['PERFORMER', 'TITLE']

        for key in CDTEXT_FIELDS:
            if key not in main and key in self.cdtext:
                lines.append("    %s %s" % (key, self.cdtext[key]))

        assert self.hasTOC(), "Table does not represent a full CD TOC"
        lines.append('REM DISCID %s' % self.getCDDBDiscId().upper())
        lines.append('REM COMMENT "%s %s"' % (program, whipper.__version__))

        if self.catalog:
            lines.append("CATALOG %s" % self.catalog)

        for key in main:
            if key in self.cdtext:
                lines.append('%s "%s"' % (key, self.cdtext[key]))

        # FIXME:
        # - the first FILE statement goes before the first TRACK, even if
        #   there is a non-file-using PREGAP
        # - the following FILE statements come after the last INDEX that
        #   use that FILE; so before a next TRACK, PREGAP silence, ...

        # add the first FILE line; EAC always puts the first FILE
        # statement before TRACK 01 and any possible PRE-GAP
        firstTrack = self.tracks[0]
        index = firstTrack.getFirstIndex()
        indexOne = firstTrack.getIndex(1)
        counter = index.counter
        track = firstTrack

        while not index.path:
            t, i = self.getNextTrackIndex(track.number, index.number)
            track = self.tracks[t - 1]
            index = track.getIndex(i)
            counter = index.counter

        if index.path:
            logger.debug('counter %d, writeFile' % counter)
            writeFile(index.path)

        for i, track in enumerate(self.tracks):
            logger.debug('track i %r, track %r' % (i, track))
            # FIXME: skip data tracks for now
            if not track.audio:
                continue

            indexes = track.indexes.keys()
            indexes.sort()

            wroteTrack = False

            for number in indexes:
                index = track.indexes[number]
                logger.debug('index %r, %r' % (number, index))

                # any time the source counter changes to a higher value,
                # write a FILE statement
                # it has to be higher, because we can run into the HTOA
                # at counter 0 here
                if index.counter > counter:
                    if index.path:
                        logger.debug('counter %d, writeFile' % counter)
                        writeFile(index.path)
                    logger.debug('setting counter to index.counter %r' %
                                 index.counter)
                    counter = index.counter

                # any time we hit the first index, write a TRACK statement
                if not wroteTrack:
                    wroteTrack = True
                    line = "  TRACK %02d %s" % (i + 1, 'AUDIO')
                    lines.append(line)
                    logger.debug('%r' % line)

                    for key in CDTEXT_FIELDS:
                        if key in track.cdtext:
                            lines.append('    %s "%s"' %
                                         (key, track.cdtext[key]))

                    if track.isrc is not None:
                        lines.append("    ISRC %s" % track.isrc)

                    if track.pre_emphasis is not None:
                        lines.append("    FLAGS PRE")

                    # handle TRACK 01 INDEX 00 specially
                    if 0 in indexes:
                        index00 = track.indexes[0]
                        if i == 0:
                            # if we have a silent pre-gap, output it
                            if not index00.path:
                                length = indexOne.absolute - index00.absolute
                                lines.append("    PREGAP %s" %
                                             common.framesToMSF(length))
                                continue

                        # handle any other INDEX 00 after its TRACK
                        lines.append("    INDEX "
                                     "%02d %s" %
                                     (0, common.framesToMSF(index00.relative)))

                if number > 0:
                    # index 00 is output after TRACK up above
                    lines.append("    INDEX %02d %s" %
                                 (number, common.framesToMSF(index.relative)))

        lines.append("")

        return "\n".join(lines)
コード例 #2
0
    def logRip(self, ripResult, epoch):
        """Returns logfile lines list"""

        lines = []

        # Ripper version
        lines.append("Log created by: whipper %s (internal logger)" %
                     whipper.__version__)

        # Rip date
        date = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(epoch)).strip()
        lines.append("Log creation date: %s" % date)
        lines.append("")

        # Rip technical settings
        lines.append("Ripping phase information:")
        lines.append("  Drive: %s%s (revision %s)" %
                     (ripResult.vendor, ripResult.model, ripResult.release))
        lines.append("  Extraction engine: cdparanoia %s" %
                     ripResult.cdparanoiaVersion)
        if ripResult.cdparanoiaDefeatsCache is None:
            defeat = "Unknown"
        elif ripResult.cdparanoiaDefeatsCache:
            defeat = "Yes"
        else:
            defeat = "No"
        lines.append("  Defeat audio cache: %s" % defeat)
        lines.append("  Read offset correction: %+d" % ripResult.offset)
        # Currently unsupported by the official cdparanoia package
        over = "No"
        # Only implemented in whipper (ripResult.overread)
        if ripResult.overread:
            over = "Yes"
        lines.append("  Overread into lead-out: %s" % over)
        # Next one fully works only using the patched cdparanoia package
        # lines.append("Fill up missing offset samples with silence: Yes")
        lines.append("  Gap detection: cdrdao %s" % ripResult.cdrdaoVersion)
        if ripResult.isCdr:
            isCdr = "Yes"
        else:
            isCdr = "No"
        lines.append("  CD-R detected: %s" % isCdr)
        lines.append("")

        # CD metadata
        lines.append("CD metadata:")
        lines.append("  Album: %s - %s" % (ripResult.artist, ripResult.title))
        lines.append("  CDDB Disc ID: %s" % ripResult.table.getCDDBDiscId())
        lines.append("  MusicBrainz Disc ID: %s" %
                     ripResult.table.getMusicBrainzDiscId())
        lines.append("  MusicBrainz lookup url: %s" %
                     ripResult.table.getMusicBrainzSubmitURL())
        lines.append("")

        # TOC section
        lines.append("TOC:")
        table = ripResult.table

        # Test for HTOA presence
        htoa = None
        try:
            htoa = table.tracks[0].getIndex(0)
        except KeyError:
            pass

        # If True, include HTOA line into log's TOC
        if htoa and htoa.path:
            htoastart = htoa.absolute
            htoaend = table.getTrackEnd(0)
            htoalength = table.tracks[0].getIndex(1).absolute - htoastart
            lines.append("  00:")
            lines.append("    Start: %s" % common.framesToMSF(htoastart))
            lines.append("    Length: %s" % common.framesToMSF(htoalength))
            lines.append("    Start sector: %d" % htoastart)
            lines.append("    End sector: %d" % htoaend)
            lines.append("")

        # For every track include information in the TOC
        for t in table.tracks:
            # FIXME: what happens to a track start over 60 minutes ?
            # Answer: tested empirically, everything seems OK
            start = t.getIndex(1).absolute
            length = table.getTrackLength(t.number)
            end = table.getTrackEnd(t.number)
            lines.append("  %02d:" % t.number)
            lines.append("    Start: %s" % common.framesToMSF(start))
            lines.append("    Length: %s" % common.framesToMSF(length))
            lines.append("    Start sector: %d" % start)
            lines.append("    End sector: %d" % end)
            lines.append("")

        # Tracks section
        lines.append("Tracks:")
        duration = 0.0
        for t in ripResult.tracks:
            if not t.filename:
                continue
            lines.extend(self.trackLog(t))
            lines.append("")
            duration += t.testduration + t.copyduration

        # Status report
        lines.append("Conclusive status report:")
        arHeading = "  AccurateRip summary:"
        if self._inARDatabase == 0:
            lines.append("%s None of the tracks are present in the "
                         "AccurateRip database" % arHeading)
        else:
            nonHTOA = len(ripResult.tracks)
            if ripResult.tracks[0].number == 0:
                nonHTOA -= 1
            if self._accuratelyRipped == 0:
                lines.append("%s No tracks could be verified as accurate "
                             "(you may have a different pressing from the "
                             "one(s) in the database)" % arHeading)
            elif self._accuratelyRipped < nonHTOA:
                accurateTracks = nonHTOA - self._accuratelyRipped
                lines.append("%s Some tracks could not be verified as "
                             "accurate (%d/%d got no match)" %
                             (arHeading, accurateTracks, nonHTOA))
            else:
                lines.append("%s All tracks accurately ripped" % arHeading)

        hsHeading = "  Health status:"
        if self._errors:
            lines.append("%s There were errors" % hsHeading)
        else:
            lines.append("%s No errors occurred" % hsHeading)
        lines.append("  EOF: End of status report")
        lines.append("")

        # Log hash
        hasher = hashlib.sha256()
        hasher.update("\n".join(lines).encode("utf-8"))
        lines.append("SHA-256 hash: %s" % hasher.hexdigest().upper())
        lines.append("")
        return lines
コード例 #3
0
ファイル: table.py プロジェクト: tobbez/whipper
    def cue(self, cuePath='', program='whipper'):
        """
        @param cuePath: path to the cue file to be written. If empty,
                        will treat paths as if in current directory.


        Dump our internal representation to a .cue file content.

        @rtype: C{unicode}
        """
        logger.debug('generating .cue for cuePath %r', cuePath)

        lines = []

        def writeFile(path):
            targetPath = common.getRelativePath(path, cuePath)
            line = 'FILE "%s" WAVE' % targetPath
            lines.append(line)
            logger.debug('writeFile: %r' % line)

        # header
        main = ['PERFORMER', 'TITLE']

        for key in CDTEXT_FIELDS:
                if key not in main and key in self.cdtext:
                    lines.append("    %s %s" % (key, self.cdtext[key]))

        assert self.hasTOC(), "Table does not represent a full CD TOC"
        lines.append('REM DISCID %s' % self.getCDDBDiscId().upper())
        lines.append('REM COMMENT "%s %s"' % (program, whipper.__version__))

        if self.catalog:
            lines.append("CATALOG %s" % self.catalog)

        for key in main:
            if key in self.cdtext:
                lines.append('%s "%s"' % (key, self.cdtext[key]))

        # FIXME:
        # - the first FILE statement goes before the first TRACK, even if
        #   there is a non-file-using PREGAP
        # - the following FILE statements come after the last INDEX that
        #   use that FILE; so before a next TRACK, PREGAP silence, ...

        # add the first FILE line; EAC always puts the first FILE
        # statement before TRACK 01 and any possible PRE-GAP
        firstTrack = self.tracks[0]
        index = firstTrack.getFirstIndex()
        indexOne = firstTrack.getIndex(1)
        counter = index.counter
        track = firstTrack

        while not index.path:
            t, i = self.getNextTrackIndex(track.number, index.number)
            track = self.tracks[t - 1]
            index = track.getIndex(i)
            counter = index.counter

        if index.path:
            logger.debug('counter %d, writeFile' % counter)
            writeFile(index.path)

        for i, track in enumerate(self.tracks):
            logger.debug('track i %r, track %r' % (i, track))
            # FIXME: skip data tracks for now
            if not track.audio:
                continue

            indexes = track.indexes.keys()
            indexes.sort()

            wroteTrack = False

            for number in indexes:
                index = track.indexes[number]
                logger.debug('index %r, %r' % (number, index))

                # any time the source counter changes to a higher value,
                # write a FILE statement
                # it has to be higher, because we can run into the HTOA
                # at counter 0 here
                if index.counter > counter:
                    if index.path:
                        logger.debug('counter %d, writeFile' % counter)
                        writeFile(index.path)
                    logger.debug('setting counter to index.counter %r' %
                        index.counter)
                    counter = index.counter

                # any time we hit the first index, write a TRACK statement
                if not wroteTrack:
                    wroteTrack = True
                    line = "  TRACK %02d %s" % (i + 1, 'AUDIO')
                    lines.append(line)
                    logger.debug('%r' % line)

                    for key in CDTEXT_FIELDS:
                        if key in track.cdtext:
                            lines.append('    %s "%s"' % (
                                key, track.cdtext[key]))

                    if track.isrc is not None:
                        lines.append("    ISRC %s" % track.isrc)

                    if track.pre_emphasis is not None:
                        lines.append("    FLAGS PRE")

                    # handle TRACK 01 INDEX 00 specially
                    if 0 in indexes:
                        index00 = track.indexes[0]
                        if i == 0:
                            # if we have a silent pre-gap, output it
                            if not index00.path:
                                length = indexOne.absolute - index00.absolute
                                lines.append("    PREGAP %s" %
                                    common.framesToMSF(length))
                                continue

                        # handle any other INDEX 00 after its TRACK
                        lines.append("    INDEX %02d %s" % (0,
                            common.framesToMSF(index00.relative)))

                if number > 0:
                    # index 00 is output after TRACK up above
                    lines.append("    INDEX %02d %s" % (number,
                        common.framesToMSF(index.relative)))

        lines.append("")

        return "\n".join(lines)
コード例 #4
0
ファイル: logger.py プロジェクト: tobbez/whipper
    def logRip(self, ripResult, epoch):
        """Returns logfile lines list"""

        lines = []

        # Ripper version
        lines.append("Log created by: whipper %s (internal logger)" %
                     whipper.__version__)

        # Rip date
        date = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(epoch)).strip()
        lines.append("Log creation date: %s" % date)
        lines.append("")

        # Rip technical settings
        lines.append("Ripping phase information:")
        lines.append("  Drive: %s%s (revision %s)" % (
            ripResult.vendor, ripResult.model, ripResult.release))
        if ripResult.cdparanoiaDefeatsCache is None:
            defeat = "Unknown"
        elif ripResult.cdparanoiaDefeatsCache:
            defeat = "Yes"
        else:
            defeat = "No"
        lines.append("  Defeat audio cache: %s" % defeat)
        lines.append("  Read offset correction: %+d" % ripResult.offset)
        # Currently unsupported by the official cdparanoia package
        over = "No"
        # Only implemented in whipper (ripResult.overread)
        if ripResult.overread:
            over = "Yes"
        lines.append("  Overread into lead-out: %s" % over)
        # Next one fully works only using the patched cdparanoia package
        # lines.append("Fill up missing offset samples with silence: Yes")
        lines.append("  Gap detection: cdrdao %s" % ripResult.cdrdaoVersion)
        lines.append("")

        # CD metadata
        lines.append("CD metadata:")
        lines.append("  Album: %s - %s" % (ripResult.artist, ripResult.title))
        lines.append("  CDDB Disc ID: %s" % ripResult. table.getCDDBDiscId())
        lines.append("  MusicBrainz Disc ID: %s" %
                     ripResult. table.getMusicBrainzDiscId())
        lines.append("  MusicBrainz lookup url: %s" %
                     ripResult. table.getMusicBrainzSubmitURL())
        lines.append("")

        # TOC section
        lines.append("TOC:")
        table = ripResult.table

        # Test for HTOA presence
        htoa = None
        try:
            htoa = table.tracks[0].getIndex(0)
        except KeyError:
            pass

        # If True, include HTOA line into log's TOC
        if htoa and htoa.path:
            htoastart = htoa.absolute
            htoaend = table.getTrackEnd(0)
            htoalength = table.tracks[0].getIndex(1).absolute - htoastart
            lines.append("  00:")
            lines.append("    Start: %s" % common.framesToMSF(htoastart))
            lines.append("    Length: %s" % common.framesToMSF(htoalength))
            lines.append("    Start sector: %d" % htoastart)
            lines.append("    End sector: %d" % htoaend)
            lines.append("")

        # For every track include information in the TOC
        for t in table.tracks:
            # FIXME: what happens to a track start over 60 minutes ?
            # Answer: tested empirically, everything seems OK
            start = t.getIndex(1).absolute
            length = table.getTrackLength(t.number)
            end = table.getTrackEnd(t.number)
            lines.append("  %02d:" % t.number)
            lines.append("    Start: %s" % common.framesToMSF(start))
            lines.append("    Length: %s" % common.framesToMSF(length))
            lines.append("    Start sector: %d" % start)
            lines.append("    End sector: %d" % end)
            lines.append("")

        # Tracks section
        lines.append("Tracks:")
        duration = 0.0
        for t in ripResult.tracks:
            if not t.filename:
                continue
            lines.extend(self.trackLog(t))
            lines.append("")
            duration += t.testduration + t.copyduration

        # Status report
        lines.append("Conclusive status report:")
        arHeading = "  AccurateRip summary:"
        if self._inARDatabase == 0:
            lines.append("%s None of the tracks are present in the "
                         "AccurateRip database" % arHeading)
        else:
            nonHTOA = len(ripResult.tracks)
            if ripResult.tracks[0].number == 0:
                nonHTOA -= 1
            if self._accuratelyRipped == 0:
                lines.append("%s No tracks could be verified as accurate "
                             "(you may have a different pressing from the "
                             "one(s) in the database)" % arHeading)
            elif self._accuratelyRipped < nonHTOA:
                accurateTracks = nonHTOA - self._accuratelyRipped
                lines.append("%s Some tracks could not be verified as "
                             "accurate (%d/%d got no match)" % (
                              arHeading, accurateTracks, nonHTOA))
            else:
                lines.append("%s All tracks accurately ripped" % arHeading)

        hsHeading = "  Health status:"
        if self._errors:
            lines.append("%s There were errors" % hsHeading)
        else:
            lines.append("%s No errors occurred" % hsHeading)
        lines.append("  EOF: End of status report")
        lines.append("")

        # Log hash
        hasher = hashlib.sha256()
        hasher.update("\n".join(lines).encode("utf-8"))
        lines.append("SHA-256 hash: %s" % hasher.hexdigest().upper())
        lines.append("")
        return lines
コード例 #5
0
    def trackLog(self, trackResult):
        """Returns Tracks section lines: data picked from trackResult"""

        lines = []

        # Track number
        lines.append("  %02d:" % trackResult.number)

        # Filename (including path) of ripped track
        lines.append("    Filename: %s" % trackResult.filename)

        # Pre-gap length
        pregap = trackResult.pregap
        if pregap:
            lines.append("    Pre-gap length: %s" % common.framesToMSF(pregap))

        # Peak level
        peak = trackResult.peak / 32768.0
        lines.append("    Peak level: %.6f" % peak)

        # Pre-emphasis status
        # Only implemented in whipper (trackResult.pre_emphasis)
        if trackResult.pre_emphasis:
            preEmph = "Yes"
        else:
            preEmph = "No"
        lines.append("    Pre-emphasis: %s" % preEmph)

        # Extraction speed
        if trackResult.copyspeed:
            lines.append("    Extraction speed: %.1f X" %
                         (trackResult.copyspeed))

        # Extraction quality
        if trackResult.quality and trackResult.quality > 0.001:
            lines.append("    Extraction quality: %.2f %%" %
                         (trackResult.quality * 100.0, ))

        # Ripper Test CRC
        if trackResult.testcrc is not None:
            lines.append("    Test CRC: %08X" % trackResult.testcrc)

        # Ripper Copy CRC
        if trackResult.copycrc is not None:
            lines.append("    Copy CRC: %08X" % trackResult.copycrc)

        # AccurateRip track status
        for v in ('v1', 'v2'):
            if trackResult.AR[v]['DBCRC']:
                lines.append("    AccurateRip %s:" % v)
                self._inARDatabase += 1
                if trackResult.AR[v]['CRC'] == trackResult.AR[v]['DBCRC']:
                    lines.append("      Result: Found, exact match")
                    self._accuratelyRipped += 1
                else:
                    lines.append("      Result: Found, NO exact match")
                lines.append("      Confidence: %d" %
                             trackResult.AR[v]['DBConfidence'])
                lines.append("      Local CRC: %s" %
                             trackResult.AR[v]['CRC'].upper())
                lines.append("      Remote CRC: %s" %
                             trackResult.AR[v]['DBCRC'].upper())
            elif trackResult.number != 0:
                lines.append("    AccurateRip %s:" % v)
                lines.append(
                    "      Result: Track not present in AccurateRip database")

        # Check if Test & Copy CRCs are equal
        if trackResult.testcrc == trackResult.copycrc:
            lines.append("    Status: Copy OK")
        else:
            self._errors = True
            lines.append("    Status: Error, CRC mismatch")
        return lines
コード例 #6
0
ファイル: logger.py プロジェクト: tobbez/whipper
    def trackLog(self, trackResult):
        """Returns Tracks section lines: data picked from trackResult"""

        lines = []

        # Track number
        lines.append("  %02d:" % trackResult.number)

        # Filename (including path) of ripped track
        lines.append("    Filename: %s" % trackResult.filename)

        # Pre-gap length
        pregap = trackResult.pregap
        if pregap:
            lines.append("    Pre-gap length: %s" % common.framesToMSF(pregap))

        # Peak level
        peak = trackResult.peak
        lines.append("    Peak level: %.6f" % peak)

        # Pre-emphasis status
        # Only implemented in whipper (trackResult.pre_emphasis)
        if trackResult.pre_emphasis:
            preEmph = "Yes"
        else:
            preEmph = "No"
        lines.append("    Pre-emphasis: %s" % preEmph)

        # Extraction speed
        if trackResult.copyspeed:
            lines.append("    Extraction speed: %.1f X" % (
                trackResult.copyspeed))

        # Extraction quality
        if trackResult.quality and trackResult.quality > 0.001:
            lines.append("    Extraction quality: %.2f %%" %
                         (trackResult.quality * 100.0, ))

        # Ripper Test CRC
        if trackResult.testcrc is not None:
            lines.append("    Test CRC: %08X" % trackResult.testcrc)

        # Ripper Copy CRC
        if trackResult.copycrc is not None:
            lines.append("    Copy CRC: %08X" % trackResult.copycrc)

        # AccurateRip track status
        # Currently there's no support for AccurateRip V2
        if trackResult.accurip:
            lines.append("    AccurateRip V1:")
            self._inARDatabase += 1
            if trackResult.ARCRC == trackResult.ARDBCRC:
                lines.append("      Result: Found, exact match")
                self._accuratelyRipped += 1
            else:
                lines.append("      Result: Found, NO exact match")
            lines.append("      Confidence: %d" %
                         trackResult.ARDBConfidence)
            lines.append("      Local CRC: %08X" % trackResult.ARCRC)
            lines.append("      Remote CRC: %08X" % trackResult.ARDBCRC)
        elif trackResult.number != 0:
            lines.append("    AccurateRip V1:")
            lines.append("      Result: Track not present in "
                         "AccurateRip database")

        # Check if Test & Copy CRCs are equal
        if trackResult.testcrc == trackResult.copycrc:
            lines.append("    Status: Copy OK")
        else:
            self._errors = True
            lines.append("    Status: Error, CRC mismatch")
        return lines
コード例 #7
0
ファイル: logger.py プロジェクト: whipper-team/whipper
    def logRip(self, ripResult, epoch):
        """Return logfile as list of lines."""
        riplog = OrderedDict()

        # Ripper version
        riplog["Log created by"] = "whipper %s (internal logger)" % (
            whipper.__version__)

        # Rip date
        date = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(epoch)).strip()
        riplog["Log creation date"] = date

        # Rip technical settings
        data = OrderedDict()

        data["Drive"] = "%s%s (revision %s)" % (
            ripResult.vendor, ripResult.model, ripResult.release)
        data["Extraction engine"] = "cdparanoia %s" % (
            ripResult.cdparanoiaVersion)
        data["Defeat audio cache"] = ripResult.cdparanoiaDefeatsCache
        data["Read offset correction"] = ripResult.offset

        # Currently unsupported by the official cdparanoia package
        # Only implemented in whipper (ripResult.overread)
        data["Overread into lead-out"] = True if ripResult.overread else False
        # Next one fully works only using the patched cdparanoia package
        # lines.append("Fill up missing offset samples with silence: true")
        data["Gap detection"] = "cdrdao %s" % ripResult.cdrdaoVersion

        data["CD-R detected"] = ripResult.isCdr
        riplog["Ripping phase information"] = data

        # CD metadata
        release = OrderedDict()
        release["Artist"] = ripResult.artist
        release["Title"] = ripResult.title
        data = OrderedDict()
        data["Release"] = release
        data["CDDB Disc ID"] = ripResult.table.getCDDBDiscId()
        data["MusicBrainz Disc ID"] = ripResult.table.getMusicBrainzDiscId()
        data["MusicBrainz lookup URL"] = (
            ripResult.table.getMusicBrainzSubmitURL())
        if ripResult.metadata:
            data["MusicBrainz Release URL"] = ripResult.metadata.url
        riplog["CD metadata"] = data

        # TOC section
        data = OrderedDict()
        table = ripResult.table

        # Test for HTOA presence
        htoa = None
        try:
            htoa = table.tracks[0].getIndex(0)
        except KeyError:
            pass

        # If True, include HTOA line into log's TOC
        if htoa and htoa.path:
            htoastart = htoa.absolute
            htoaend = table.getTrackEnd(0)
            htoalength = table.tracks[0].getIndex(1).absolute - htoastart
            track = OrderedDict()
            track["Start"] = common.framesToMSF(htoastart)
            track["Length"] = common.framesToMSF(htoalength)
            track["Start sector"] = htoastart
            track["End sector"] = htoaend
            data[0] = track

        # For every track include information in the TOC
        for t in table.tracks:
            start = t.getIndex(1).absolute
            length = table.getTrackLength(t.number)
            end = table.getTrackEnd(t.number)
            track = OrderedDict()
            track["Start"] = common.framesToMSF(start)
            track["Length"] = common.framesToMSF(length)
            track["Start sector"] = start
            track["End sector"] = end
            data[t.number] = track
        riplog["TOC"] = data

        # Tracks section
        data = OrderedDict()
        duration = 0.0
        for t in ripResult.tracks:
            if not t.filename:
                continue
            track_dict, ARDB_entry, ARDB_match = self.trackLog(t)
            self._inARDatabase += int(ARDB_entry)
            self._accuratelyRipped += int(ARDB_match)
            data[t.number] = track_dict
            duration += t.testduration + t.copyduration
        riplog["Tracks"] = data

        # Status report
        data = OrderedDict()
        if self._inARDatabase == 0:
            message = ("None of the tracks are present in the "
                       "AccurateRip database")
        else:
            nonHTOA = len(ripResult.tracks)
            if ripResult.tracks[0].number == 0:
                nonHTOA -= 1
            if self._accuratelyRipped == 0:
                message = ("No tracks could be verified as accurate "
                           "(you may have a different pressing from the "
                           "one(s) in the database)")
            elif self._accuratelyRipped < nonHTOA:
                accurateTracks = nonHTOA - self._accuratelyRipped
                message = ("Some tracks could not be verified as "
                           "accurate (%d/%d got no match)") % (accurateTracks,
                                                               nonHTOA)
            else:
                message = "All tracks accurately ripped"
        data["AccurateRip summary"] = message

        if self._errors:
            message = "There were errors"
        elif self._skippedTracks:
            message = "Some tracks were not ripped (skipped)"
        else:
            message = "No errors occurred"
        data["Health status"] = message
        data["EOF"] = "End of status report"
        riplog["Conclusive status report"] = data

        riplog = yaml.dump(riplog,
                           default_flow_style=False,
                           width=4000,
                           Dumper=yaml.RoundTripDumper)
        # Add a newline after the "Log creation date" line
        riplog = re.sub(r'^(Log creation date: .*)$',
                        "\\1\n",
                        riplog,
                        flags=re.MULTILINE)
        # Add a newline after a dictionary ends and returns to top-level
        riplog = re.sub(r"^(\s{2})([^\n]*)\n([A-Z][^\n]+)",
                        "\\1\\2\n\n\\3",
                        riplog,
                        flags=re.MULTILINE)
        # Add a newline after a track closes
        riplog = re.sub(r"^(\s{4}[^\n]*)\n(\s{2}[0-9]+)",
                        "\\1\n\n\\2",
                        riplog,
                        flags=re.MULTILINE)
        # Remove single quotes around the "Log creation date" value
        riplog = re.sub(r"^(Log creation date: )'(.*)'",
                        "\\1\\2",
                        riplog,
                        flags=re.MULTILINE)

        # Log hash
        hasher = hashlib.sha256()
        hasher.update(riplog.encode("utf-8"))
        riplog += "\nSHA-256 hash: %s\n" % hasher.hexdigest().upper()
        return riplog
コード例 #8
0
ファイル: logger.py プロジェクト: whipper-team/whipper
    def trackLog(self, trackResult):
        """Return Tracks section lines: data picked from trackResult."""
        track = OrderedDict()

        # Filename (including path) of ripped track
        track["Filename"] = trackResult.filename

        # Pre-gap length
        pregap = trackResult.pregap
        if pregap:
            track["Pre-gap length"] = common.framesToMSF(pregap)

        # Peak level
        peak = trackResult.peak / 32768.0
        track["Peak level"] = float("%.6f" % peak)

        # Pre-emphasis status
        # Only implemented in whipper (trackResult.pre_emphasis)
        track["Pre-emphasis"] = trackResult.pre_emphasis

        # Extraction speed
        if trackResult.copyspeed:
            track["Extraction speed"] = "%.1f X" % trackResult.copyspeed

        # Extraction quality
        if trackResult.quality and trackResult.quality > 0.001:
            track["Extraction quality"] = "%.2f %%" % (trackResult.quality *
                                                       100.0, )

        # Ripper Test CRC
        if trackResult.testcrc is not None:
            track["Test CRC"] = "%08X" % trackResult.testcrc

        # Ripper Copy CRC
        if trackResult.copycrc is not None:
            track["Copy CRC"] = "%08X" % trackResult.copycrc

        # AccurateRip track status
        ARDB_entry = 0
        ARDB_match = 0
        for v in ("v1", "v2"):
            data = OrderedDict()
            if trackResult.AR[v]["DBCRC"]:
                ARDB_entry += 1
                if trackResult.AR[v]["CRC"] == trackResult.AR[v]["DBCRC"]:
                    data["Result"] = "Found, exact match"
                    ARDB_match += 1
                else:
                    data["Result"] = "Found, NO exact match"
                data["Confidence"] = trackResult.AR[v]["DBConfidence"]
                data["Local CRC"] = trackResult.AR[v]["CRC"].upper()
                data["Remote CRC"] = trackResult.AR[v]["DBCRC"].upper()
            elif trackResult.number != 0:
                data["Result"] = "Track not present in AccurateRip database"
            track["AccurateRip %s" % v] = data

        # Check if track has been skipped
        if trackResult.skipped:
            track["Status"] = "Track not ripped (skipped)"
            self._skippedTracks = True
        # Check if Test & Copy CRCs are equal
        elif trackResult.testcrc == trackResult.copycrc:
            track["Status"] = "Copy OK"
        else:
            self._errors = True
            track["Status"] = "Error, CRC mismatch"
        return track, bool(ARDB_entry), bool(ARDB_match)
コード例 #9
0
ファイル: logger.py プロジェクト: JoeLametta/whipper
    def trackLog(self, trackResult):
        """Returns Tracks section lines: data picked from trackResult"""

        lines = []

        # Track number
        lines.append("  %d:" % trackResult.number)

        # Filename (including path) of ripped track
        lines.append("    Filename: %s" % trackResult.filename)

        # Pre-gap length
        pregap = trackResult.pregap
        if pregap:
            lines.append("    Pre-gap length: %s" % common.framesToMSF(pregap))

        # Peak level
        peak = trackResult.peak / 32768.0
        lines.append("    Peak level: %.6f" % peak)

        # Pre-emphasis status
        # Only implemented in whipper (trackResult.pre_emphasis)
        if trackResult.pre_emphasis:
            preEmph = "Yes"
        else:
            preEmph = "No"
        lines.append("    Pre-emphasis: %s" % preEmph)

        # Extraction speed
        if trackResult.copyspeed:
            lines.append("    Extraction speed: %.1f X" % (
                trackResult.copyspeed))

        # Extraction quality
        if trackResult.quality and trackResult.quality > 0.001:
            lines.append("    Extraction quality: %.2f %%" %
                         (trackResult.quality * 100.0, ))

        # Ripper Test CRC
        if trackResult.testcrc is not None:
            lines.append("    Test CRC: %08X" % trackResult.testcrc)

        # Ripper Copy CRC
        if trackResult.copycrc is not None:
            lines.append("    Copy CRC: %08X" % trackResult.copycrc)

        # AccurateRip track status
        ARDB_entry = 0
        ARDB_match = 0
        for v in ("v1", "v2"):
            if trackResult.AR[v]["DBCRC"]:
                lines.append("    AccurateRip %s:" % v)
                ARDB_entry += 1
                if trackResult.AR[v]["CRC"] == trackResult.AR[v]["DBCRC"]:
                    lines.append("      Result: Found, exact match")
                    ARDB_match += 1
                else:
                    lines.append("      Result: Found, NO exact match")
                lines.append(
                    "      Confidence: %d" % trackResult.AR[v]["DBConfidence"]
                )
                lines.append(
                    "      Local CRC: %s" % trackResult.AR[v]["CRC"].upper()
                )
                lines.append(
                    "      Remote CRC: %s" % trackResult.AR[v]["DBCRC"].upper()
                )
            elif trackResult.number != 0:
                lines.append("    AccurateRip %s:" % v)
                lines.append(
                    "      Result: Track not present in AccurateRip database"
                )

        # Check if Test & Copy CRCs are equal
        if trackResult.testcrc == trackResult.copycrc:
            lines.append("    Status: Copy OK")
        else:
            self._errors = True
            lines.append("    Status: Error, CRC mismatch")
        return lines, bool(ARDB_entry), bool(ARDB_match)
コード例 #10
0
ファイル: logger.py プロジェクト: Lapin0t/whipper
    def trackLog(self, trackResult):
        """Generate tracks section lines.

        Tracks information are mostly taken from ``trackResult``.

        :param trackResult:
        :type trackResult:
        :returns: tracks section lines.
        :rtype: list
        """
        lines = []

        # Track number
        lines.append("  %02d:" % trackResult.number)

        # Filename (including path) of ripped track
        lines.append("    Filename: %s" % trackResult.filename)

        # Pre-gap length
        pregap = trackResult.pregap
        if pregap:
            lines.append("    Pre-gap length: %s" % common.framesToMSF(pregap))

        # Peak level
        peak = trackResult.peak
        lines.append("    Peak level: %.6f" % peak)

        # Pre-emphasis status
        # Only implemented in whipper (trackResult.pre_emphasis)
        if trackResult.pre_emphasis:
            preEmph = "Yes"
        else:
            preEmph = "No"
        lines.append("    Pre-emphasis: %s" % preEmph)

        # Extraction speed
        if trackResult.copyspeed:
            lines.append("    Extraction speed: %.1f X" % (
                trackResult.copyspeed))

        # Extraction quality
        if trackResult.quality and trackResult.quality > 0.001:
            lines.append("    Extraction quality: %.2f %%" %
                         (trackResult.quality * 100.0, ))

        # Ripper Test CRC
        if trackResult.testcrc is not None:
            lines.append("    Test CRC: %08X" % trackResult.testcrc)

        # Ripper Copy CRC
        if trackResult.copycrc is not None:
            lines.append("    Copy CRC: %08X" % trackResult.copycrc)

        # AccurateRip track status
        for v in ('v1', 'v2'):
            if trackResult.AR[v]['DBCRC']:
                lines.append("    AccurateRip %s:" % v)
                self._inARDatabase += 1
                if trackResult.AR[v]['CRC'] == trackResult.AR[v]['DBCRC']:
                    lines.append("      Result: Found, exact match")
                    self._accuratelyRipped += 1
                else:
                    lines.append("      Result: Found, NO exact match")
                lines.append(
                    "      Confidence: %d" % trackResult.AR[v]['DBConfidence']
                )
                lines.append(
                    "      Local CRC: %s" % trackResult.AR[v]['CRC'].upper()
                )
                lines.append(
                    "      Remote CRC: %s" % trackResult.AR[v]['DBCRC'].upper()
                )
            elif trackResult.number != 0:
                lines.append("    AccurateRip %s:" % v)
                lines.append(
                    "      Result: Track not present in AccurateRip database"
                )

        # Check if Test & Copy CRCs are equal
        if trackResult.testcrc == trackResult.copycrc:
            lines.append("    Status: Copy OK")
        else:
            self._errors = True
            lines.append("    Status: Error, CRC mismatch")
        return lines