def load(opts, path): server = client.Server('http://localhost:5984') # FIXME: put this in quotes and see a 500 that gets unhandled cdb = server[opts.database] print 'Loading pickle', path handle = open(path) d = pickle.load(handle) for path, l in d.items(): # apparently we saved as str; decode to utf-8 if type(path) is str: path = path.decode('utf-8') assert type(path) is unicode if not path: print 'ERROR: no path', path continue try: audiofile = lookup.getAudioFile(cdb, path) except KeyError, e: print 'WARNING: %s not in database' % path continue except Exception, e: print log.getExceptionMessage(e) raise
def _chromaPrintOne(self, printer, track, fragment, f): """ @type track: L{dad.model.track.TrackModel} @type fragment: L{dad.model.track.FragmentModel} @type f: L{dad.model.track.FileModel} """ assert isinstance(track, mtrack.TrackModel) self.debug("_chromaPrintOne %r, %r, %r", track, fragment, f) if not fragment.chroma.chromaprint or not fragment.chroma.duration: try: # FIXME: maybe getChromaPrint should return a model ? fingerprint, duration = printer.getChromaPrint(f.info.path, runner=self._runner) except task.TaskException, e: print 'ERROR:', log.getExceptionMessage(e) print 'skipping', f.info.path.encode('utf-8') return self.debug('Got fingerprint: %r', fingerprint) # store fingerprint before looking up cp = mtrack.ChromaPrintModel() cp.chromaprint = fingerprint cp.duration = duration printed = yield self.database.trackAddFragmentChromaPrint( track, f.info, cp)
def doLater(self, args): if not args: self.stderr.write('Please give path to chromaprint.\n') defer.returnValue(3) return self.debug('Chromaprint: args %r', args) interactor = database.DatabaseInteractor( self.parentCommand.database, self.parentCommand.runner) # FIXME: database-specific, should be replaced by more generic things # FIXME: imports reactor from twisted.web import error paths = common.expandPaths(args, self.stderr) failed = [] for path in paths: path = os.path.abspath(path) self.stdout.write('%s\n' % path.encode('utf-8')) try: res = yield interactor.chromaprint(path, hostname=self.hostname) except error.Error, e: if e.status == 404: self.stderr.write('Database or view does not exist.\n') self.reactor.stop() defer.returnValue(3) return except Exception, e: failed.append((path, log.getExceptionMessage(e))) continue
def setup(self, options, playerOptions): if options.gtk == True: self._setup_gtk() # always add a command line player # FIXME: remove init argument for player in view ? self._player.addView(player.CommandPlayerView(self._player)) try: self._setup_mediakeys() except Exception, e: self.warning('Could not add mediakeys: %r', log.getExceptionMessage(e))
def get(self): """ @returns: a deferred firing a list of L{daddb.ItemTracksByArtist} objects representing only artists and their track count. """ start = time.time() self.debug('get') v = views.View(self.database.db, self.database.dbName, 'dad', 'view-tracks-by-artist', self.database.modelFactory(ItemTracksByArtist)) try: itemTracks = yield v.queryView() except Exception, e: self.warning('get: exception: %r', log.getExceptionMessage(e)) raise
def getTracks(self): self.debug('getTracks') # FIXME: this gets all possible tracks for this artist, but maybe # this should be more limited ? keys = [ 'artist:name:%s' % self.getName(), 'artist:mbid:%s' % self.getMbId(), self.getId() ] v = views.View(self.database.db, self.database.dbName, 'dad', 'view-tracks-by-artist', self.database.modelFactory(ItemTracksByArtist), keys=keys) try: result = yield v.queryView() except Exception, e: self.warning('get: exception: %r', log.getExceptionMessage(e)) raise
def lookup(self, chromaprint): postdata = { 'client': CHROMAPRINT_APIKEY, 'meta': '2', 'duration': str(chromaprint.duration), 'fingerprint': chromaprint.chromaprint } resp = None from twisted.web import client for i in range(0, 3): try: d = client.getPage(CHROMAPRINT_URL, method='POST', postdata=urllib.urlencode(postdata), headers={'Content-Type':'application/x-www-form-urlencoded'}) resp = yield d # uncomment for a quick debug that you can paste in tests # print resp break except Exception, e: self.debug('Failed to open %r', log.getExceptionMessage(e))
def add(self, path, hostname=None, force=False): """ @type path: C{unicode} @type hostname: C{unicode} @type force: C{bool} @returns: - None if it was already in the database. - ([existing], [new]) tracks for this path """ ret = ([], []) self.debug('Adding %r', path) if not os.path.exists(path): raise PathError(path) # look up first if not hostname: hostname = self._hostname() self.debug('Looking up: host %r, path %r', hostname, path) res = yield self.database.getTracksByHostPath( hostname, path) if not res: res = [] res = list(res) self.debug('Looked up: %r', res) t = md5task.MD5Task(path) self._runner.run(t) if len(res) > 0: if not force: # FIXME: verify md5sum self.debug('%r already in database: %r', path, res[0]) defer.returnValue(ret) return # check if it exists by md5sum on any other host res = yield self.database.getTracksByMD5Sum(t.md5sum) res = list(res) self.debug('Looked up by md5sum: %r', res) if len(res) > 0: self.debug('%r exists by md5sum: %r', path, res[0]) # FIXME: add by md5sum only, copying from another file # defer.returnValue(ret) # return # doesn't exist, so add it # get metadata # FIXME: choose ? from dad import plugins getter = None for getter in plugin.getPlugins(idad.IMetadataGetter, plugins): continue try: metadata = getter.getMetadata(path, runner=self._runner) except task.TaskException, e: print 'ERROR:', log.getExceptionMessage(e) print 'skipping', path.encode('utf-8') return
self.stdout.write('Created %d new track(s).\n' % len(new)) else: self.stdout.write('Audio file already in database.\n') # now chromaprint # FIXME: decide if this is how we want to delegate chromaprinting? c = self.parentCommand.subCommands['chromaprint'] # commands deal with arguments which are not unicode, so decode yield c.doLater([path.encode('utf-8'), ]) if failed: for path, e in failed: self.stdout.write('Failed to add %s:\n' % path.encode('utf-8')) self.stdout.write('%s\n' % log.getExceptionMessage(e)) class Chromaprint(tcommand.TwistedCommand): """ @type hostname: unicode """ description = """Chromaprint an audio file in the database.""" hostname = None def addOptions(self): self.parser.add_option('-H', '--hostname', action="store", dest="hostname", default=common.hostname(), help="override hostname (%default)")