def initCombos(self, evt): ''' make some web queries to init the combo boxes ''' self.artist_combo.Clear() self.album_combo.Clear() self.track_combo.Clear() wait_dialog = wx.ProgressDialog('Searching...', 'Searching...', maximum=10, parent=self) wait_dialog.SetSize((300, 150)) wait_dialog.SetMaxSize((300,300)) wait_dialog.SetPosition((250,250)) wait_dialog.Update(1, 'querying web...') self.Refresh() _, web_guess = tagGuessCache.queryGoogCache(self.artist_str) if web_guess: self.artist_combo.Append(web_guess) self.artist_combo.SetSelection(0) if not self.artist_obj and web_guess: wait_dialog.Update(2, 'querying web...') self.artist_obj = tagGuessCache.getRawArtistInfo(web_guess) if self.artist_obj and web_guess: do_first_alb = True do_first_trk = True i = 0 for album_obj in self.artist_obj.albums: i += 1 wait_dialog.Update(i % 10, album_obj.name) self.album_combo.Append(album_obj.name) if do_first_alb: self.album_combo.SetSelection(0) for track_obj in album_obj.tracks: self.track_combo.Append(track_obj.name) if do_first_trk: self.track_combo.SetSelection(0) do_first_trk = False do_first_alb = False wait_dialog.Destroy()
def IdentifyMusic(mp3_list, callback=None): '''The meat of the entire program. Loops through a list of MP3File objs, and will attempt to find better tag matches for the artist, album, track, and tracknum. mp3_list -> list of MP3File objects (supposedly populated via main.FindMusic) (note that these objects specify both old and refined tags. entering this function, the refined tags will be empty. exiting this function, they will be populated) callback -> a function pointer funct(str) used to return status info returns -> None ''' if globalz.PERSIST_CACHE_ON: tagGuessCache.undump() try: # PASS 1: use google to refine the artist name for mp3_count, mp3_obj in enumerate(mp3_list): if callback: callback('pass1: %s - %s' % (mp3_obj.orig_track.artist, mp3_obj.orig_track.name)) # use google instead of last.fm to correct the artist name (net_error, web_guess) = tagGuessCache.queryGoogCache(mp3_obj.orig_track.artist) if not net_error: if web_guess: # run some heuristics to make sure the artist makes sense if strtool.artistCompare(mp3_obj.orig_track.artist, web_guess): mp3_obj.clean_track.artist = web_guess # now look up the last.fm track list for the top 10 albums of artist is_track_found = tagGuessCache.updateGuessCache(mp3_obj.orig_track.path, mp3_obj.orig_track.name, mp3_obj.clean_track.artist) if not is_track_found: mp3_obj.result = MP3File.QRY_RESULT.TRACK_NOT_FOUND mp3_obj.clean_track.artist = mp3_obj.orig_track.artist else: mp3_obj.result = MP3File.QRY_RESULT.OK else: mp3_obj.result = MP3File.QRY_RESULT.ARTIST_BAD_MATCH mp3_obj.clean_track.artist = mp3_obj.orig_track.artist else: mp3_obj.result = MP3File.QRY_RESULT.ARTIST_NOT_FOUND mp3_obj.clean_track.artist = mp3_obj.orig_track.artist else: mp3_obj.result = MP3File.QRY_RESULT.NET_ERROR mp3_obj.clean_track.artist = mp3_obj.orig_track.artist if (mp3_count % 100) == 0: mylog.INFO('processed %d files' % (mp3_count)) if globalz.CACHE_DEBUG_ON: with open('pprint.txt','w') as f: f.write('BEFORE:\n') tagGuessCache.dbgPrint(f) mylog.INFO("refining track info...") # PASS 2: use lastfm and musicbrainz for better track/album info tagGuessCache.refineGuessCache() # see if we found a guess in last.fm for mp3_obj in mp3_list: if mp3_obj.result == MP3File.QRY_RESULT.OK: if callback: callback('pass2: lastfm: %s - %s' % (mp3_obj.orig_track.artist, mp3_obj.orig_track.name)) guess_track_obj = tagGuessCache.searchGuessCache(mp3_obj.clean_track.artist, mp3_obj.orig_track.path) if not guess_track_obj: mp3_obj.result = MP3File.QRY_RESULT.TRACK_NOT_FOUND else: mp3_obj.clean_track.name = guess_track_obj.name mp3_obj.clean_track.album = guess_track_obj.album mp3_obj.clean_track.track_num = guess_track_obj.track_num mp3_obj.method1 = MP3File.METHOD.ID3ID # now use musicbrainz for what lastfm couldn't find # (skip NET_ERROR tracks too...want to be clear in the gui that # these tracks failed due to network problems, not algorithm failure for mp3_obj in mp3_list: if mp3_obj.result != MP3File.QRY_RESULT.OK and \ mp3_obj.result != MP3File.QRY_RESULT.NET_ERROR: if callback: callback('pass2: hashing: %s - %s' % (mp3_obj.orig_track.artist, mp3_obj.orig_track.name)) mylog.INFO('using hashing for unknown file %s' % (mp3_obj.orig_track.path)) puid_qry_obj = puidquery.PUIDQuery() (mp3_obj.clean_track.artist, mp3_obj.clean_track.album, mp3_obj.clean_track.name, mp3_obj.clean_track.track_num) = puid_qry_obj.lookupTrack(mp3_obj.orig_track.path) if mp3_obj.clean_track.artist: mp3_obj.method1 = MP3File.METHOD.HASHED else: mp3_obj.method1 = MP3File.METHOD.FAILEDHASH # PASS 3: retry album name guessing. now that the data has been partially cleaned, we'll have # better luck guessing the correct album name tagGuessCache.clearCache() for mp3_obj in mp3_list: if mp3_obj.result == MP3File.QRY_RESULT.NET_ERROR: continue mylog.INFO('pass3: on file \'%s\' track \'%s\'' % (mp3_obj.orig_track.path, mp3_obj.clean_track.name)) if callback: callback('pass3: on file \'%s\' track \'%s\'' % (mp3_obj.orig_track.path, mp3_obj.clean_track.name)) if mp3_obj.clean_track.artist: if mp3_obj.clean_track.name: tagGuessCache.updateGuessCache(mp3_obj.orig_track.path, mp3_obj.clean_track.name, mp3_obj.clean_track.artist) else: tagGuessCache.updateGuessCache(mp3_obj.orig_track.path, mp3_obj.orig_track.name, mp3_obj.clean_track.artist) tagGuessCache.refineGuessCache() for mp3_obj in mp3_list: if mp3_obj.result == MP3File.QRY_RESULT.NET_ERROR: continue guess_track_obj = tagGuessCache.searchGuessCache(mp3_obj.clean_track.artist, mp3_obj.orig_track.path) if guess_track_obj: mylog.INFO('pass3_result: found guess on file \'%s\' track \'%s\'' % (mp3_obj.orig_track.path, mp3_obj.clean_track.name)) mp3_obj.clean_track.name = guess_track_obj.name mp3_obj.clean_track.album = guess_track_obj.album mp3_obj.clean_track.track_num = guess_track_obj.track_num mp3_obj.updateResults() mp3_obj.method2 = MP3File.METHOD.ID3ID mp3_obj.result = MP3File.QRY_RESULT.FIELDS_CHANGED else: mylog.INFO('pass3_result: no guess found on file \'%s\' track \'%s\'' % (mp3_obj.orig_track.path, mp3_obj.clean_track.name)) mp3_obj.method2 = MP3File.METHOD.SECONDPASSFAIL # make a final call on whether we got good results or not if mp3_obj.method1 == MP3File.METHOD.FAILEDHASH or \ mp3_obj.method1 == MP3File.METHOD.UNKNOWN: mp3_obj.result = MP3File.QRY_RESULT.NO_GUESS else: mp3_obj.result = MP3File.QRY_RESULT.FIELDS_CHANGED if globalz.CACHE_DEBUG_ON: for x in mp3_list: print unicode(x).encode('utf-8') with open('pprint.txt','w') as f: f.write('AFTER:\n') tagGuessCache.dbgPrint(f) finally: if globalz.PERSIST_CACHE_ON: mylog.INFO('persisting track guesses') tagGuessCache.dump() return mp3_list