class SearchPage(urwid.Pile, AbstractPage): """ Search page. Allows to perform searches & displays search results. """ @property def name(self): return 'Search' @property def key(self): return 4 def __init__(self, app): self.app = app self.songlist = SongListBox(app) self.search_box = SearchBox() urwid.connect_signal(self.search_box, 'search-requested', self.perform_search) super(SearchPage, self).__init__([ ('pack', self.search_box), ('pack', urwid.Divider(u'\u2500')), self.songlist ]) def perform_search(self, query): """ Search tracks by query. """ self.songlist.set_placeholder(u' \U0001F50D Searching for "{}"...'.format( query )) GP.get().search_async(query, callback=self.search_finished) def search_finished(self, results, error): """ Populate song list with search results. """ if error: NotificationArea.notify('Failed to search: {}'.format(str(error))) else: self.songlist.populate(results.get_tracks()) self.app.redraw() def activate(self): pass def keypress(self, size, key): if key == 'tab': if self.focus == self.search_box: self.focus_position = 2 else: self.focus_position = 0 return None else: return super(SearchPage, self).keypress(size, key)
class MyStationsPage(urwid.Columns, AbstractPage): """ Stations page. Contains two parts: - List of stations (:class:`.MyStationBox`) - List of songs in selected station (:class:`clay:songlist:SongListBox`) """ @property def name(self): return 'Stations' @property def key(self): return 3 @property def slug(self): """ Return page ID (str). """ return "stations" def __init__(self, app): self.app = app self.stationlist = MyStationListBox(app) self.songlist = SongListBox(app) self.songlist.set_placeholder('\n Select a station.') urwid.connect_signal(self.stationlist, 'activate', self.mystationlistitem_activated) super(MyStationsPage, self).__init__([self.stationlist, self.songlist]) def mystationlistitem_activated(self, mystationlistitem): """ Called when specific station is selected. Requests fetching of station tracks """ self.songlist.set_placeholder(u'\n \uf01e Loading station tracks...') mystationlistitem.station.load_tracks_async( callback=self.on_station_loaded) def on_station_loaded(self, station, error): """ Called when station tracks fetch completes. Populates songlist with tracks from the selected station. """ if error: notification_area.notify('Failed to get station tracks: {}'.format( str(error))) self.songlist.populate(station.get_tracks()) self.app.redraw() def activate(self): pass
class MyLibraryPage(urwid.Columns, AbstractPage): """ My library page. Displays :class:`clay.songlist.SongListBox` with all songs in library. """ @property def name(self): return 'Library' @property def key(self): return 1 @property def slug(self): """ Return page ID (str). """ return "library" def __init__(self, app): self.app = app self.songlist = SongListBox(app) self.notification = None gp.auth_state_changed += self.get_all_songs gp.caches_invalidated += self.get_all_songs super(MyLibraryPage, self).__init__([self.songlist]) def on_get_all_songs(self, tracks, error): """ Called when all library songs are fetched from server. Populate song list. """ if error: notification_area.notify('Failed to load my library: {}'.format( str(error))) return tracks.sort(key=lambda k: k.original_data['title']) self.songlist.populate(tracks) self.app.redraw() def get_all_songs(self, *_): """ Called when auth state changes or GP caches are invalidated. """ if gp.is_authenticated: self.songlist.set_placeholder(u'\n \uf01e Loading song list...') gp.get_all_tracks_async(callback=self.on_get_all_songs) self.app.redraw() def activate(self): pass
class MyLibraryPage(urwid.Columns, AbstractPage): """ My library page. Displays :class:`clay.songlist.SongListBox` with all songs in library. """ @property def name(self): return 'Library' @property def key(self): return 1 def __init__(self, app): self.app = app self.songlist = SongListBox(app) self.notification = None GP.get().auth_state_changed += self.get_all_songs GP.get().caches_invalidated += self.get_all_songs super(MyLibraryPage, self).__init__([self.songlist]) def on_get_all_songs(self, tracks, error): """ Called when all library songs are fetched from server. Populate song list. """ if error: NotificationArea.notify('Failed to load my library: {}'.format( str(error))) return # self.notification.close() self.songlist.populate(tracks) self.app.redraw() def get_all_songs(self, *_): """ Called when auth state changes or GP caches are invalidated. """ if GP.get().is_authenticated: self.songlist.set_placeholder(u'\n \uf01e Loading song list...') GP.get().get_all_tracks_async(callback=self.on_get_all_songs) self.app.redraw() # self.notification = NotificationArea.notify('Loading library...') def activate(self): pass
class MyPlaylistsPage(urwid.Columns, AbstractPage): """ Playlists page. Contains two parts: - List of playlists (:class:`.MyPlaylistListBox`) - List of songs in selected playlist (:class:`clay:songlist:SongListBox`) """ @property def name(self): return 'Playlists' @property def key(self): return 2 @property def slug(self): """ Return page ID (str). """ return "playlists" def __init__(self, app): self.app = app self.myplaylistlist = MyPlaylistListBox(app) self.songlist = SongListBox(app) self.songlist.set_placeholder('\n Select a playlist.') urwid.connect_signal(self.myplaylistlist, 'activate', self.myplaylistlistitem_activated) super(MyPlaylistsPage, self).__init__([self.myplaylistlist, self.songlist]) def myplaylistlistitem_activated(self, myplaylistlistitem): """ Called when specific playlist is selected. Populates songlist with tracks from the selected playlist. """ self.songlist.populate(myplaylistlistitem.get_tracks()) def activate(self): pass