from DataBase import * from LocalLibraryIndexer import update_local_library from LinkerPatternGenerator import run_pattern_generators from LocalPLaylistGenerator import generate_playlists from SpotifyWebAPI import fetch_data, update_access_token import cmd local_library_path = "/home/auser/Music/" rel_autogen_dir = "0autogen" playlists = get_data('playlistTracks') top_artists = get_data('top_artists') top_tracks = get_data('top_tracks') user_tracks = get_data('tracks') link_pattern = get_data('link_pattern_spotify') local_library = get_data("local_library") user_tracks_by_id = {track['track']['id']: track['track'] for track in user_tracks} def get_playlist_names(pl): return [name for name, items in pl.items()] def print_playlist_tracks(pl_id: int): pls = list(playlists) name = pls[pl_id] pl = playlists[name] print(name) for track in pl: track_data = track['track'] track_name = track_data['name'] artists = get_artists_str(track_data['artists']) print(f" '{track_name}' - '{artists}' ") def print_top_artists(): for artist in top_artists: name = artist['name'] print(f" '{name}'") def print_top_tracks(): for track in top_tracks: track_name = track['name'] artists = get_artists_str(track['artists']) print(f" '{track_name}' - '{artists}' ") def print_stats(): print(f" tracks - {len(user_tracks)}") print(f" playlists - {len(playlists)}") for name, tracks in playlists.items(): print(f" '{name}' - {len(tracks)}") print(f" top tracks - {len(top_tracks)}") print(f" top artists - {len(top_artists)}") def print_tracks(): track_idx = 0 for trackItem in user_tracks: track = trackItem['track'] print(f" {track_idx}: '{track['name']}' by '{get_artists_str(track['artists'])}'") track_idx += 1 def sort_remote_tracks_by_popularity(track_ids): out = [] for top_track in top_tracks: if top_track['id'] in track_ids: out.append(top_track['id']) return out def print_link_stats(link_pattern): resolved_reversed = {} resolved = [] unresolved_local = [] unresolved_remote = [] for local_id, links in link_pattern.items(): if len(links['items']): resolved.append(local_id) resolved_reversed[links['items'][0]] = local_id else: unresolved_local.append(local_id) for track in user_tracks: track_id = track['track']['id'] if track_id not in resolved_reversed: unresolved_remote.append(track_id) print(f"Local Tracks: {len(local_library)}") print(f"Remote Tracks: {len(user_tracks)}") unresolved_remote = sort_remote_tracks_by_popularity(unresolved_remote) unresolved_remote = unresolved_remote[0:min(len(unresolved_remote), 100)] print(f"\nUnresolved tracks from the remote: {len(unresolved_remote)}") index = 0 for remote_id in unresolved_remote: remote_track = user_tracks_by_id[remote_id] print(f" {index}: '{remote_track['name']}' by '{get_artists_str(remote_track['artists'])}'") index += 1 print(f"\nResolved tracks: {len(resolved)}") index = 0 for link in resolved: remote_id = link_pattern[link]['items'][0] local_track = local_library[link] remote_track = user_tracks_by_id[remote_id] print(f" {index}: '{local_track['name']}' by '{local_track['artist']}'", end=' ----> ') print(f"'{remote_track['name']}' by '{get_artists_str(remote_track['artists'])}'") index += 1 class Interpreter(cmd.Cmd): intro = "Welcome to the interactive command loop. Type help or ? to list commands.\n" prompt = "(spotify) " def do_list_stat_vs_types(self, arg): """prints available linking patterns""" print(f"0 - fuzzy tags") print(f"1 - spotify") print(f"2 - fuzzy") def do_stat_local_library_vs_spotify(self, arg): """compares local library and remote with the link pattern generated by the generate_pattern_command""" print_link_stats(link_pattern) def do_playlists(self, arg): """prints user playlists""" pl_id = 0 for pl in get_playlist_names(playlists): print(f"{pl_id} - {pl}") pl_id += 1 def do_playlist_tracks(self, arg): """prints playlist [name]""" try: pl_id = int(arg.split()[0]) print_playlist_tracks(pl_id) except IndexError: print("Invalid input") def do_top_artists(self, arg): """Top artists""" print_top_artists() def do_top_tracks(self, arg): """Top tracks""" print_top_tracks() def do_stat(self, arg): """Print stats""" print_stats() def do_tracks(self, arg): """Print tracks""" print_tracks() def do_generate_local_playlists(self, arg): """generates local playlists based on the vs comparison type""" generate_playlists(local_library, local_library_path, playlists, link_pattern, local_library_path + rel_autogen_dir) def do_index_local_library(self, arg): """find local tracks and fetches the data from them for further analysis""" global local_library update_local_library(local_library_path) local_library = get_data("local_library") def do_generate_vs_stat(self, arg): """compares local and remote library and generates the vs stats""" global link_pattern run_pattern_generators() link_pattern = get_data('link_pattern_spotify') def do_fetch(self, arg): """Fetch all spotify data""" try: update_access_token() fetch_data() global playlists, top_artists, top_tracks, user_tracks playlists = get_data('playlistTracks') top_artists = get_data('top_artists') top_tracks = get_data('top_tracks') user_tracks = get_data('tracks') except ValueError: print("Can not fetch the data.") def do_generate_todo(self, arg): """generates todos for the pirates""" print("sorry not implemented yet.") def do_run_all_default(self, arg): """runs general flow""" local_lib_path = "/home/auser/Music/" print("Fetching spotify data...") self.do_fetch([]) print("Fetching local data...") self.do_index_local_library(f"{local_lib_path}/organized") print("Generating vs patterns...") self.do_generate_vs_stat("0") print("Generating todos...") self.do_generate_todo(f"{local_lib_path}") print("Generating local playlists...") self.do_generate_local_playlists(f"{local_lib_path}") return True def do_exit(self, arg): """Exit the command loop: exit""" print("Goodbye!") return True if __name__ == '__main__': try: Interpreter().cmdloop() except KeyboardInterrupt as kb: print("process terminated")