コード例 #1
0
    def do(self, args):
        prog = program.Program(self.getRootCommand().config)
        runner = ctask.SyncRunner()

        device = self.options.device

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

        prog.loadDevice(device)
        prog.unmountDevice(device)

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

        self.debug("CDDB disc id: %r", table.getCDDBDiscId())
        url = table.getAccurateRipURL()
        self.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:
                self.stdout.write(
                    'Album not found in AccurateRip database.\n')
                return 1
            else:
                raise
コード例 #2
0
ファイル: image.py プロジェクト: mustbenice/morituri
    def do(self, args):
        prog = program.Program()
        runner = task.SyncRunner()

        for arg in args:
            print 'Retagging image %r' % arg
            arg = arg.decode('utf-8')
            cueImage = image.Image(arg)
            cueImage.setup(runner)

            mbdiscid = cueImage.table.getMusicBrainzDiscId()
            prog.metadata = prog.getMusicBrainz(cueImage.table, mbdiscid)

            if not prog.metadata:
                print 'Not in MusicBrainz database, skipping'
                continue

            # FIXME: this feels like we're poking at internals.
            prog.cuePath = arg
            prog.result = result.RipResult()
            for track in cueImage.table.tracks:
                path = track.indexes[1].path
                taglist = prog.getTagList(track.number)
                self.debug('possibly retagging %r with taglist %r', path,
                           taglist)
                t = encode.SafeRetagTask(path, taglist)
                runner.run(t)
                path = os.path.basename(path)
                if t.changed:
                    print 'Retagged %s' % path
                else:
                    print '%s already tagged correctly' % path
            print
コード例 #3
0
    def testIssue66TemplateFilled(self):
        prog = program.Program()
        md = musicbrainzngs.DiscMetadata()
        md.artist = md.sortName = 'Jeff Buckley'
        md.title = 'Grace'
        prog.metadata = md

        path = prog.getPath(u'/tmp', u'%A/%d', 'mbdiscid', 0)
        self.assertEquals(path, u'/tmp/Jeff Buckley/Grace')
コード例 #4
0
    def testStandardTemplateEmpty(self):
        prog = program.Program(config.Config())

        path = prog.getPath(u'/tmp', rcommon.DEFAULT_DISC_TEMPLATE, 'mbdiscid',
                            0)
        self.assertEquals(
            path,
            u'/tmp/unknown/Unknown Artist - mbdiscid/Unknown Artist - mbdiscid'
        )
コード例 #5
0
    def testStandardTemplateFilled(self):
        prog = program.Program()
        md = musicbrainzngs.DiscMetadata()
        md.artist = md.sortName = 'Jeff Buckley'
        md.title = 'Grace'
        prog.metadata = md

        path = prog.getPath(u'/tmp', cd.DEFAULT_DISC_TEMPLATE, 'mbdiscid', 0)
        self.assertEquals(path,
                          u'/tmp/Jeff Buckley - Grace/Jeff Buckley - Grace')
コード例 #6
0
    def testStandardTemplateFilled(self):
        prog = program.Program(config.Config())
        md = mbngs.DiscMetadata()
        md.artist = md.sortName = 'Jeff Buckley'
        md.title = 'Grace'
        prog.metadata = md

        path = prog.getPath(u'/tmp', rcommon.DEFAULT_DISC_TEMPLATE, 'mbdiscid',
                            0)
        self.assertEquals(
            path, u'/tmp/unknown/Jeff Buckley - Grace/Jeff Buckley - Grace')
