def _status_menu(self): """Return a menu displaying the current state of the playback as well as the commands available to the user. """ title = 'Now Playing: %s' % self._player.get_media_name() stats = ( ('Playback rate', '%1.1fx' % self._player.get_playback_rate()), ('Elapsed', _format_time(self._player.get_position())), ('Total Length', _format_time(self._player.get_media_length())), ) return '\n'.join((build_menu(title, action_rows=stats), build_menu('Commands', action_rows=self._command_help)))
def all_podcasts(self, podcasts): # Build menu data new_series = ('New?', lambda podcast: '[X]' if podcast.has_update() else "[ ]", lambda f: f) name_series = ('Podcast', attrgetter('name'), lambda f: f) to_key = lambda i: str(i + 1) data_rows = build_data_rows(to_key, podcasts, new_series, name_series) # Build menu actions cb_return_menu = self.controller.all_podcasts other_actions = { 'a': ('Add a new podcast URL', self.controller.add_podcast), 'u': ('Update All Podcasts', lambda: self.controller.update_podcasts(cb_return_menu)), 't': ('View Downloaded Episodes', self.controller.downloaded_episodes), 'q': ('Quit', None) } action_rows = [(cmd, desc) for cmd, (desc, _) in other_actions.iteritems()] # Build menu page page_text = build_menu('All Podcasts', data_rows, action_rows) # Build action table actions = {} for ind, podcast in enumerate(podcasts): pid = podcast.id actions[to_key(ind)] = lambda p=pid: self.controller.episodes(p) for cmd, (_, action) in other_actions.iteritems(): actions[cmd] = action return self._menu_action(page_text, actions)
def test_no_data_rows(self): title = 'Foo' rows = (('a', 'b'), ) lines = build_menu(title, data_rows=rows).split('\n') self.assertRegexpMatches(lines[3], r'\| *%s *\| *%s *\|' % rows[0]) self.assertRegexpMatches(lines[4], r'\+-*\+-*\+') self.assertRegexpMatches(lines[5], r'\? *There\'s nothing here... *\?') self.assertRegexpMatches(lines[6], r'\+-*\+-*\+')
def test_only_actions(self): title = 'Foo' actions = (('a', 'b'), ('1', '2'), ('A', 'B')) lines = build_menu(title, action_rows=actions).split('\n') self.assertRegexpMatches(lines[3], r'\| *%s *\| *%s *\|' % actions[0]) self.assertRegexpMatches(lines[4], r'\| *%s *\| *%s *\|' % actions[1]) self.assertRegexpMatches(lines[5], r'\| *%s *\| *%s *\|' % actions[2]) self.assertRegexpMatches(lines[6], r'\+-*\+-*\+')
def test_data_rows(self): title = 'Foo' rows = (('a', 'b', 'c'), ('1', '2', '3')) lines = build_menu(title, data_rows=rows).split('\n') self.assertRegexpMatches(lines[3], r'\| *%s *\| *%s *\| *%s *\|' % rows[0]) self.assertRegexpMatches(lines[4], r'\+-*\+-*v-*\+') self.assertRegexpMatches(lines[5], r'\| *%s *\| *%s *%s *\|' % rows[1]) self.assertRegexpMatches(lines[6], r'\+-*\+-*\^-*\+')
def episodes(self, podcast, episodes, episode_range): date_series = ("Date", attrgetter('date_published'), lambda field: field.strftime('%m/%d')) dld_series = ("DLD?", lambda episode: "[%s]" % ("X" if episode.local_file is not None else " "), lambda f: f) title_series = ("Episode", attrgetter('title'), lambda f: f) to_key = lambda i: str(i + 1) data_rows = build_data_rows(to_key, episodes, date_series, dld_series, title_series) # Build menu actions cb_return_menu = lambda p=podcast.id: self.controller.episodes( p, episode_range[0]) other_actions = { 'b': ('Back to All Podcasts', self.controller.all_podcasts), 'u': ('Update', lambda: self.controller.update_podcast(podcast.id, cb_return_menu) ), 'd{n}': ('Delete an Episode', lambda: None), 'q': ('Quit', None) } next_func = lambda: self.controller.episodes(podcast.id, episode_range[ 1]) prev_func = lambda: self.controller.episodes(podcast.id, episode_range[ 0] - 10) if episode_range[1] is not None: other_actions['n'] = ('Next Page', next_func) if episode_range[0] != 0: other_actions['p'] = ('Previous Page', prev_func) action_rows = [(cmd, desc) for cmd, (desc, _) in other_actions.iteritems()] # Build menu page page_text = build_menu('`%s` Episodes' % podcast.name, data_rows, action_rows) actions = {} for ind, episode in enumerate(episodes): eid = episode.id actions[to_key( ind)] = lambda e=eid: self.controller.play(e, cb_return_menu) actions['d' + to_key(ind)] = lambda e=eid:\ self.controller.delete_episode(e, cb_return_menu) del other_actions['d{n}'] for cmd, (_, action) in other_actions.iteritems(): actions[cmd] = action return self._menu_action(page_text, actions)
def downloaded_episodes(self, episodes, podcasts): """Menu containing all episodes that are currently downloaded Args: episodes: the list of Episode objects that currently reside on the file system podcasts: a list of Podcast objects corresponding by index to each Episode in `episodes` """ # extract the 10 episodes prior to `base` date_series = ("Date", lambda e: e.local_file.date_created, lambda date: date.strftime('%m/%d')) title_series = ("Episode", attrgetter('title'), lambda f: f) # Add podcast name to episode objects for episode, podcast in zip(episodes, podcasts): episode.podcast_name = podcast.name podcast_series = ("Podcast", attrgetter('podcast_name'), lambda f: f) to_key = lambda i: str(i + 1) data_rows = build_data_rows(to_key, episodes, date_series, title_series, podcast_series) # Build menu actions other_actions = { 'b': ('Back to All Podcasts', self.controller.all_podcasts), 'd{n}': ('Delete an Episode', lambda: None), 'q': ('Quit', None) } action_rows = [(cmd, desc) for cmd, (desc, _) in other_actions.iteritems()] # Build menu page page_text = build_menu('Downloaded Episodes', data_rows, action_rows) actions = {} cb_return_menu = self.controller.downloaded_episodes for ind, episode in enumerate(episodes): eid = episode.id actions[to_key(ind)] = lambda e=eid: self.controller.play(e, cb_return_menu) actions['d' + to_key(ind)] = lambda e=eid:\ self.controller.delete_episode(e, cb_return_menu) del other_actions['d{n}'] for cmd, (_, action) in other_actions.iteritems(): actions[cmd] = action return self._menu_action(page_text, actions)
def downloaded_episodes(self, episodes, podcasts): """Menu containing all episodes that are currently downloaded Args: episodes: the list of Episode objects that currently reside on the file system podcasts: a list of Podcast objects corresponding by index to each Episode in `episodes` """ # extract the 10 episodes prior to `base` date_series = ("Date", lambda e: e.local_file.date_created, lambda date: date.strftime('%m/%d')) title_series = ("Episode", attrgetter('title'), lambda f: f) # Add podcast name to episode objects for episode, podcast in zip(episodes, podcasts): episode.podcast_name = podcast.name podcast_series = ("Podcast", attrgetter('podcast_name'), lambda f: f) to_key = lambda i: str(i + 1) data_rows = build_data_rows(to_key, episodes, date_series, title_series, podcast_series) # Build menu actions other_actions = { 'b': ('Back to All Podcasts', self.controller.all_podcasts), 'd{n}': ('Delete an Episode', lambda: None), 'q': ('Quit', None) } action_rows = [(cmd, desc) for cmd, (desc, _) in other_actions.iteritems()] # Build menu page page_text = build_menu('Downloaded Episodes', data_rows, action_rows) actions = {} cb_return_menu = self.controller.downloaded_episodes for ind, episode in enumerate(episodes): eid = episode.id actions[to_key( ind)] = lambda e=eid: self.controller.play(e, cb_return_menu) actions['d' + to_key(ind)] = lambda e=eid:\ self.controller.delete_episode(e, cb_return_menu) del other_actions['d{n}'] for cmd, (_, action) in other_actions.iteritems(): actions[cmd] = action return self._menu_action(page_text, actions)
def episodes(self, podcast, episodes, episode_range): date_series = ("Date", attrgetter('date_published'), lambda field: field.strftime('%m/%d')) dld_series = ("DLD?", lambda episode: "[%s]" % ("X" if episode.local_file is not None else " "), lambda f: f) title_series = ("Episode", attrgetter('title'), lambda f: f) to_key = lambda i: str(i + 1) data_rows = build_data_rows(to_key, episodes, date_series, dld_series, title_series) # Build menu actions cb_return_menu = lambda p=podcast.id: self.controller.episodes(p, episode_range[0]) other_actions = { 'b': ('Back to All Podcasts', self.controller.all_podcasts), 'u': ('Update', lambda: self.controller.update_podcast(podcast.id, cb_return_menu)), 'd{n}': ('Delete an Episode', lambda: None), 'q': ('Quit', None) } next_func = lambda: self.controller.episodes(podcast.id, episode_range[1]) prev_func = lambda: self.controller.episodes(podcast.id, episode_range[0] - 10) if episode_range[1] is not None: other_actions['n'] = ('Next Page', next_func) if episode_range[0] != 0: other_actions['p'] = ('Previous Page', prev_func) action_rows = [(cmd, desc) for cmd, (desc, _) in other_actions.iteritems()] # Build menu page page_text = build_menu('`%s` Episodes' % podcast.name, data_rows, action_rows) actions = {} for ind, episode in enumerate(episodes): eid = episode.id actions[to_key(ind)] = lambda e=eid: self.controller.play(e, cb_return_menu) actions['d' + to_key(ind)] = lambda e=eid:\ self.controller.delete_episode(e, cb_return_menu) del other_actions['d{n}'] for cmd, (_, action) in other_actions.iteritems(): actions[cmd] = action return self._menu_action(page_text, actions)
def test_only_title(self): title = 'Foo' lines = build_menu(title).split('\n') self.assertRegexpMatches(lines[0], r'\+-*\+') self.assertRegexpMatches(lines[1], r'\| *%s *\|' % title) self.assertRegexpMatches(lines[2], r'\+-*\+')