class LibraryMenu(Component): def __init__(self, stdscr, api, change_tracklist): self.stdscr = stdscr self.api = api self.change_tracklist = change_tracklist self.title = "Made For You" self.interactive = True self.items = [ { "text": "Top Tracks", "handler": self.__select_top_tracks }, { "text": "Recently Played", "handler": self.__select_recent_tracks }, { "text": "Liked Songs", "handler": self.__select_liked_tracks }, ] self.restart() def restart(self): scry, scrx = self.stdscr.getmaxyx() self.startx = 0 self.endx = round(scrx / 4) - 2 self.starty = 0 self.endy = 5 self.component = Menu( self.stdscr, self.items, self.starty, self.startx, self.endy, self.endx, self.component and self.component.active, self.component.selected if self.component and self.component.selected else 0, self.component.scroll_start if self.component and self.component.scroll_start else 0, ) def __select_top_tracks(self): self.change_tracklist(self.api.get_top_tracks(), "Top Tracks") def __select_recent_tracks(self): self.change_tracklist(self.api.get_recently_played(), "Recently Played") def __select_liked_tracks(self): self.change_tracklist(self.api.get_liked_tracks(), "Liked Songs") def receive_input(self, key): if key == curses.KEY_ENTER or key in [10, 13]: self.items[self.component.selected]["handler"]() else: self.component.receive_input(key)
class Lib(Component): def __init__(self, stdscr): self.stdscr = stdscr scry, scrx = stdscr.getmaxyx() self.interactive = True self.startx = round(scrx / 4) self.endx = scrx - 2 self.starty = 0 self.endy = scry - 10 self.items = [ "Baby one more time", "Baby one more time", "Baby one more time", "Oops, I did it again", "Toxic", "Baby one more time", "Oops, I did it again", "Toxic", "Baby one more time", "Oops, I did it again", "Toxic", "Baby one more time", "Oops, I did it again", "Oops, I did it again", "Toxic", "Baby one more time", "Oops, I did it again", "Toxic", "Baby one more time", "Oops, I did it again", "Toxic", "Baby one more time", "Oops, I did it again", "Oops, I did it again", "Toxic", "Baby one more time", "Oops, I did it again", "Toxic", "Baby one more time", "Oops, I did it again", "Toxic", "Baby one more time", "Oops, I did it again", "Toxic", "Slave4u", ] self.component = Menu( stdscr, self.items, self.starty + 1, self.startx + 2, self.endy - 1, self.endx - 2, ) def receive_input(self, key): self.component.receive_input(key)
class DeviceMenu(Component): def __init__(self, stdscr, api, select_device, close): self.stdscr = stdscr self.api = api self.select_device = select_device self.close = close self.active = True self.popup = True self.title = "Select a Device" self.interactive = True self.items = api.get_devices() self.restart() def restart(self): self.items = self.api.get_devices() scry, scrx = self.stdscr.getmaxyx() box_height = round(scry / 2) box_width = round(scrx / 2.5) self.startx = round((scrx / 2) - (box_width / 2)) self.endx = self.startx + box_width self.starty = round((scry / 2) - (box_height / 2)) self.endy = self.starty + box_height self.component = Menu( self.stdscr, list(map(self.__map_devices, self.items)) if self.items and len(self.items) > 0 else [], self.starty, self.startx, self.endy, self.endx, ) def __map_devices(self, item): available_space = self.endx - self.startx - 6 item["text"] = truncate(item["text"], available_space) def handler(): if item and "id" in item: self.select_device(item["id"]) item["handler"] = handler return item def receive_input(self, key): if ((key == curses.KEY_ENTER or key in [10, 13]) and self.items and len(self.items) > 0): self.items[self.component.selected]["handler"]() self.close() else: self.component.receive_input(key)
class PlaylistMenu(Component): def __init__(self, stdscr, api, change_tracklist): self.stdscr = stdscr self.api = api self.change_tracklist = change_tracklist self.title = "Playlists" self.interactive = True self.items = self.api.get_playlists() self.restart() def restart(self): self.items = self.api.get_playlists() scry, scrx = self.stdscr.getmaxyx() self.startx = 0 self.endx = round(scrx / 4) - 2 self.starty = 6 self.endy = scry - 5 self.component = Menu( self.stdscr, list(map(self.__map_playlists, self.items)), self.starty, self.startx, self.endy, self.endx, self.component and self.component.active, self.component.selected if self.component and self.component.selected else 0, self.component.scroll_start if self.component and self.component.scroll_start else 0, ) def __select_playlist(self, playlist_name, playlist_id, playlist_uri): self.change_tracklist(self.api.get_playlist_tracks(playlist_id), playlist_name, playlist_uri) def __map_playlists(self, item): available_space = self.endx - self.startx - 6 item["text"] = truncate(item["text"], available_space) def handler(): self.__select_playlist(item["text"], item["id"], item["uri"]) item["handler"] = handler return item def receive_input(self, key): if key == curses.KEY_ENTER or key in [10, 13]: self.items[self.component.selected]["handler"]() else: self.component.receive_input(key)
def restart(self): scry, scrx = self.stdscr.getmaxyx() box_height = round(scry / 2) box_width = round(scrx / 2.5) self.startx = round((scrx / 2) - (box_width / 2)) self.endx = self.startx + box_width self.starty = round((scry / 2) - (box_height / 2)) self.endy = self.starty + box_height self.component = Menu( self.stdscr, list(map(self.__map_devices, self.items)) if self.items and len(self.items) > 0 else [], self.starty, self.startx, self.endy, self.endx, )
def update_tracks(self, tracks, title): self.tracks = tracks self.items = list(map(self.__map_tracks, tracks)) self.title = title self.component = Menu( self.stdscr, self.items, self.starty, self.startx, self.endy, self.endx, self.component and self.component.active, self.component.selected if self.component and self.component.selected else 0, self.component.scroll_start if self.component and self.component.scroll_start else 0, )
def restart(self): scry, scrx = self.stdscr.getmaxyx() self.startx = 0 self.endx = round(scrx / 4) - 2 self.starty = 0 self.endy = 5 self.component = Menu( self.stdscr, self.items, self.starty, self.startx, self.endy, self.endx, self.component and self.component.active, self.component.selected if self.component and self.component.selected else 0, self.component.scroll_start if self.component and self.component.scroll_start else 0, )
def restart(self): self.items = self.api.get_playlists() scry, scrx = self.stdscr.getmaxyx() self.startx = 0 self.endx = round(scrx / 4) - 2 self.starty = 6 self.endy = scry - 5 self.component = Menu( self.stdscr, list(map(self.__map_playlists, self.items)), self.starty, self.startx, self.endy, self.endx, self.component and self.component.active, self.component.selected if self.component and self.component.selected else 0, self.component.scroll_start if self.component and self.component.scroll_start else 0, )
class TracksMenu(Component): def __init__(self, stdscr, api, play_track, status=None): self.stdscr = stdscr self.api = api self.currently_playing = None self.play_track = play_track self.title = "Top Tracks" self.interactive = True self.items = [] self.tracks = [] self.restart() self.refresh_now_playing(status) def restart(self): scry, scrx = self.stdscr.getmaxyx() self.startx = round(scrx / 4) self.endx = scrx - 2 self.starty = 0 self.endy = scry - 5 self.update_tracks(self.tracks, self.title) def update_tracks(self, tracks, title): self.tracks = tracks self.items = list(map(self.__map_tracks, tracks)) self.title = title self.component = Menu( self.stdscr, self.items, self.starty, self.startx, self.endy, self.endx, self.component and self.component.active, self.component.selected if self.component and self.component.selected else 0, self.component.scroll_start if self.component and self.component.scroll_start else 0, ) def refresh_now_playing(self, status): currently_playing = (status["item"]["uri"] if status and status["is_playing"] else None) if currently_playing and currently_playing != self.currently_playing: self.currently_playing = currently_playing self.restart() def receive_input(self, key): if key == curses.KEY_ENTER or key in [10, 13]: if len(self.items) > 0: self.items[self.component.selected]["handler"]() else: self.component.receive_input(key) def __map_tracks(self, track): available_space = self.endx - self.startx highlight = self.currently_playing and self.currently_playing == track[ "uri"] max_word_length = round((available_space / 2) - 3) track_name = self.__pad_track_text( truncate(track["name"], max_word_length), max_word_length, ) artist_name = self.__pad_track_text( truncate(track["artist"], max_word_length), max_word_length, ) def handler(): self.play_track(track["uri"]) return { "text": track_name + " " + artist_name, "handler": handler, "highlight": highlight, } def __pad_track_text(self, text, max_word_length): spaces_needed = max_word_length - len(text) if spaces_needed > 0: for i in range(0, spaces_needed + 1): text += " " return text