subclient

Subsonic ncurses client
git clone https://git.e1e0.net/subclient.git
Log | Files | Refs | README

commit e41825454efb2f1fce17d5d74ae9facdb0d4f0b6
parent f1f24ef751e8b3eaf6a4d8423f62e856140828f1
Author: Paco Esteban <paco@e1e0.net>
Date:   Sat, 19 Jun 2021 20:01:47 +0200

ui remodel + playlist approach

Diffstat:
Msubclient/subclient.py | 181+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
1 file changed, 117 insertions(+), 64 deletions(-)

diff --git a/subclient/subclient.py b/subclient/subclient.py @@ -29,94 +29,147 @@ class SubClient: self.subsonic = subsonic.Subsonic(self.config['subclient']) self.player = playback.Player() self.master = master + self.current_artist = None + self.current_album = None self.current_song = None + self.playlist = [] + self.what = 0 self.master.run_on_exit(self.player.exit) self.master.add_key_command(py_cui.keys.KEY_SPACE, self.pause) # The scrolled list cells that will contain our tasks in each of the # three categories - self.artist_scroll_cell = self.master.add_scroll_menu( + self.nav_scroll_cell = self.master.add_scroll_menu( 'Artists', 0, 0, row_span=4, column_span=1) - self.album_scroll_cell = self.master.add_scroll_menu( - 'Albums', 0, 1, row_span=4, column_span=1) - self.song_scroll_cell = self.master.add_scroll_menu( - 'Songs', 0, 2, row_span=4, column_span=1) + self.play_scroll_cell = self.master.add_scroll_menu( + 'Playlist', 0, 1, row_span=4, column_span=1) self.now_playing_block = self.master.add_block_label( - 'Now', 4, 0, row_span=1, column_span=3) + 'Now', 4, 0, row_span=1, column_span=2) # self.master.add_key_command(py_cui.keys.KEY_Q_LOWER, self._exit) - self.artist_scroll_cell.add_key_command(py_cui.keys.KEY_ENTER, - self.update_albums) - self.artist_scroll_cell.add_key_command(py_cui.keys.KEY_TAB, - self._switch_to_next) - self.artist_scroll_cell.add_key_command(py_cui.keys.KEY_SPACE, - self.pause) - self.artist_scroll_cell.add_key_command(py_cui.keys.KEY_Q_LOWER, - self.quit) - self.album_scroll_cell.add_key_command(py_cui.keys.KEY_ENTER, - self.update_songs) - self.album_scroll_cell.add_key_command(py_cui.keys.KEY_TAB, - self._switch_to_next) - self.album_scroll_cell.add_key_command(py_cui.keys.KEY_SPACE, - self.pause) - self.album_scroll_cell.add_key_command(py_cui.keys.KEY_Q_LOWER, - self.quit) - self.song_scroll_cell.add_key_command(py_cui.keys.KEY_ENTER, - self.play_song) - self.song_scroll_cell.add_key_command(py_cui.keys.KEY_TAB, - self._switch_to_first) - self.song_scroll_cell.add_key_command(py_cui.keys.KEY_SPACE, + self.nav_scroll_cell.add_key_command(py_cui.keys.KEY_ENTER, + self.play_from_here) + self.nav_scroll_cell.add_key_command(py_cui.keys.KEY_TAB, + self._switch_to_play) + self.nav_scroll_cell.add_key_command(py_cui.keys.KEY_SPACE, + self.pause) + self.nav_scroll_cell.add_key_command(py_cui.keys.KEY_Q_LOWER, + self.quit) + self.nav_scroll_cell.add_key_command(py_cui.keys.KEY_H_LOWER, + self._nav_back) + self.nav_scroll_cell.add_key_command(py_cui.keys.KEY_J_LOWER, + self._nav_down) + self.nav_scroll_cell.add_key_command(py_cui.keys.KEY_K_LOWER, + self._nav_up) + self.nav_scroll_cell.add_key_command(py_cui.keys.KEY_L_LOWER, + self._nav_forward) + self.nav_scroll_cell.add_key_command(py_cui.keys.KEY_G_LOWER, + self._nav_top) + self.nav_scroll_cell.add_key_command(py_cui.keys.KEY_G_UPPER, + self._nav_bottom) + self.play_scroll_cell.add_key_command(py_cui.keys.KEY_TAB, + self._switch_to_nav) + self.play_scroll_cell.add_key_command(py_cui.keys.KEY_SPACE, self.pause) - self.song_scroll_cell.add_key_command(py_cui.keys.KEY_Q_LOWER, + self.play_scroll_cell.add_key_command(py_cui.keys.KEY_Q_LOWER, self.quit) status_bar_text = ('Quit - q | Pause - space | ' 'Select - enter | Cycle list - tab') - self.artist_scroll_cell.set_focus_text(status_bar_text) - self.album_scroll_cell.set_focus_text(status_bar_text) - self.song_scroll_cell.set_focus_text(status_bar_text) - - self.update_artists() - self.master.move_focus(self.artist_scroll_cell) - - def update_artists(self): - artists = self.subsonic.get_artists() - self.artist_scroll_cell.add_item_list(artists) - - def update_albums(self): - self.album_scroll_cell.clear() - artist = self.artist_scroll_cell.get() - albums = self.subsonic.get_albums_from_artist(artist) - self.album_scroll_cell.add_item_list(albums) - - def update_songs(self): - self.song_scroll_cell.clear() - album = self.album_scroll_cell.get() - songs = self.subsonic.get_songs_from_album(album) - self.song_scroll_cell.add_item_list(songs) + self.nav_scroll_cell.set_focus_text(status_bar_text) + self.play_scroll_cell.set_focus_text(status_bar_text) + + self.update_nav() + self.master.move_focus(self.nav_scroll_cell) + + def update_nav(self, back=False): + if self.what == 0: + items = self.subsonic.get_artists() + self.nav_scroll_cell.set_title('Artists') + elif self.what == 1: + if not back: + self.current_artist = self.nav_scroll_cell.get() + items = self.subsonic.get_albums_from_artist(self.current_artist) + self.nav_scroll_cell.set_title(self.current_artist.name) + elif self.what == 2: + if not back: + self.current_album = self.nav_scroll_cell.get() + items = self.subsonic.get_songs_from_album(self.current_album) + self.curr_album_songs = items + self.nav_scroll_cell.set_title( + self.current_artist.name + + ' | ' + + self.current_album.title) + else: + raise Exception('unknown nav update') + self.nav_scroll_cell.clear() + self.nav_scroll_cell.add_item_list(items) + + def play_from_here(self): + self.update_playlist() + self.play_song() + + def update_playlist(self): + self.current_song = self.nav_scroll_cell.get() + self.playlist = self.curr_album_songs[ + self.curr_album_songs.index(self.current_song):] + self.play_scroll_cell.clear() + self.play_scroll_cell.add_item_list(self.playlist) def play_song(self): - self.current_song = self.song_scroll_cell.get() self.now_playing_block.set_title( - self._now_playing_format('Now Playing', self.current_song)) - stream = self.subsonic.get_song_stream(self.current_song) + self._now_playing_format('Now Playing', self.playlist[0])) + stream = self.subsonic.get_song_stream(self.playlist[0]) + del self.playlist[0] self.player.play(stream) def _now_playing_format(self, state, song): return (f'{state}:\n' f'{song.title} ({helpers.format_duration(song.duration)})') - def _switch_to_next(self): - all_widgets = self.master.get_widgets() - current_widget = self.master.get_selected_widget() - neighbors = self.master._get_horizontal_neighbors( - current_widget, - py_cui.keys.KEY_RIGHT_ARROW) - self.master.move_focus(all_widgets[neighbors[0]]) - - def _switch_to_first(self): - self.master.move_focus(self.artist_scroll_cell) + def _switch_to_nav(self): + self.master.move_focus(self.nav_scroll_cell) + + def _switch_to_play(self): + self.master.move_focus(self.play_scroll_cell) + + def _nav_down(self): + new_index = self.nav_scroll_cell.get_selected_item_index() + 1 + max_len = len(self.nav_scroll_cell.get_item_list()) - 1 + if new_index > max_len: + new_index = max_len + self.nav_scroll_cell.set_selected_item_index(new_index) + + def _nav_up(self): + new_index = self.nav_scroll_cell.get_selected_item_index() - 1 + if new_index < 0: + new_index = 0 + self.nav_scroll_cell.set_selected_item_index(new_index) + + def _nav_top(self): + self.nav_scroll_cell.set_selected_item_index(0) + self.nav_scroll_cell._jump_to_top() + + def _nav_bottom(self): + max_len = len(self.nav_scroll_cell.get_item_list()) - 1 + self.nav_scroll_cell.set_selected_item_index(max_len) + self.nav_scroll_cell._jump_to_bottom( + self.nav_scroll_cell.get_viewport_height()) + + def _nav_back(self): + self.what -= 1 + if self.what < 0: + self.what = 0 + return + self.update_nav(back=True) + + def _nav_forward(self): + self.what += 1 + if self.what > 2: + self.what = 2 + return + self.update_nav() def pause(self): paused = self.player.is_paused() @@ -132,7 +185,7 @@ class SubClient: def main(): - root = py_cui.PyCUI(5, 3) + root = py_cui.PyCUI(5, 2) # enable unicode box chars root.toggle_unicode_borders() root.set_title('SubsonicClient')