コード例 #7
0
    def testVerify(self):
        path = os.path.join(os.path.dirname(__file__),
                            'dBAR-020-002e5023-029d8e49-040eaa14.bin')
        data = open(path, "rb").read()
        responses = accurip.getAccurateRipResponses(data)

        # these crc's were calculated from an actual rip
        checksums = [
            1644890007, 2945205445, 3983436658, 1528082495, 1203704270,
            1163423644, 3649097244, 100524219, 1583356174, 373652058,
            1842579359, 2850056507, 1329730252, 2526965856, 2525886806,
            209743350, 3184062337, 2099956663, 2943874164, 2321637196
        ]

        prog = program.Program()
        prog.result = result.RipResult()
        # fill it with empty trackresults
        for i, c in enumerate(checksums):
            r = result.TrackResult()
            r.number = i + 1
            prog.result.tracks.append(r)

        prog._verifyImageWithChecksums(responses, checksums)

        # now check if the results were filled in properly
        tr = prog.result.getTrackResult(1)
        self.assertEquals(tr.accurip, False)
        self.assertEquals(tr.ARDBMaxConfidence, 0)
        self.assertEquals(tr.ARDBCRC, 0)
        self.assertEquals(tr.ARDBCRC, 0)

        tr = prog.result.getTrackResult(2)
        self.assertEquals(tr.accurip, True)
        self.assertEquals(tr.ARDBMaxConfidence, 2)
        self.assertEquals(tr.ARDBCRC, checksums[2 - 1])

        tr = prog.result.getTrackResult(10)
        self.assertEquals(tr.accurip, False)
        self.assertEquals(tr.ARDBMaxConfidence, 2)
        # we know track 10 was ripped wrong
        self.assertNotEquals(tr.ARDBCRC, checksums[10 - 1])

        res = prog.getAccurateRipResults()
        self.assertEquals(
            res[1 - 1], "Track  1: rip NOT accurate (not found)             "
            "[620b0797], DB [notfound]")
        self.assertEquals(
            res[2 - 1], "Track  2: rip accurate     (max confidence      2) "
            "[af8c44c5], DB [af8c44c5]")
        self.assertEquals(
            res[10 - 1], "Track 10: rip NOT accurate (max confidence      2) "
            "[16457a5a], DB [eb6e55b4]")
コード例 #8
0
    def do(self, args):
        # here to avoid import gst eating our options
        from morituri.common import encode

        prog = program.Program(self.getRootCommand().config,
                               stdout=self.stdout)
        runner = task.SyncRunner()

        for arg in args:
            self.stdout.write('Retagging image %r\n' % arg)
            arg = arg.decode('utf-8')
            cueImage = image.Image(arg)
            cueImage.setup(runner)

            mbdiscid = cueImage.table.getMusicBrainzDiscId()
            self.stdout.write('MusicBrainz disc id is %s\n' % mbdiscid)

            self.stdout.write("MusicBrainz lookup URL %s\n" %
                              cueImage.table.getMusicBrainzSubmitURL())
            prog.metadata = prog.getMusicBrainz(
                cueImage.table,
                mbdiscid,
                release=self.options.release_id,
                country=self.options.country,
                prompt=self.options.prompt)

            if not prog.metadata:
                print 'Not in MusicBrainz database, skipping'
                continue

            prog.metadata.discid = mbdiscid

            # FIXME: this feels like we're poking at internals.
            prog.cuePath = arg
            prog.result = result.RipResult()
            for track in cueImage.table.tracks:
                path = cueImage.getRealPath(track.indexes[1].path)

                taglist = prog.getTagList(track.number)
                self.debug(
                    'possibly retagging %r from cue path %r with taglist %r',
                    path, arg, taglist)
                t = encode.SafeRetagTask(path, taglist)
                runner.run(t)
                path = os.path.basename(path)
                if t.changed:
                    print 'Retagged %s' % path
                else:
                    print '%s already tagged correctly' % path
            print
