from DataBase import * from SpotifyWebAPI import find_song, update_access_token from fuzzywuzzy import fuzz from tqdm import tqdm def spotify_pattern_generator(): update_access_token() local_library = get_data("local_library") spotify_library = get_data("tracks") def find_local_songs_on_spotify(local_lib): total = len(local_library) found_tracks_map = {} with tqdm(total=total, desc='Searching local songs on spotify') as pbar: for track_id, track in local_lib.items(): search_pattern = f"{track['name']} {track['artist']} {track['album']}" found_tracks = find_song(search_pattern) found_tracks_map[track_id] = found_tracks[0:1] pbar.update(1) return found_tracks_map spotify_found_tracks = find_local_songs_on_spotify(local_library) spotify_user_track = {track['track']['id']: {"local_mappings": []} for track in spotify_library} spotify_pattern = {} for local_id, found_items in spotify_found_tracks.items(): spotify_pattern[local_id] = {"score": 0.0, "items": []} if not len(found_items): continue for found_item in found_items: spotify_track_id = found_item['id'] if spotify_track_id in spotify_user_track: spotify_pattern[local_id]['items'].append(spotify_track_id) spotify_user_track[spotify_track_id]['local_mappings'].append(local_id) for spotify_id, track_local_mappings in spotify_user_track.items(): score = len(track_local_mappings['local_mappings']) for local_id in track_local_mappings['local_mappings']: spotify_pattern[local_id]['score'] = 1 / score save_data(spotify_pattern, "link_pattern_spotify") def fuzzy_pattern_generator(): local_library = get_data("local_library") track_descriptions = get_data("tracks") def get_matched(src_pattern, patterns): result = {} for target_pattern in patterns: similarity_score = fuzz.token_set_ratio(src_pattern, target_pattern) result[target_pattern] = similarity_score / 100 sorted_results = sorted(result.items(), key=lambda item: item[1], reverse=True) return sorted_results def resolve_tracks(s_patterns, t_patterns): pattern_map = {} total = len(s_patterns) with tqdm(total=total, desc='Progress') as pbar: for s_pattern in s_patterns: res = get_matched(s_pattern, t_patterns) matched = {"score": 0, "items": []} if len(res): matched['items'] = res[0:min(len(res), 4)] matched['score'] = res[0][1] pattern_map[s_pattern] = matched pbar.update(1) return pattern_map source_patterns = [] for track in track_descriptions: artists = get_artists_str(track['track']['artists']) pattern = f"{track['track']['name']} {artists}" source_patterns.append(pattern) target_patterns = [local['path'] for _, local in local_library.items()] fuzzy_pattern = resolve_tracks(source_patterns, target_patterns) save_data(fuzzy_pattern, "link_pattern_fuzzy") def fuzzy_tag_pattern_generator(): local_library = get_data("local_library") spotify_library = get_data("tracks") mappings = {} def fuzzy_tags_ratio(first: SongTags, second: SongTags): title_ratio = fuzz.ratio(first.title, second.title) / 100 artist_ratio = fuzz.ratio(first.artist, second.artist) / 100 album_ratio = fuzz.ratio(first.album, second.album) / 100 return sum([title_ratio, artist_ratio, album_ratio]) / 3 with tqdm(total=len(local_library), desc='Searching local songs on spotify') as pbar: for local_track_id, local_track in local_library.items(): mapping = mappings.get(local_track_id, {"score": 1.0, "items": []}) ratios = [] for remote_track in spotify_library: track = remote_track['track'] tag1 = SongTags(local_track['name'], local_track['artist'], local_track['album']) tag2 = SongTags(track['name'], get_artists_str(track['artists']), track['album']['name']) ratios.append((fuzzy_tags_ratio(tag1, tag2), track['id'])) ratios.sort(reverse=True, key=lambda x: x[0]) if ratios[0][0] > 0.8: mapping['items'] = [ratios[0][1]] mappings[local_track_id] = mapping pbar.update(1) save_data(mappings, "link_pattern_tags") def run_pattern_generators(): #fuzzy_pattern_generator() #spotify_pattern_generator() fuzzy_tag_pattern_generator() if __name__ == "__main__": run_pattern_generators()