コード例 #9
0
    def do(self, args):
        prog = program.Program(self.getRootCommand().config)
        prog.outdir = (self.options.output_directory or os.getcwd())
        prog.outdir = prog.outdir.decode('utf-8')

        # here to avoid import gst eating our options
        from morituri.common import encode

        profile = encode.ALL_PROFILES[self.options.profile]()

        runner = task.SyncRunner()

        for arg in args:
            arg = arg.decode('utf-8')
            indir = os.path.dirname(arg)
            cueImage = image.Image(arg)
            cueImage.setup(runner)
            # FIXME: find a decent way to get an album-specific outdir
            root = os.path.basename(indir)
            outdir = os.path.join(prog.outdir, root)
            try:
                os.makedirs(outdir)
            except:
                # FIXME: handle other exceptions than OSError Errno 17
                pass
            # FIXME: handle this nicer
            assert outdir != indir

            taskk = image.ImageEncodeTask(cueImage, profile, outdir)
            runner.run(taskk)

            # FIXME: translate .m3u file if it exists
            root, ext = os.path.splitext(arg)
            m3upath = root + '.m3u'
            if os.path.exists(m3upath):
                self.debug('translating .m3u file')
                inm3u = open(m3upath)
                outm3u = open(os.path.join(outdir, os.path.basename(m3upath)),
                              'w')
                for line in inm3u.readlines():
                    root, ext = os.path.splitext(line)
                    if ext:
                        # newline is swallowed by splitext here
                        outm3u.write('%s.%s\n' % (root, profile.extension))
                    else:
                        outm3u.write('%s' % root)
                outm3u.close()
コード例 #10
0
    def do(self, args):
        prog = program.Program(self.getRootCommand().config)
        runner = ctask.SyncRunner()

        device = self.options.device

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

        prog.loadDevice(device)
        prog.unmountDevice(device)

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

        try:
            runner.run(t)
        except cdrdao.DeviceOpenException, e:
            self.error(e.msg)
            return 3
コード例 #11
0
ファイル: image.py プロジェクト: megies/morituri
    def do(self, args):
        prog = program.Program(self.getRootCommand.config(),
                               stdout=self.stdout)
        runner = task.SyncRunner()

        for arg in args:
            self.stdout.write('Renaming image %r\n' % arg)
            arg = arg.decode('utf-8')
            cueImage = image.Image(arg)
            cueImage.setup(runner)

            mbdiscid = cueImage.table.getMusicBrainzDiscId()

            operator = renamer.Operator(statePath, mbdiscid)

            self.stdout.write('MusicBrainz disc id is %s\n' % mbdiscid)
            prog.metadata = prog.getMusicBrainz(
                cueImage.table, mbdiscid, release=self.options.release_id)

            if not prog.metadata:
                print 'Not in MusicBrainz database, skipping'
                continue

            # FIXME: this feels like we're poking at internals.
            prog.cuePath = arg
            prog.result = result.RipResult()
            for track in cueImage.table.tracks:
                path = cueImage.getRealPath(track.indexes[1].path)

                taglist = prog.getTagList(track.number)
                self.debug(
                    'possibly retagging %r from cue path %r with taglist %r',
                    path, arg, taglist)
                t = encode.SafeRetagTask(path, taglist)
                runner.run(t)
                path = os.path.basename(path)
                if t.changed:
                    print 'Retagged %s' % path
                else:
                    print '%s already tagged correctly' % path
            print
コード例 #12
0
    def do(self, args):
        prog = program.Program(self.getRootCommand().config)
        runner = task.SyncRunner()
        cache = accurip.AccuCache()

        for arg in args:
            arg = arg.decode('utf-8')
            cueImage = image.Image(arg)
            cueImage.setup(runner)

            url = cueImage.table.getAccurateRipURL()
            responses = cache.retrieve(url)

            # FIXME: this feels like we're poking at internals.
            prog.cuePath = arg
            prog.result = result.RipResult()
            for track in cueImage.table.tracks:
                tr = result.TrackResult()
                tr.number = track.number
                prog.result.tracks.append(tr)

            prog.verifyImage(runner, responses)

            print "\n".join(prog.getAccurateRipResults()) + "\n"
コード例 #13
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, ))
コード例 #14
0
ファイル: cd.py プロジェクト: mustbenice/morituri
    def do(self, args):
        prog = program.Program(record=self.getRootCommand().record)
        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.loadDevice(device)
        prog.unmountDevice(device)

        version = None

        # first, read the normal TOC, which is fast
        ptoc = common.Persister(self.options.toc_pickle or None)
        if not ptoc.object:
            t = cdrdao.ReadTOCTask(device=device)
            function(runner, t)
            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.
See  http://sourceforge.net/tracker/?func=detail&aid=604751&group_id=2171&atid=102171
''')
            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,
                                            self.options.release)

        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 or os.getcwd())
        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.cdrdao_version = version
        prog.result.cdparanoia_version = cdparanoia.ParanoiaVersion()
        prog.result.offset = int(self.options.offset)
        prog.result.artist = prog.metadata and prog.metadata.artist \
            or 'Unknown Artist'
        prog.result.title = prog.metadata and prog.metadata.title \
            or 'Unknown Title'
        # cdio is optional for now
        try:
            import cdio
            _, prog.result.vendor, prog.result.model, prog.result.release = \
                cdio.Device(device).get_hwinfo()
        except ImportError:
            self.stdout.write(
                'WARNING: pycdio not installed, cannot identify drive\n')
            prog.result.vendor = 'Unknown'
            prog.result.model = 'Unknown'
            prog.result.release = 'Unknown'

        # FIXME: turn this into a method

        def ripIfNotRipped(number):
            # we can have a previous result
            trackResult = prog.result.getTrackResult(number)
            if not trackResult:
                trackResult = result.TrackResult()
                prog.result.tracks.append(trackResult)

            path = prog.getPath(prog.outdir, self.options.track_template,
                                mbdiscid, number) + '.' + profile.extension
            trackResult.number = number

            assert type(path) is unicode, "%r is not unicode" % path
            trackResult.filename = path
            if number > 0:
                trackResult.pregap = itable.tracks[number - 1].getPregap()

            # FIXME: optionally allow overriding reripping
            if os.path.exists(path):
                self.stdout.write('Verifying track %d of %d: %s\n' %
                                  (number, len(itable.tracks),
                                   os.path.basename(path).encode('utf-8')))
                if not prog.verifyTrack(runner, trackResult):
                    self.stdout.write('Verification failed, reripping...\n')
                    os.unlink(path)

            if not os.path.exists(path):
                tries = 0
                self.stdout.write('Ripping track %d of %d: %s\n' %
                                  (number, len(itable.tracks),
                                   os.path.basename(path).encode('utf-8')))
                while tries < MAX_TRIES:
                    tries += 1
                    try:
                        self.debug('ripIfNotRipped: track %d, try %d', number,
                                   tries)
                        prog.ripTrack(runner,
                                      trackResult,
                                      offset=int(self.options.offset),
                                      device=self.parentCommand.options.device,
                                      profile=profile,
                                      taglist=prog.getTagList(number),
                                      what='track %d of %d' %
                                      (number, len(itable.tracks)))
                        break
                    except Exception, e:
                        self.debug('Got exception %r on try %d', e, tries)

                if tries == MAX_TRIES:
                    self.error('Giving up on track %d after %d times' %
                               (number, tries))
                if trackResult.testcrc == trackResult.copycrc:
                    self.stdout.write('Checksums match for track %d\n' %
                                      number)
                else:
                    self.stdout.write(
                        'ERROR: checksums did not match for track %d\n' %
                        number)
                    raise

                self.stdout.write('Peak level: %.2f %%\n' %
                                  (math.sqrt(trackResult.peak) * 100.0, ))
                self.stdout.write('Rip quality: %.2f %%\n' %
                                  (trackResult.quality * 100.0, ))

            # overlay this rip onto the Table
            if number == 0:
                # HTOA goes on index 0 of track 1
                itable.setFile(1, 0, trackResult.filename,
                               ittoc.getTrackStart(1), number)
            else:
                itable.setFile(number, 1, trackResult.filename,
                               ittoc.getTrackLength(number), number)

            prog.saveRipResult()
コード例 #15
0
    def testGetAccurateRipResults(self):
        prog = program.Program()
        prog.result = result.RipResult()
        prog.result.tracks = self._tracks

        prog.getAccurateRipResults()