Пример #1
0
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer

        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.listeners = listeners
        self.listeners[KEY_LIST] = self.set_list
        self.factory = Factory(util)
        dbutil = util.get_db_util()
        self.selector = Selector(dbutil)

        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)

        MenuScreen.__init__(self,
                            util,
                            listeners,
                            ROWS,
                            COLUMNS,
                            voice_assistant, [ROWS, COLUMNS],
                            self.turn_page,
                            page_in_title=False,
                            show_loading=False)

        m = self.factory.create_collection_menu_button
        self.topic_menu = MultiPageMenu(util,
                                        self.next_page,
                                        self.previous_page,
                                        self.set_title,
                                        self.reset_title,
                                        self.go_to_page,
                                        m,
                                        ROWS,
                                        COLUMNS,
                                        None, (0, 0, 0),
                                        self.menu_layout,
                                        align=ALIGN_LEFT)
        self.set_menu(self.topic_menu)

        self.navigator = TopicNavigator(self.util, self.layout.BOTTOM,
                                        listeners)
        self.components.append(self.navigator)

        self.current_topic = None
        self.current_item = None
        self.current_page_items = None
        self.first_item = None
        self.last_item = None
        self.collection_topic = None
        self.previous_page = 1
        self.search_string = None
        self.source = None
        self.mode = KEY_LIST
        self.animated_title = True
Пример #2
0
 def __init__(self, util, listeners, go_book_by_genre, genres, base_url,
              voice_assistant, d):
     self.util = util
     self.go_book_by_genre = go_book_by_genre
     self.config = util.config
     self.genres_list = genres
     self.base_url = base_url
     self.factory = Factory(util)
     MenuScreen.__init__(self, util, listeners, MENU_ROWS, MENU_COLUMNS,
                         voice_assistant, d, self.turn_page)
     self.total_pages = math.ceil(len(genres) / PAGE_SIZE)
     self.title = self.config[LABELS][KEY_CHOOSE_GENRE]
     m = self.create_book_genre_menu_button
     font_size = int(((self.menu_layout.h / MENU_ROWS) / 100) *
                     self.config[FONT_HEIGHT_PERCENT])
     self.genre_menu = MultiPageMenu(util,
                                     self.next_page,
                                     self.previous_page,
                                     self.set_title,
                                     self.reset_title,
                                     self.go_to_page,
                                     m,
                                     MENU_ROWS,
                                     MENU_COLUMNS,
                                     None, (0, 0, 0, 0),
                                     self.menu_layout,
                                     font_size=font_size)
     self.set_menu(self.genre_menu)
     self.navigator = BookNavigator(util, self.layout.BOTTOM, listeners,
                                    d[4])
     self.add_component(self.navigator)
     self.turn_page()
Пример #3
0
    def __init__(self, util, listeners, ch, f, go_author, parser, base_url,
                 voice_assistant, d):
        """ Initializer
        
        :param util: utility object
        :param listeners: screen listeners
        :param ch: selected character
        :param f: selected filter
        :param go_authors: callback
        :param parser: authors parser
        :param base_url: url
        :param d: dictionary with menu button flags 
        """
        self.util = util
        self.factory = Factory(util)
        self.base_url = base_url
        self.config = util.config

        self.parser = parser
        self.current_author_char = ch
        self.current_author_filter = f
        self.go_author = go_author
        self.author_cache = {}
        self.title = self.config[LABELS][KEY_AUTHORS]

        MenuScreen.__init__(self, util, listeners, MENU_ROWS, MENU_COLUMNS,
                            voice_assistant, d, self.turn_page)
        m = self.factory.create_book_author_menu_button

        self.authors_menu = MultiPageMenu(util, self.next_page,
                                          self.previous_page, self.set_title,
                                          self.reset_title, self.go_to_page, m,
                                          MENU_ROWS, MENU_COLUMNS, None,
                                          (0, 0, 0), self.menu_layout)
        self.set_menu(self.authors_menu)
Пример #4
0
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer

        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.listeners = listeners
        self.factory = Factory(util)
        self.go_home = listeners[KEY_HOME]
        self.go_file_playback = listeners[KEY_PLAY_COLLECTION]

        dbutil = util.get_db_util()
        self.selector = Selector(dbutil)

        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)

        MenuScreen.__init__(self,
                            util,
                            listeners,
                            ROWS,
                            COLUMNS,
                            voice_assistant, [ROWS, COLUMNS],
                            self.turn_page,
                            page_in_title=False,
                            show_loading=False)

        m = self.factory.create_collection_menu_button
        font_size = int(((self.menu_layout.h / ROWS) / 100) * FONT_HEIGHT)
        self.collection_list_menu = MultiPageMenu(util,
                                                  self.next_page,
                                                  self.previous_page,
                                                  self.set_title,
                                                  self.reset_title,
                                                  self.go_to_page,
                                                  m,
                                                  ROWS,
                                                  COLUMNS,
                                                  None, (0, 0, 0, 0),
                                                  self.menu_layout,
                                                  align=ALIGN_LEFT,
                                                  font_size=font_size)
        self.set_menu(self.collection_list_menu)

        self.navigator = TopicDetailNavigator(self.util, self.layout.BOTTOM,
                                              listeners)
        self.add_component(self.navigator)
        self.current_item = None
        self.current_page_items = None
        self.first_item = None
        self.last_item = None
        self.collection_topic = None
        self.selection = None
        self.prev_page = 1
        self.animated_title = True
Пример #5
0
 def __init__(self,
              util,
              next_page,
              previous_page,
              set_title,
              reset_title,
              go_to_page,
              play_track,
              bgr=None,
              bounding_box=None):
     """ Initializer
     
     :param util: utility object
     :param next_page: next page callback
     :param previous_page: previous page callback
     :param set_title: set title callback
     :param reset_title: reset title callback
     :param go_to_page: go to page callback
     :param play_track: play track callback
     :param bgr: menu background
     :param bounding_box: bounding box
     """
     self.factory = Factory(util)
     self.util = util
     self.next_page = next_page
     self.previous_page = previous_page
     self.bb = bounding_box
     m = self.factory.create_track_menu_button
     MultiPageMenu.__init__(self, util, next_page, previous_page, set_title,
                            reset_title, go_to_page, m, TRACK_ROWS,
                            TRACK_COLUMNS, None, bgr, bounding_box)
     self.config = util.config
     self.play_track = play_track
     self.tracks = None
Пример #6
0
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer
        
        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.listeners = listeners
        self.factory = Factory(util)

        self.podcasts_util = util.get_podcasts_util()
        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)

        d = [MENU_ROWS_PODCASTS, MENU_COLUMNS_PODCASTS]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS_PODCASTS,
                            MENU_COLUMNS_PODCASTS,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False,
                            show_loading=True)
        self.title = self.config[LABELS][PODCASTS]

        m = self.factory.create_podcast_menu_button
        self.podcasts_menu = MultiPageMenu(util,
                                           self.next_page,
                                           self.previous_page,
                                           self.set_title,
                                           self.reset_title,
                                           self.go_to_page,
                                           m,
                                           MENU_ROWS_PODCASTS,
                                           MENU_COLUMNS_PODCASTS,
                                           None, (0, 0, 0),
                                           self.menu_layout,
                                           align=ALIGN_CENTER)
        self.set_menu(self.podcasts_menu)

        self.navigator = PodcastNavigator(
            self.util, self.layout.BOTTOM, listeners,
            self.config[COLORS][COLOR_DARK_LIGHT], PAGE_SIZE_PODCASTS + 1)
        self.components.append(self.navigator)

        url = self.config[PODCASTS][PODCAST_URL]
        if url and len(url) > 0:
            self.current_page = self.podcasts_util.get_podcast_page(
                url, PAGE_SIZE_PODCASTS)
        else:
            self.current_page = 1

        self.animated_title = True
Пример #7
0
    def __init__(self, util, listeners, voice_assistant, state):
        """ Initializer
        
        :param util: utility object
        :param listeners: file browser listeners
        :param voice_assistant: voice assistant
        :param state: button state
        """
        self.util = util
        self.config = util.config
        self.podcasts_util = util.get_podcasts_util()
        self.listeners = listeners
        self.factory = Factory(util)
        self.bounding_box = util.screen_rect
        self.layout = BorderLayout(self.bounding_box)
        self.layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                            PERCENT_BOTTOM_HEIGHT, 0, 0)

        d = [MENU_ROWS_EPISODES, MENU_COLUMNS_EPISODES]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS_EPISODES,
                            MENU_COLUMNS_EPISODES,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False)

        if hasattr(state, "podcast_url"):
            podcast_url = state.podcast_url
            self.title = self.podcasts_util.summary_cache[podcast_url].name
        else:
            self.title = state.name

        m = self.factory.create_episode_menu_button
        self.episodes_menu = MultiPageMenu(util,
                                           self.next_page,
                                           self.previous_page,
                                           self.set_title,
                                           self.reset_title,
                                           self.go_to_page,
                                           m,
                                           MENU_ROWS_EPISODES,
                                           MENU_COLUMNS_EPISODES,
                                           None, (0, 0, 0),
                                           self.menu_layout,
                                           align=ALIGN_MIDDLE)
        self.set_menu(self.episodes_menu)

        self.total_pages = PAGE_SIZE_EPISODES * 2
        self.episodes = []
        self.navigator = EpisodeNavigator(
            self.util, self.layout.BOTTOM, listeners,
            self.config[COLORS][COLOR_DARK_LIGHT], self.total_pages)
        self.components.append(self.navigator)
        self.current_page = 1

        self.save_episode_listeners = []
Пример #8
0
    def __init__(self, util, listeners, voice_assistant):
        self.util = util
        self.config = util.config
        self.groups_list = self.util.get_stations_folders()
        self.factory = Factory(util)
        d = [MENU_ROWS, MENU_COLUMNS]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS,
                            MENU_COLUMNS,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False)
        self.total_pages = math.ceil(len(self.groups_list) / PAGE_SIZE)
        self.title = util.get_stations_top_folder()
        m = self.create_genre_menu_button
        label_area = (
            (self.menu_layout.h / MENU_ROWS) / 100) * (100 - ICON_AREA)
        font_size = int((label_area / 100) * FONT_HEIGHT)

        self.navigator = RadioGroupNavigator(self.util, self.layout.BOTTOM,
                                             listeners, self.total_pages)
        self.add_navigator(self.navigator)
        self.player_button = self.navigator.get_button_by_name(KEY_PLAYER)
        if self.total_pages > 1:
            self.left_button = self.navigator.get_button_by_name(KEY_PAGE_DOWN)
            self.right_button = self.navigator.get_button_by_name(KEY_PAGE_UP)

        self.groups_menu = MultiPageMenu(util,
                                         self.next_page,
                                         self.previous_page,
                                         self.set_title,
                                         self.reset_title,
                                         self.go_to_page,
                                         m,
                                         MENU_ROWS,
                                         MENU_COLUMNS,
                                         None, (0, 0, 0, 0),
                                         self.menu_layout,
                                         align=ALIGN_CENTER,
                                         font_size=font_size)
        self.groups_menu.add_listener(listeners[KEY_GENRE])
        self.set_menu(self.groups_menu)

        current_name = self.get_current_group_name()

        if current_name == None:
            self.current_page = 1
        else:
            try:
                current_group_index = self.groups_list.index(current_name)
                self.current_page = int(current_group_index / PAGE_SIZE) + 1
            except:
                current_group_index = 0

        self.turn_page()
Пример #9
0
    def __init__(self, util, listeners, voice_assistant):
        self.util = util
        self.config = util.config
        self.groups_list = self.util.get_stations_folders()
        self.factory = Factory(util)
        d = [MENU_ROWS, MENU_COLUMNS]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS,
                            MENU_COLUMNS,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False)
        self.total_pages = math.ceil(len(self.groups_list) / PAGE_SIZE)
        self.title = util.get_stations_top_folder()
        m = self.factory.create_genre_menu_button

        self.groups_menu = MultiPageMenu(util,
                                         self.next_page,
                                         self.previous_page,
                                         self.set_title,
                                         self.reset_title,
                                         self.go_to_page,
                                         m,
                                         MENU_ROWS,
                                         MENU_COLUMNS,
                                         None, (0, 0, 0),
                                         self.menu_layout,
                                         align=ALIGN_CENTER)
        self.groups_menu.add_listener(listeners[KEY_GENRE])
        self.set_menu(self.groups_menu)

        color_dark_light = self.config[COLORS][COLOR_DARK_LIGHT]
        self.navigator = RadioGroupNavigator(self.util, self.layout.BOTTOM,
                                             listeners, color_dark_light,
                                             self.total_pages)
        self.components.append(self.navigator)

        current_name = self.get_current_group_name()

        if current_name == None:
            self.current_page = 1
        else:
            try:
                current_group_index = self.groups_list.index(current_name)
                self.current_page = int(current_group_index / PAGE_SIZE) + 1
            except:
                current_group_index = 0

        self.turn_page()
Пример #10
0
class BookGenre(MenuScreen):
    """ Bokk genre screen """
    def __init__(self, util, listeners, go_book_by_genre, genres, base_url,
                 voice_assistant, d):
        self.util = util
        self.go_book_by_genre = go_book_by_genre
        self.config = util.config
        self.genres_list = genres
        self.base_url = base_url
        self.factory = Factory(util)
        MenuScreen.__init__(self, util, listeners, MENU_ROWS, MENU_COLUMNS,
                            voice_assistant, d, self.turn_page)
        self.total_pages = math.ceil(len(genres) / PAGE_SIZE)
        self.title = self.config[LABELS][KEY_CHOOSE_GENRE]
        m = self.factory.create_book_genre_menu_button
        self.genre_menu = MultiPageMenu(util, self.next_page,
                                        self.previous_page, self.set_title,
                                        self.reset_title, self.go_to_page, m,
                                        MENU_ROWS, MENU_COLUMNS, None,
                                        (0, 0, 0), self.menu_layout)
        self.set_menu(self.genre_menu)
        self.turn_page()

    def turn_page(self):
        """ Turn book genre page """

        start = (self.current_page - 1) * PAGE_SIZE
        end = self.current_page * PAGE_SIZE
        page = self.genres_list[start:end]
        self.genres_dict = self.factory.create_book_genre_items(
            page, self.base_url)
        self.genre_menu.set_items(self.genres_dict, 0, self.go_book_by_genre,
                                  False)
        self.genre_menu.align_labels(ALIGN_LEFT)
        self.genre_menu.select_by_index(0)
        self.genre_menu.clean_draw_update()

        self.navigator.left_button.change_label(str(self.current_page - 1))
        self.navigator.right_button.change_label(
            str(self.total_pages - self.current_page))
        self.set_title(self.current_page)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        self.navigator.add_observers(update_observer, redraw_observer)
        self.genre_menu.add_menu_observers(update_observer,
                                           redraw_observer,
                                           release=False)
Пример #11
0
    def __init__(self, util, listeners, ch, f, go_author, parser, base_url,
                 voice_assistant, d):
        """ Initializer
        
        :param util: utility object
        :param listeners: screen listeners
        :param ch: selected character
        :param f: selected filter
        :param go_authors: callback
        :param parser: authors parser
        :param base_url: url
        :param d: dictionary with menu button flags 
        """
        self.util = util
        self.factory = Factory(util)
        self.base_url = base_url
        self.config = util.config

        self.parser = parser
        self.current_author_char = ch
        self.current_author_filter = f
        self.go_author = go_author
        self.author_cache = {}
        self.title = self.config[LABELS][KEY_AUTHORS]

        MenuScreen.__init__(self, util, listeners, MENU_ROWS, MENU_COLUMNS,
                            voice_assistant, d, self.turn_page)
        m = self.create_book_author_menu_button

        self.navigator = BookNavigator(util, self.layout.BOTTOM, listeners,
                                       d[4])
        self.back_button = self.navigator.get_button_by_name(KEY_BACK)
        self.left_button = self.navigator.get_button_by_name(KEY_PAGE_DOWN)
        self.right_button = self.navigator.get_button_by_name(KEY_PAGE_UP)
        self.add_navigator(self.navigator)

        font_size = int(((self.menu_layout.h / MENU_ROWS) / 100) *
                        self.config[FONT_HEIGHT_PERCENT])
        self.authors_menu = MultiPageMenu(util,
                                          self.next_page,
                                          self.previous_page,
                                          self.set_title,
                                          self.reset_title,
                                          self.go_to_page,
                                          m,
                                          MENU_ROWS,
                                          MENU_COLUMNS,
                                          None, (0, 0, 0),
                                          self.menu_layout,
                                          font_size=font_size)
        self.set_menu(self.authors_menu)
Пример #12
0
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer

        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.listeners = listeners
        self.factory = Factory(util)
        self.go_home = listeners[KEY_HOME]
        self.go_keyboard = listeners[KEY_KEYBOARD_KEY]
        self.keyboard_callback = listeners[KEY_CALLBACK]

        self.wifi_selection_listeners = []

        self.wifi_util = WiFiUtil(util)
        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT, PERCENT_BOTTOM_HEIGHT, 0, 0)

        d = [MENU_ROWS_WIFI, MENU_COLUMNS_WIFI]
        MenuScreen.__init__(self, util, listeners, MENU_ROWS_WIFI, MENU_COLUMNS_WIFI, voice_assistant, d,
                            self.turn_page, page_in_title=False, show_loading=False)
        self.title = self.config[LABELS]["select.wifi"]
        self.set_title(1)

        m = self.factory.create_wifi_menu_button
        self.wifi_menu = MultiPageMenu(util, self.next_page, self.previous_page, self.set_title, self.reset_title,
                                           self.go_to_page, m, MENU_ROWS_WIFI, MENU_COLUMNS_WIFI, None,
                                           (0, 0, 0), self.menu_layout, align=ALIGN_MIDDLE)
        self.set_menu(self.wifi_menu)

        listeners[KEY_REFRESH] = self.set_current
        listeners[KEY_SORT] = self.sort_abc
        self.navigator = WiFiNavigator(self.util, self.layout.BOTTOM, listeners, PAGE_SIZE_WIFI + 1)
        self.components.append(self.navigator)
        self.original_networks = None
        self.networks = None
        self.sort_direction = False
        self.current_network = None
Пример #13
0
 def __init__(self, util, listeners, go_book_by_genre, genres, base_url,
              voice_assistant, d):
     self.util = util
     self.go_book_by_genre = go_book_by_genre
     self.config = util.config
     self.genres_list = genres
     self.base_url = base_url
     self.factory = Factory(util)
     MenuScreen.__init__(self, util, listeners, MENU_ROWS, MENU_COLUMNS,
                         voice_assistant, d, self.turn_page)
     self.total_pages = math.ceil(len(genres) / PAGE_SIZE)
     self.title = self.config[LABELS][KEY_CHOOSE_GENRE]
     m = self.factory.create_book_genre_menu_button
     self.genre_menu = MultiPageMenu(util, self.next_page,
                                     self.previous_page, self.set_title,
                                     self.reset_title, self.go_to_page, m,
                                     MENU_ROWS, MENU_COLUMNS, None,
                                     (0, 0, 0), self.menu_layout)
     self.set_menu(self.genre_menu)
     self.turn_page()
Пример #14
0
 def __init__(self, util, next_page, previous_page, set_title, reset_title, go_to_page, callback, rows, columns, menu_button_layout, bounding_box=None):
     """ Initializer
     
     :param util: utility object
     :param next_page: next page callback
     :param previous_page: previous page callback
     :param set_title: set title callback
     :param reset_title: reset title callback
     :param go_to_page: go to page callback
     :param callback: 
     :param rows: menu rows
     :param columns: menu columns
     :param menu_button_layout: button layout
     :param bounding_box: bounding box
     """ 
     self.factory = Factory(util)
     self.util = util
     
     self.callback = callback
     self.config = self.util.config
     m = self.create_book_menu_button
     self.bounding_box = bounding_box
     self.menu_button_layout = menu_button_layout        
     
     MultiPageMenu.__init__(self, util, next_page, previous_page, set_title, reset_title, go_to_page, m, rows, 
         columns, menu_button_layout, None, bounding_box, align=ALIGN_CENTER)
     
     self.browsing_history = {}        
     self.left_number_listeners = []
     self.right_number_listeners = []
     self.change_folder_listeners = []
     self.play_file_listeners = []
     self.playlist_size_listeners = []
     self.menu_navigation_listeners = []
     self.page_turned = False
     self.separator = os.sep
     self.selected_index = 0
     self.empty_state = State()
Пример #15
0
class PodcastEpisodesScreen(MenuScreen):
    """ Podcast Episodes Screen """
    def __init__(self, util, listeners, voice_assistant, state):
        """ Initializer
        
        :param util: utility object
        :param listeners: file browser listeners
        :param voice_assistant: voice assistant
        :param state: button state
        """
        self.util = util
        self.config = util.config
        self.podcasts_util = util.get_podcasts_util()
        self.listeners = listeners
        self.factory = Factory(util)
        self.bounding_box = util.screen_rect
        self.layout = BorderLayout(self.bounding_box)
        self.layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                            PERCENT_BOTTOM_HEIGHT, 0, 0)

        d = [MENU_ROWS_EPISODES, MENU_COLUMNS_EPISODES]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS_EPISODES,
                            MENU_COLUMNS_EPISODES,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False)

        if hasattr(state, "podcast_url"):
            podcast_url = state.podcast_url
            self.title = self.podcasts_util.summary_cache[podcast_url].name
        else:
            self.title = state.name

        m = self.factory.create_episode_menu_button
        self.episodes_menu = MultiPageMenu(util,
                                           self.next_page,
                                           self.previous_page,
                                           self.set_title,
                                           self.reset_title,
                                           self.go_to_page,
                                           m,
                                           MENU_ROWS_EPISODES,
                                           MENU_COLUMNS_EPISODES,
                                           None, (0, 0, 0),
                                           self.menu_layout,
                                           align=ALIGN_MIDDLE)
        self.set_menu(self.episodes_menu)

        self.total_pages = PAGE_SIZE_EPISODES * 2
        self.episodes = []
        self.navigator = EpisodeNavigator(
            self.util, self.layout.BOTTOM, listeners,
            self.config[COLORS][COLOR_DARK_LIGHT], self.total_pages)
        self.components.append(self.navigator)
        self.current_page = 1

        self.save_episode_listeners = []

    def set_current(self, state):
        """ Set current state
        
        :param state: button state
        """
        if not self.util.connected_to_internet and len(
                self.episodes) == 0 and not hasattr(state, "url"):
            return

        if state.name == KEY_BACK or (getattr(state, "source",
                                              None) == FILE_BUTTON
                                      and len(self.episodes) != 0):
            self.episodes_menu.clean_draw_update()
            return

        if getattr(state, "podcast_url", None) != None:
            self.episodes = self.podcasts_util.get_episodes(state.podcast_url)
            if len(self.episodes) != 0:
                self.total_pages = math.ceil(
                    len(self.episodes) / PAGE_SIZE_EPISODES)
                self.turn_page(state)
                return

        self.set_loading(self.title)
        if state.name != self.title or len(self.episodes) == 0:
            self.title = state.name
            if self.util.connected_to_internet:
                self.episodes = self.podcasts_util.get_episodes(state.url)
            else:
                self.episodes = self.podcasts_util.get_episodes_from_disk(
                    state.url)

        self.total_pages = math.ceil(len(self.episodes) / PAGE_SIZE_EPISODES)

        self.turn_page(state)
        self.reset_loading()

    def turn_page(self, state=None):
        """ Turn screen page
        
        :param state: button state
        """
        filelist = Page(self.episodes, MENU_ROWS_EPISODES,
                        MENU_COLUMNS_EPISODES)

        if state == None:
            filelist.current_page_index = self.current_page - 1
            index = filelist.current_page_index * PAGE_SIZE_EPISODES
        else:
            if getattr(state, "status", None) == STATUS_LOADED:
                if hasattr(state, "original_url") and len(
                        state.original_url.strip()) > 0:
                    filelist.set_current_item_by_url(state.original_url)
                else:
                    filelist.set_current_item_by_file_name(state.file_name)
            else:
                filelist.set_current_item_by_url(state.url)
            index = filelist.current_item_index

        self.current_page = filelist.current_page_index + 1

        page = filelist.get_current_page()
        d = self.episodes_menu.make_dict(page)
        self.episodes_menu.set_items(d, filelist.current_page_index,
                                     self.select_episode, False)
        self.set_title(self.current_page)
        self.episodes_menu.unselect()
        self.episodes_menu.select_by_index(index)

        self.navigator.left_button.change_label(
            str(filelist.get_left_items_number()))
        self.navigator.right_button.change_label(
            str(filelist.get_right_items_number()))
        self.episodes_menu.clean_draw_update()

        if hasattr(self, "update_observer"):
            self.episodes_menu.add_menu_observers(self.update_observer,
                                                  self.redraw_observer)

    def select_episode(self, state):
        """ Select podacst episode
        
        :param state: button state
        """
        if getattr(state, "long_press", None) == True:
            if state.status == STATUS_LOADED:
                self.podcasts_util.delete_episode(state)
                if not self.util.connected_to_internet:
                    for i, c in enumerate(self.episodes):
                        if c.name == state.name:
                            del self.episodes[i]
                            break
                    if len(self.episodes) == 0:
                        self.title = " "
                        self.set_title(0)
                    self.turn_page(state)
                else:
                    state.icon_base = state.event_origin.components[
                        1].content = self.podcasts_util.available_icon
                    state.status = STATUS_AVAILABLE
            elif state.status == STATUS_AVAILABLE:
                if self.podcasts_util.is_podcast_folder_available():
                    state.icon_base = state.event_origin.components[
                        1].content = self.podcasts_util.loading_icon
                    state.status = STATUS_LOADING
                    self.add_save_episode_listener(state)
                    self.podcasts_util.save_episode(
                        state, self.notify_save_episode_listeners)
            self.clean_draw_update()
        else:
            podcast_player = self.listeners[KEY_PLAYER]
            podcast_player(state)

    def add_save_episode_listener(self, listener):
        """ Add save episode listener
        
        :param listener: event listener
        """
        if listener not in self.save_episode_listeners:
            self.save_episode_listeners.append(listener)

    def notify_save_episode_listeners(self):
        """ Notify all save episode listeners """

        for index, listener in enumerate(self.save_episode_listeners):
            listener.icon_base = listener.event_origin.components[
                1].content = self.podcasts_util.loaded_icon
            listener.status = STATUS_LOADED
            self.clean_draw_update()
            if hasattr(self, "redraw_observer"):
                self.redraw_observer()
            del self.save_episode_listeners[index]

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        MenuScreen.add_screen_observers(self, update_observer, redraw_observer)
        self.update_observer = update_observer
        self.redraw_observer = redraw_observer
        self.add_loading_listener(redraw_observer)
        self.navigator.add_observers(self.update_observer,
                                     self.redraw_observer)
Пример #16
0
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer

        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.listeners = listeners
        self.factory = Factory(util)
        self.go_home = listeners[KEY_HOME]
        self.go_network = listeners[KEY_NETWORK]
        self.go_player = listeners[KEY_PLAYER]

        self.wifi_selection_listeners = []

        self.bluetooth_util = self.util.get_bluetooth_util()
        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)

        d = [MENU_ROWS_BLUETOOTH, MENU_COLUMNS_BLUETOOTH]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS_BLUETOOTH,
                            MENU_COLUMNS_BLUETOOTH,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False,
                            show_loading=False)
        self.title = self.config[LABELS]["select.bluetooth.device"]
        self.set_title(1)

        m = self.factory.create_wifi_menu_button
        self.bluetooth_menu = MultiPageMenu(util,
                                            self.next_page,
                                            self.previous_page,
                                            self.set_title,
                                            self.reset_title,
                                            self.go_to_page,
                                            m,
                                            MENU_ROWS_BLUETOOTH,
                                            MENU_COLUMNS_BLUETOOTH,
                                            None, (0, 0, 0),
                                            self.menu_layout,
                                            align=ALIGN_LEFT)
        self.set_menu(self.bluetooth_menu)

        listeners[KEY_HOME] = self.before_home
        listeners[KEY_NETWORK] = self.before_network
        listeners[KEY_PLAYER] = self.before_player
        listeners[KEY_REFRESH] = self.set_current

        self.navigator = BluetoothNavigator(self.util, self.layout.BOTTOM,
                                            listeners, PAGE_SIZE_BLUETOOTH + 1)
        self.components.append(self.navigator)
        self.devices = None
        self.networks = None
        self.sort_direction = False
        self.current_device = None
Пример #17
0
class BluetoothScreen(MenuScreen):
    """ Bluetooth Screen """
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer

        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.listeners = listeners
        self.factory = Factory(util)
        self.go_home = listeners[KEY_HOME]
        self.go_network = listeners[KEY_NETWORK]
        self.go_player = listeners[KEY_PLAYER]

        self.wifi_selection_listeners = []

        self.bluetooth_util = self.util.get_bluetooth_util()
        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)

        d = [MENU_ROWS_BLUETOOTH, MENU_COLUMNS_BLUETOOTH]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS_BLUETOOTH,
                            MENU_COLUMNS_BLUETOOTH,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False,
                            show_loading=False)
        self.title = self.config[LABELS]["select.bluetooth.device"]
        self.set_title(1)

        m = self.factory.create_wifi_menu_button
        self.bluetooth_menu = MultiPageMenu(util,
                                            self.next_page,
                                            self.previous_page,
                                            self.set_title,
                                            self.reset_title,
                                            self.go_to_page,
                                            m,
                                            MENU_ROWS_BLUETOOTH,
                                            MENU_COLUMNS_BLUETOOTH,
                                            None, (0, 0, 0),
                                            self.menu_layout,
                                            align=ALIGN_LEFT)
        self.set_menu(self.bluetooth_menu)

        listeners[KEY_HOME] = self.before_home
        listeners[KEY_NETWORK] = self.before_network
        listeners[KEY_PLAYER] = self.before_player
        listeners[KEY_REFRESH] = self.set_current

        self.navigator = BluetoothNavigator(self.util, self.layout.BOTTOM,
                                            listeners, PAGE_SIZE_BLUETOOTH + 1)
        self.components.append(self.navigator)
        self.devices = None
        self.networks = None
        self.sort_direction = False
        self.current_device = None

    def set_current(self, state):
        """ Set current state

        :param state: button state
        """
        self.set_loading(self.title)
        self.bluetooth_util.start_scan()
        self.devices = self.bluetooth_util.get_available_devices()

        if not self.devices:
            self.reset_loading()
            self.clean_draw_update()
            return

        self.current_device = self.devices[0]
        d = self.bluetooth_util.get_connected_device()
        if d:
            self.current_device = d

        self.total_pages = math.ceil(len(self.devices) / PAGE_SIZE_BLUETOOTH)
        self.reset_loading()

        self.current_page = self.bluetooth_util.get_page_num(
            self.current_device, self.devices)
        self.turn_page()

    def select_network(self, state=None):
        """ Select network from menu

        :param state: button state
        """
        if hasattr(state,
                   "mac_address") and self.bluetooth_util.is_device_connected(
                       state.mac_address):
            self.before_network(state)
            return

        state.source = "bluetooth"
        self.notify_wifi_selection_listeners(state.name)
        self.before_network(state)

    def turn_page(self):
        """ Turn page """

        p = self.bluetooth_util.get_page(self.current_page, self.devices)
        try:
            self.bluetooth_menu.set_items(p, 0, self.select_network, False)
        except Exception as e:
            logging.debug(e)

        if len(self.devices) != 0 and self.navigator and self.total_pages > 1:
            self.navigator.left_button.change_label(str(self.current_page - 1))
            self.navigator.right_button.change_label(
                str(self.total_pages - self.current_page))

        self.set_title(self.current_page)
        self.bluetooth_menu.clean_draw_update()

        if hasattr(self, "update_observer"):
            self.bluetooth_menu.add_menu_observers(self.update_observer,
                                                   self.redraw_observer)

        self.bluetooth_menu.unselect()
        for b in self.bluetooth_menu.buttons.values():
            if self.current_device["name"] == b.state.name:
                self.bluetooth_menu.select_by_index(b.state.index)
                return
        index = (self.current_page - 1) * PAGE_SIZE_BLUETOOTH
        self.bluetooth_menu.select_by_index(index)

    def before_home(self, state):
        """ Stop bluetooth scanning and go to home screen

        :param state: button state
        """
        self.bluetooth_util.stop_scan()
        self.go_home(state)

    def before_network(self, state):
        """ Stop bluetooth scanning and go to network screen

        :param state: button state
        """
        self.bluetooth_util.stop_scan()
        self.go_network(state)

    def before_player(self, state):
        """ Stop bluetooth scanning and go to player screen

        :param state: button state
        """
        self.bluetooth_util.stop_scan()
        self.go_player(state)

    def add_bluetooth_selection_listener(self, listener):
        """ Add listener

        :param listener: event listener
        """
        if listener not in self.wifi_selection_listeners:
            self.wifi_selection_listeners.append(listener)

    def notify_wifi_selection_listeners(self, selected_wifi):
        """ Notify all listeners

        :param selected_wifi:
        """
        for listener in self.wifi_selection_listeners:
            listener(selected_wifi)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers

        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        MenuScreen.add_screen_observers(self, update_observer, redraw_observer)
        self.update_observer = update_observer
        self.redraw_observer = redraw_observer
        self.add_loading_listener(redraw_observer)
        for b in self.navigator.menu_buttons:
            self.add_button_observers(b, update_observer, redraw_observer)
Пример #18
0
class TopicDetailScreen(MenuScreen):
    """ Topic Detail Screen """
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer

        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.listeners = listeners
        self.factory = Factory(util)
        self.go_home = listeners[KEY_HOME]
        self.go_file_playback = listeners[KEY_PLAY_COLLECTION]

        dbutil = util.get_db_util()
        self.selector = Selector(dbutil)

        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)

        MenuScreen.__init__(self,
                            util,
                            listeners,
                            ROWS,
                            COLUMNS,
                            voice_assistant, [ROWS, COLUMNS],
                            self.turn_page,
                            page_in_title=False,
                            show_loading=False)

        m = self.factory.create_collection_menu_button
        self.collection_list_menu = MultiPageMenu(util,
                                                  self.next_page,
                                                  self.previous_page,
                                                  self.set_title,
                                                  self.reset_title,
                                                  self.go_to_page,
                                                  m,
                                                  ROWS,
                                                  COLUMNS,
                                                  None, (0, 0, 0),
                                                  self.menu_layout,
                                                  align=ALIGN_LEFT)
        self.set_menu(self.collection_list_menu)

        self.navigator = TopicDetailNavigator(self.util, self.layout.BOTTOM,
                                              listeners)
        self.components.append(self.navigator)
        self.current_item = None
        self.current_page_items = None
        self.first_item = None
        self.last_item = None
        self.collection_topic = None
        self.selection = None
        self.prev_page = 1
        self.animated_title = True

    def set_current(self, state):
        """ Set current state

        :param state: button state
        """
        source = getattr(state, KEY_SOURCE, None)

        if source == KEY_NAVIGATOR or source == KEY_BACK:
            return

        if hasattr(state, "collection_topic"):
            self.collection_topic = getattr(state, "collection_topic", "")

        if self.current_item and self.current_item[0] == getattr(
                state, "name", None):
            return

        if hasattr(state, "name"):
            self.selection = getattr(state, "name", "")

        self.title = self.config[LABELS][
            self.collection_topic] + ": " + self.selection
        self.set_title(1)

        self.current_page = 1
        self.prev_page = 1
        self.navigator.left_button.change_label("0")
        self.navigator.right_button.change_label("0")

        self.set_loading(self.title)

        topic = self.get_topic()

        self.total_pages = self.selector.get_page_count_by_column(
            topic, self.selection, PAGE_SIZE)

        if self.total_pages == 0:
            self.reset_loading()
            return

        self.filename = None
        self.title = None

        if self.collection_topic == KEY_FILE:
            self.filename = state.name
        elif self.collection_topic == TITLE:
            self.title = state.name

        self.turn_page()
        self.reset_loading()

    def turn_page(self):
        """ Turn page """

        topic = self.get_topic()

        self.current_page_items = self.selector.get_topic_detail_page(
            topic, self.selection, self.current_page, self.prev_page,
            self.first_item, self.last_item, PAGE_SIZE)
        self.prev_page = self.current_page

        if not self.current_page_items:
            self.current_page_items = []
            return

        self.current_item = self.current_page_items[0]
        self.first_item = self.current_item
        self.last_item = self.current_page_items[len(self.current_page_items) -
                                                 1]

        p = {}
        for i, f in enumerate(self.current_page_items):
            s = State()
            s.index = i
            s.folder = f
            if "\x00" in f:
                f = f.replace("\x00", "")
            if "/" in f:
                parts = f.split("/")
                if len(parts) > 1:
                    last = parts[len(parts) - 1]
                    if len(last) > 6:
                        f = last
                    else:
                        f = parts[len(parts) - 2] + "/" + last
            s.name = f
            s.l_name = s.name
            if self.filename:
                s.file_name = self.filename
            if self.title:
                s.title = self.title
            p[str(i)] = s

        self.collection_list_menu.set_items(p, 0, self.select_item, False)

        keys = list(p.keys())

        if len(keys) != 0 and self.navigator and self.total_pages > 1:
            self.navigator.left_button.change_label(str(self.current_page - 1))
            self.navigator.right_button.change_label(
                str(self.total_pages - self.current_page))

        self.collection_list_menu.clean_draw_update()

        if hasattr(self, "update_observer"):
            self.collection_list_menu.add_menu_observers(
                self.update_observer, self.redraw_observer)

        self.collection_list_menu.unselect()
        for i, b in enumerate(self.collection_list_menu.buttons.values()):
            if self.current_item[0] == b.state.name:
                self.collection_list_menu.select_by_index(b.state.index)
                return
        index = (self.current_page - 1) * PAGE_SIZE
        self.collection_list_menu.select_by_index(index)

    def get_topic(self):
        """ Get topic

        :return: proper topic name
        """
        topic = self.collection_topic
        if topic == KEY_AUDIO_FOLDER:
            topic = FOLDER
        elif topic == KEY_FILE:
            topic = FILENAME

        return topic

    def select_item(self, s=None):
        """ Select item from menu

        :param state: button state
        """
        self.current_item = s.name
        state = State()
        state.folder = os.path.join(self.config[COLLECTION][BASE_FOLDER],
                                    s.folder[1:])
        state.topic = self.collection_topic

        if state.topic == KEY_FILE:
            state.file_name = s.file_name
        elif state.topic == TITLE:
            state.file_name = self.selector.get_filename_by_title(
                s.folder, self.title)
            state.url = os.path.join(state.folder, state.file_name)
        else:
            files = self.util.get_audio_files_in_folder(state.folder, False)
            if files:
                f = files[0]
                state.file_name = f.file_name
                state.url = os.path.join(state.folder, state.file_name)
            else:
                state.file_name = None
                state.url = None

        state.source = "detail"
        self.collection_list_menu.select_by_index(s.index)
        self.go_file_playback(state)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers

        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        MenuScreen.add_screen_observers(self, update_observer, redraw_observer)
        self.update_observer = update_observer
        self.redraw_observer = redraw_observer
        self.add_loading_listener(redraw_observer)
        for b in self.navigator.menu_buttons:
            self.add_button_observers(b, update_observer, redraw_observer)
Пример #19
0
class PodcastsScreen(MenuScreen):
    """ Podcasts Screen """
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer
        
        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.listeners = listeners
        self.factory = Factory(util)

        self.podcasts_util = util.get_podcasts_util()
        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)

        d = [MENU_ROWS_PODCASTS, MENU_COLUMNS_PODCASTS]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS_PODCASTS,
                            MENU_COLUMNS_PODCASTS,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False,
                            show_loading=True)
        self.title = self.config[LABELS][PODCASTS]

        m = self.create_podcast_menu_button
        font_size = int(
            ((self.menu_layout.h / MENU_ROWS_PODCASTS) / 100) * FONT_HEIGHT)
        self.podcasts_menu = MultiPageMenu(util,
                                           self.next_page,
                                           self.previous_page,
                                           self.set_title,
                                           self.reset_title,
                                           self.go_to_page,
                                           m,
                                           MENU_ROWS_PODCASTS,
                                           MENU_COLUMNS_PODCASTS,
                                           None, (0, 0, 0, 0),
                                           self.menu_layout,
                                           align=ALIGN_CENTER,
                                           font_size=font_size)
        self.set_menu(self.podcasts_menu)

        self.navigator = PodcastNavigator(self.util, self.layout.BOTTOM,
                                          listeners, PAGE_SIZE_PODCASTS + 1)
        self.add_component(self.navigator)

        url = self.config[PODCASTS][PODCAST_URL]
        if url and len(url) > 0:
            self.current_page = self.podcasts_util.get_podcast_page(
                url, PAGE_SIZE_PODCASTS)
        else:
            self.current_page = 1

        self.animated_title = True

    def create_podcast_menu_button(self, s, constr, action, scale, font_size):
        """ Create podcast menu button

        :param s: button state
        :param constr: scaling constraints
        :param action: button event listener
        :param scale: True - scale images, False - don't scale images

        :return: genre menu button
        """
        s.bounding_box = constr
        s.img_x = None
        s.img_y = None
        s.auto_update = True
        s.show_bgr = True
        s.show_img = True
        s.show_label = True
        s.image_location = ICON_LOCATION
        s.label_location = CENTER
        s.label_area_percent = 30
        s.image_size_percent = ICON_SIZE
        s.text_color_normal = self.config[COLORS][COLOR_BRIGHT]
        s.text_color_selected = self.config[COLORS][COLOR_CONTRAST]
        s.text_color_disabled = self.config[COLORS][COLOR_MEDIUM]
        s.text_color_current = s.text_color_normal
        s.scale = scale
        s.source = None
        s.v_align = V_ALIGN_TOP
        s.h_align = H_ALIGN_LEFT
        s.v_offset = (constr.h / 100) * 5
        s.bgr = self.config[BACKGROUND][MENU_BGR_COLOR]
        s.image_area_percent = ICON_AREA
        s.fixed_height = font_size

        button = PodcastButton(self.util, s)
        button.add_release_listener(action)
        if not getattr(s, "enabled", True):
            button.set_enabled(False)
        elif getattr(s, "icon_base",
                     False) and not getattr(s, "scaled", False):
            button.components[1].content = s.icon_base
        button.scaled = scale
        return button

    def set_current(self, state):
        """ Set current state
        
        :param state: button state
        """
        if self.util.connected_to_internet:
            podcast_links_num = len(self.podcasts_util.get_podcasts_links())
        else:
            podcast_links_num = len(self.podcasts_util.load_podcasts())

        self.total_pages = math.ceil(podcast_links_num / PAGE_SIZE_PODCASTS)

        self.set_loading(self.title)
        self.turn_page()
        self.reset_loading()

    def turn_page(self):
        """ Turn podcasts page """

        page = {}
        if self.util.connected_to_internet:
            page = self.podcasts_util.get_podcasts(self.current_page,
                                                   PAGE_SIZE_PODCASTS)

        if len(list(page.keys())) == 0 or not self.util.connected_to_internet:
            page = self.podcasts_util.get_podcasts_from_disk(
                self.current_page, PAGE_SIZE_PODCASTS)

        self.podcasts_menu.set_items(page, 0,
                                     self.listeners[KEY_PODCAST_EPISODES],
                                     False)

        keys = list(page.keys())

        if len(keys) != 0:
            self.podcasts_menu.item_selected(page[keys[0]])
            if self.navigator and self.total_pages > 1:
                self.navigator.left_button.change_label(
                    str(self.current_page - 1))
                self.navigator.right_button.change_label(
                    str(self.total_pages - self.current_page))

        self.set_title(self.current_page)
        self.podcasts_menu.clean_draw_update()

        if hasattr(self, "update_observer"):
            self.podcasts_menu.add_menu_observers(self.update_observer,
                                                  self.redraw_observer)

        self.podcasts_menu.unselect()
        for i, b in enumerate(self.podcasts_menu.buttons.values()):
            url = self.config[PODCASTS][PODCAST_URL]
            if url == b.state.url:
                self.podcasts_menu.select_by_index(i)
                return
        self.podcasts_menu.select_by_index(0)
        self.podcasts_menu.set_parent_screen(self)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        MenuScreen.add_screen_observers(self, update_observer, redraw_observer)
        self.update_observer = update_observer
        self.redraw_observer = redraw_observer
        self.add_loading_listener(redraw_observer)
        for b in self.navigator.menu_buttons:
            self.add_button_observers(b, update_observer, redraw_observer)
Пример #20
0
class RadioGroupScreen(MenuScreen):
    """ Radio group screen """
    def __init__(self, util, listeners, voice_assistant):
        self.util = util
        self.config = util.config
        self.groups_list = self.util.get_stations_folders()
        self.factory = Factory(util)
        d = [MENU_ROWS, MENU_COLUMNS]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS,
                            MENU_COLUMNS,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False)
        self.total_pages = math.ceil(len(self.groups_list) / PAGE_SIZE)
        self.title = util.get_stations_top_folder()
        m = self.factory.create_genre_menu_button

        self.groups_menu = MultiPageMenu(util,
                                         self.next_page,
                                         self.previous_page,
                                         self.set_title,
                                         self.reset_title,
                                         self.go_to_page,
                                         m,
                                         MENU_ROWS,
                                         MENU_COLUMNS,
                                         None, (0, 0, 0),
                                         self.menu_layout,
                                         align=ALIGN_CENTER)
        self.groups_menu.add_listener(listeners[KEY_GENRE])
        self.set_menu(self.groups_menu)

        color_dark_light = self.config[COLORS][COLOR_DARK_LIGHT]
        self.navigator = RadioGroupNavigator(self.util, self.layout.BOTTOM,
                                             listeners, color_dark_light,
                                             self.total_pages)
        self.components.append(self.navigator)

        current_name = self.get_current_group_name()

        if current_name == None:
            self.current_page = 1
        else:
            try:
                current_group_index = self.groups_list.index(current_name)
                self.current_page = int(current_group_index / PAGE_SIZE) + 1
            except:
                current_group_index = 0

        self.turn_page()

    def get_current_group_name(self):
        key = STATIONS + "." + self.config[CURRENT][LANGUAGE]
        name = None
        try:
            name = self.config[key][CURRENT_STATIONS]
        except:
            pass
        return name

    def get_page(self):
        start = (self.current_page - 1) * PAGE_SIZE
        end = self.current_page * PAGE_SIZE
        page = self.groups_list[start:end]
        tmp_layout = self.groups_menu.get_layout(self.groups_list)
        button_rect = tmp_layout.constraints[0]
        groups_dict = self.util.load_stations_folders(button_rect)

        return self.util.get_radio_group_slice(groups_dict, start, end)

    def turn_page(self):
        """ Turn book genre page """

        group_page = self.get_page()
        self.groups_menu.set_items(group_page, 0, self.change_group, False)
        current_name = self.get_current_group_name()

        try:
            self.current_genre = group_page[current_name]
            self.groups_menu.item_selected(self.current_genre)
        except:
            keys = list(group_page.keys())
            self.groups_menu.item_selected(group_page[keys[0]])

        if self.navigator and self.total_pages > 1:
            self.navigator.left_button.change_label(str(self.current_page - 1))
            self.navigator.right_button.change_label(
                str(self.total_pages - self.current_page))

        self.set_title(self.current_page)
        self.groups_menu.clean_draw_update()

    def change_group(self, state):
        """ Change group event listener
         
        :param state: button state
        """
        if not self.visible:
            return
        self.current_genre = state

        key = STATIONS + "." + self.config[CURRENT][LANGUAGE]
        self.config[key][CURRENT_STATIONS] = state.genre
        state.source = GENRE
        self.groups_menu.notify_listeners(state)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        self.navigator.add_observers(update_observer, redraw_observer)
        self.groups_menu.add_menu_observers(update_observer,
                                            redraw_observer,
                                            release=False)
Пример #21
0
class WiFiScreen(MenuScreen):
    """ Wi-Fi Screen """
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer

        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.listeners = listeners
        self.factory = Factory(util)
        self.go_home = listeners[KEY_HOME]
        self.go_keyboard = listeners[KEY_KEYBOARD_KEY]
        self.keyboard_callback = listeners[KEY_CALLBACK]

        self.wifi_selection_listeners = []

        self.wifi_util = WiFiUtil(util)
        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)

        d = [MENU_ROWS_WIFI, MENU_COLUMNS_WIFI]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS_WIFI,
                            MENU_COLUMNS_WIFI,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False,
                            show_loading=False)
        self.title = self.config[LABELS]["select.wifi"]
        self.set_title(1)

        m = self.factory.create_wifi_menu_button
        self.wifi_menu = MultiPageMenu(util,
                                       self.next_page,
                                       self.previous_page,
                                       self.set_title,
                                       self.reset_title,
                                       self.go_to_page,
                                       m,
                                       MENU_ROWS_WIFI,
                                       MENU_COLUMNS_WIFI,
                                       None, (0, 0, 0),
                                       self.menu_layout,
                                       align=ALIGN_CENTER)
        self.set_menu(self.wifi_menu)

        listeners[KEY_REFRESH] = self.set_current
        listeners[KEY_SORT] = self.sort_abc
        self.navigator = WiFiNavigator(self.util, self.layout.BOTTOM,
                                       listeners, PAGE_SIZE_WIFI + 1)
        self.components.append(self.navigator)
        self.original_networks = None
        self.networks = None
        self.sort_direction = False
        self.current_network = None

    def set_current(self, state):
        """ Set current state

        :param state: button state
        """
        self.set_loading(self.title)
        info = self.wifi_util.get_wifi_networks()

        self.original_networks = info["networks"]

        if not self.original_networks:
            self.reset_loading()
            return

        self.networks = self.sort_networks(SORT_ALPHABETICALLY)
        self.current_network = info["profile"]
        self.total_pages = math.ceil(len(self.networks) / PAGE_SIZE_WIFI)
        self.reset_loading()

        self.current_page = self.wifi_util.get_page_num(
            self.current_network, self.networks)
        self.turn_page()

    def sort_networks(self, order):
        """ Sort networks

        :param order: sort order
        :return: sorted networks
        """
        sorted_networks = []

        if order == SORT_ALPHABETICALLY:
            sorted_networks = sorted(self.original_networks,
                                     key=lambda i: i["name"],
                                     reverse=self.sort_direction)
        else:
            sorted_networks = sorted(self.original_networks,
                                     key=lambda i: i["strength"],
                                     reverse=self.sort_direction)

        states = {}
        h = self.layout.CENTER.h / MENU_ROWS_WIFI
        bb = pygame.Rect(0, 0, h, h)
        for i, n in enumerate(sorted_networks):
            s = self.wifi_util.get_network_info(i, n["name"], n["strength"],
                                                bb)
            states[s.name] = s

        return states

    def sort_abc(self, state):
        """ Sort in alphabetical order

        :param state: button state
        """
        self.sort(SORT_ALPHABETICALLY)

    def select_network(self, state=None):
        """ Select network from menu

        :param state: button state
        """
        self.current_network = state.name
        self.notify_wifi_selection_listeners(self.current_network)
        state.title = self.config[LABELS]["enter.password"]
        state.callback = self.keyboard_callback
        self.go_keyboard(state)

    def sort(self, order):
        """ Sort by order

        :param order: sort order
        :return:
        """
        self.sort_direction = not self.sort_direction
        self.current_page = 1
        self.networks = self.sort_networks(order)
        self.turn_page()

    def turn_page(self):
        """ Turn page """

        p = self.wifi_util.get_network_page(self.current_page, self.networks)
        self.wifi_menu.set_items(p, 0, self.select_network, False)

        keys = list(p.keys())

        if len(keys) != 0 and self.navigator and self.total_pages > 1:
            self.navigator.left_button.change_label(str(self.current_page - 1))
            self.navigator.right_button.change_label(
                str(self.total_pages - self.current_page))

        self.set_title(self.current_page)
        self.wifi_menu.clean_draw_update()

        if hasattr(self, "update_observer"):
            self.wifi_menu.add_menu_observers(self.update_observer,
                                              self.redraw_observer)

        self.wifi_menu.unselect()
        for i, b in enumerate(self.wifi_menu.buttons.values()):
            if self.current_network == b.state.name:
                self.wifi_menu.select_by_index(b.state.index)
                return
        index = (self.current_page - 1) * PAGE_SIZE_WIFI
        self.wifi_menu.select_by_index(index)

    def add_wifi_selection_listener(self, listener):
        """ Add listener

        :param listener: event listener
        """
        if listener not in self.wifi_selection_listeners:
            self.wifi_selection_listeners.append(listener)

    def notify_wifi_selection_listeners(self, selected_wifi):
        """ Notify all listeners

        :param selected_wifi:
        """
        for listener in self.wifi_selection_listeners:
            listener(selected_wifi)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers

        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        MenuScreen.add_screen_observers(self, update_observer, redraw_observer)
        self.update_observer = update_observer
        self.redraw_observer = redraw_observer
        self.add_loading_listener(redraw_observer)
        for b in self.navigator.menu_buttons:
            self.add_button_observers(b, update_observer, redraw_observer)
Пример #22
0
class TopicScreen(MenuScreen):
    """ Collection Topic Screen """
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer

        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.listeners = listeners
        self.listeners[KEY_LIST] = self.set_list
        self.factory = Factory(util)
        dbutil = util.get_db_util()
        self.selector = Selector(dbutil)

        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)

        MenuScreen.__init__(self,
                            util,
                            listeners,
                            ROWS,
                            COLUMNS,
                            voice_assistant, [ROWS, COLUMNS],
                            self.turn_page,
                            page_in_title=False,
                            show_loading=False)

        m = self.factory.create_collection_menu_button
        self.topic_menu = MultiPageMenu(util,
                                        self.next_page,
                                        self.previous_page,
                                        self.set_title,
                                        self.reset_title,
                                        self.go_to_page,
                                        m,
                                        ROWS,
                                        COLUMNS,
                                        None, (0, 0, 0),
                                        self.menu_layout,
                                        align=ALIGN_LEFT)
        self.set_menu(self.topic_menu)

        self.navigator = TopicNavigator(self.util, self.layout.BOTTOM,
                                        listeners)
        self.components.append(self.navigator)

        self.current_topic = None
        self.current_item = None
        self.current_page_items = None
        self.first_item = None
        self.last_item = None
        self.collection_topic = None
        self.previous_page = 1
        self.search_string = None
        self.source = None
        self.mode = KEY_LIST
        self.animated_title = True

    def set_current(self, state):
        """ Set current state

        :param state: button state
        """
        self.source = getattr(state, KEY_SOURCE, None)
        if self.source:
            if self.source == KEY_ABC:
                self.mode = KEY_ABC
            elif self.source == KEY_SEARCH:
                self.mode = KEY_SEARCH
            elif self.source == KEY_LIST:
                self.mode = KEY_LIST

        self.topic_menu.select_by_index(self.topic_menu.selected_index)

        if self.current_topic and (self.source == KEY_NAVIGATOR or self.source
                                   == KEY_BACK or self.source == None):
            return

        if self.source == KEY_MENU:
            self.config[COLLECTION_PLAYBACK][COLLECTION_TOPIC] = state.name
            self.mode = KEY_LIST

        if hasattr(state, "genre"):
            if self.current_topic == state.genre:
                return
            else:
                self.current_topic = state.genre

        name = self.config[COLLECTION_PLAYBACK][COLLECTION_TOPIC]
        if self.source:
            if self.source == KEY_ABC:
                name = getattr(state, KEY_NAME, None)
            elif self.source == KEY_SEARCH:
                name = getattr(state, KEY_CALLBACK_VAR, None)

        if not self.source or not name:
            return

        if self.source != KEY_ABC and self.source != KEY_SEARCH:
            self.collection_topic = name
            self.search_string == None
        else:
            self.search_string = name

        self.navigator.set_buttons(self.collection_topic)
        self.navigator.left_button.change_label("0")
        self.navigator.right_button.change_label("0")
        self.current_page_items = None
        self.first_item = ""
        self.last_item = ""
        self.current_page = 1
        self.previous_page = 1

        if not self.current_topic:
            return

        self.title = self.get_title(name)
        self.set_title(1)
        self.set_loading(self.title)
        self.total_pages = self.get_total_pages(name)
        self.turn_page()
        self.reset_loading()

    def set_list(self, state=None):
        """ Set list view """

        s = State()
        s.source = KEY_LIST
        s.name = self.collection_topic
        self.set_current(s)

    def get_title(self, search_string):
        """ Return title based on call source. The source can be:
        - Collection screen
        - ABC keyboard
        - Keyboard Search screen

        :param search_string: search string from keyboard

        :return: title which depends on call source
        """
        title = None
        try:
            title = self.config[LABELS][self.collection_topic]
        except:
            pass

        if self.source == KEY_ABC:
            title = f"{title}. {search_string.strip()}"
        elif self.source == KEY_SEARCH:
            title = f"{title}. *{search_string.strip()}*"

        return title

    def get_total_pages(self, search_string):
        """ Return the number of total pages for defined search criteria

        :param search_string: search string from keyboard

        :return: total pages number
        """
        mode = self.collection_topic
        if mode == KEY_AUDIO_FOLDER:
            mode = FOLDER
        elif mode == KEY_FILE:
            mode = FILENAME

        total_pages = 0

        if self.source == KEY_ABC:
            total_pages = self.selector.get_page_count_by_char(
                mode, search_string.strip(), PAGE_SIZE)
        elif self.source == KEY_SEARCH:
            total_pages = self.selector.get_page_count_by_pattern(
                mode, search_string.strip(), PAGE_SIZE)
        else:
            total_pages = self.selector.get_page_count(mode, PAGE_SIZE)

        return total_pages

    def turn_page(self):
        """ Turn page """

        if self.total_pages == 0:
            self.topic_menu.set_items({}, 0, self.select_item, False)
            return

        p = self.prepare_page()
        self.topic_menu.set_items(p, 0, self.select_item, False)
        keys = list(p.keys())

        if len(keys) != 0 and self.navigator and self.total_pages > 1:
            self.navigator.left_button.change_label(str(self.current_page - 1))
            self.navigator.right_button.change_label(
                str(self.total_pages - self.current_page))

        self.topic_menu.clean_draw_update()

        if hasattr(self, "update_observer"):
            self.topic_menu.add_menu_observers(self.update_observer,
                                               self.redraw_observer)

        self.topic_menu.unselect()
        for b in self.topic_menu.buttons.values():
            if self.current_item == b.state.name:
                self.topic_menu.select_by_index(b.state.index)
                return
        index = (self.current_page - 1) * PAGE_SIZE
        self.topic_menu.select_by_index(index)

    def prepare_page(self):
        """ Prepare topic page

        :return: page dictionary
        """
        page, self.first_item, self.last_item, self.current_item = self.get_current_page(
        )
        p = {}
        for i, n in enumerate(page):
            s = State()
            s.index = i
            if "\x00" in n:
                n = n.replace("\x00", "")
            s.name = n
            s.l_name = n
            p[str(i)] = s
        return p

    def get_current_page(self):
        """ Get current page content 
        
        :return: page content
        """
        topic = self.collection_topic
        if topic == KEY_AUDIO_FOLDER:
            topic = FOLDER
        elif topic == KEY_FILE:
            topic = FILENAME

        page_items = self.selector.get_topic_page(
            self.mode, topic, self.search_string, self.current_page,
            self.previous_page, self.first_item, self.last_item, PAGE_SIZE)

        self.previous_page = self.current_page

        if not page_items:
            page_items = []
            current_item = None
            first_item = None
            last_item = None
        else:
            current_item = page_items[0]
            first_item = current_item
            last_item = page_items[len(page_items) - 1]

        return (page_items, first_item, last_item, current_item)

    def select_item(self, s=None):
        """ Select item from menu

        :param s: button state
        """
        if not s: return

        s.collection_topic = self.collection_topic
        self.topic_menu.selected_index = s.index

        if self.collection_topic == KEY_AUDIO_FOLDER:
            s.folder = os.path.join(self.config[COLLECTION][BASE_FOLDER],
                                    s.name[1:])
            s.source = KEY_MENU
            files = self.util.get_audio_files_in_folder(s.folder, False)
            if files:
                f = files[0]
                s.file_name = f.file_name
                s.url = os.path.join(s.folder, s.file_name)
            else:
                s.file_name = None
                s.url = None

        self.listeners[TOPIC_DETAIL](s)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers

        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        MenuScreen.add_screen_observers(self, update_observer, redraw_observer)
        self.update_observer = update_observer
        self.redraw_observer = redraw_observer
        self.add_loading_listener(redraw_observer)
        self.topic_menu.add_menu_observers(update_observer, redraw_observer)
        self.navigator.add_observers(update_observer, redraw_observer)
Пример #23
0
class PodcastsScreen(MenuScreen):
    """ Podcasts Screen """
    def __init__(self, util, listeners, voice_assistant):
        """ Initializer
        
        :param util: utility object
        :param listeners: listeners
        :param voice_assistant: voice assistant
        """
        self.util = util
        self.config = util.config
        self.listeners = listeners
        self.factory = Factory(util)

        self.podcasts_util = util.get_podcasts_util()
        self.bounding_box = util.screen_rect
        layout = BorderLayout(self.bounding_box)
        layout.set_percent_constraints(PERCENT_TOP_HEIGHT,
                                       PERCENT_BOTTOM_HEIGHT, 0, 0)

        d = [MENU_ROWS_PODCASTS, MENU_COLUMNS_PODCASTS]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS_PODCASTS,
                            MENU_COLUMNS_PODCASTS,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False,
                            show_loading=True)
        self.title = self.config[LABELS][PODCASTS]

        m = self.factory.create_podcast_menu_button
        self.podcasts_menu = MultiPageMenu(util,
                                           self.next_page,
                                           self.previous_page,
                                           self.set_title,
                                           self.reset_title,
                                           self.go_to_page,
                                           m,
                                           MENU_ROWS_PODCASTS,
                                           MENU_COLUMNS_PODCASTS,
                                           None, (0, 0, 0),
                                           self.menu_layout,
                                           align=ALIGN_CENTER)
        self.set_menu(self.podcasts_menu)

        self.navigator = PodcastNavigator(
            self.util, self.layout.BOTTOM, listeners,
            self.config[COLORS][COLOR_DARK_LIGHT], PAGE_SIZE_PODCASTS + 1)
        self.components.append(self.navigator)

        url = self.config[PODCASTS][PODCAST_URL]
        if url and len(url) > 0:
            self.current_page = self.podcasts_util.get_podcast_page(
                url, PAGE_SIZE_PODCASTS)
        else:
            self.current_page = 1

        self.animated_title = True

    def set_current(self, state):
        """ Set current state
        
        :param state: button state
        """
        if self.util.connected_to_internet:
            podcast_links_num = len(self.podcasts_util.get_podcasts_links())
        else:
            podcast_links_num = len(self.podcasts_util.load_podcasts())

        self.total_pages = math.ceil(podcast_links_num / PAGE_SIZE_PODCASTS)

        self.set_loading(self.title)
        self.turn_page()
        self.reset_loading()

    def turn_page(self):
        """ Turn podcasts page """

        page = {}
        if self.util.connected_to_internet:
            page = self.podcasts_util.get_podcasts(self.current_page,
                                                   PAGE_SIZE_PODCASTS)

        if len(list(page.keys())) == 0 or not self.util.connected_to_internet:
            page = self.podcasts_util.get_podcasts_from_disk(
                self.current_page, PAGE_SIZE_PODCASTS)

        self.podcasts_menu.set_items(page, 0,
                                     self.listeners[KEY_PODCAST_EPISODES],
                                     False)

        keys = list(page.keys())

        if len(keys) != 0:
            self.podcasts_menu.item_selected(page[keys[0]])
            if self.navigator and self.total_pages > 1:
                self.navigator.left_button.change_label(
                    str(self.current_page - 1))
                self.navigator.right_button.change_label(
                    str(self.total_pages - self.current_page))

        self.set_title(self.current_page)
        self.podcasts_menu.clean_draw_update()

        if hasattr(self, "update_observer"):
            self.podcasts_menu.add_menu_observers(self.update_observer,
                                                  self.redraw_observer)

        self.podcasts_menu.unselect()
        for i, b in enumerate(self.podcasts_menu.buttons.values()):
            url = self.config[PODCASTS][PODCAST_URL]
            if url == b.state.url:
                self.podcasts_menu.select_by_index(i)
                return
        self.podcasts_menu.select_by_index(0)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        MenuScreen.add_screen_observers(self, update_observer, redraw_observer)
        self.update_observer = update_observer
        self.redraw_observer = redraw_observer
        self.add_loading_listener(redraw_observer)
        for b in self.navigator.menu_buttons:
            self.add_button_observers(b, update_observer, redraw_observer)
Пример #24
0
class PodcastEpisodesScreen(MenuScreen):
    """ Podcast Episodes Screen """
    
    def __init__(self, util, listeners, voice_assistant, state):
        """ Initializer
        
        :param util: utility object
        :param listeners: file browser listeners
        :param voice_assistant: voice assistant
        :param state: button state
        """
        self.util = util
        self.config = util.config
        self.podcasts_util = util.get_podcasts_util()
        self.listeners = listeners
        self.factory = Factory(util)
        self.bounding_box = util.screen_rect
        self.layout = BorderLayout(self.bounding_box)
        self.layout.set_percent_constraints(PERCENT_TOP_HEIGHT, PERCENT_BOTTOM_HEIGHT, 0, 0)

        d = [MENU_ROWS_EPISODES, MENU_COLUMNS_EPISODES]
        MenuScreen.__init__(self, util, listeners, MENU_ROWS_EPISODES, MENU_COLUMNS_EPISODES, voice_assistant, d, self.turn_page, page_in_title=False)
        
        if hasattr(state, "podcast_url"):            
            podcast_url = state.podcast_url
            self.title = self.podcasts_util.summary_cache[podcast_url].name
        else:
            self.title = state.name
        
        self.total_pages = PAGE_SIZE_EPISODES * 2
        self.episodes = []
        self.navigator = EpisodeNavigator(self.util, self.layout.BOTTOM, listeners, self.total_pages)
        self.add_navigator(self.navigator)        
        self.current_page = 1
        self.current_item = None

        m = self.create_episode_menu_button
        font_size = int(((self.menu_layout.h / MENU_ROWS_EPISODES) / 100) * FONT_HEIGHT)
        self.episodes_menu = MultiPageMenu(util, self.next_page, self.previous_page, self.set_title, self.reset_title, 
            self.go_to_page, m, MENU_ROWS_EPISODES, MENU_COLUMNS_EPISODES, None, (0, 0, 0, 0), self.menu_layout, align=ALIGN_CENTER, font_size=font_size)
        self.set_menu(self.episodes_menu)
        
        self.save_episode_listeners = []
        self.animated_title = True
    
    def create_episode_menu_button(self, s, constr, action, scale, font_size):
        """ Create podcast episode menu button

        :param s: button state
        :param constr: scaling constraints
        :param action: button event listener
        :param scale: True - scale images, False - don't scale images
        :param font_size: label font height in pixels

        :return: genre menu button
        """
        s.bounding_box = constr
        s.img_x = None
        s.img_y = None
        s.auto_update = True
        s.show_bgr = True
        s.show_img = True
        s.show_label = True
        s.image_location = LEFT
        s.label_location = CENTER
        s.label_area_percent = 30
        s.image_size_percent = 0.12
        s.text_color_normal = self.config[COLORS][COLOR_BRIGHT]
        s.text_color_selected = self.config[COLORS][COLOR_CONTRAST]
        s.text_color_disabled = self.config[COLORS][COLOR_MEDIUM]
        s.text_color_current = s.text_color_normal
        s.scale = scale
        s.source = "episode_menu"
        s.v_align = V_ALIGN_TOP
        s.h_align = H_ALIGN_LEFT
        s.v_offset = (constr.h/100) * 5
        s.bgr = self.config[BACKGROUND][MENU_BGR_COLOR]
        s.image_area_percent = ICON_AREA
        s.fixed_height = font_size

        button = EpisodeButton(self.util, s)
        button.add_release_listener(action)
        if not getattr(s, "enabled", True):
            button.set_enabled(False)
        elif getattr(s, "icon_base", False) and not getattr(s, "scaled", False):
            button.components[1].content = s.icon_base
        button.scaled = scale
        return button

    def set_current(self, state):
        """ Set current state
        
        :param state: button state
        """
        if not self.util.connected_to_internet and len(self.episodes) == 0 and not hasattr(state, "url"):
            return
            
        if state.name == KEY_BACK or (getattr(state, "source", None) == FILE_BUTTON and len(self.episodes) != 0):
            self.episodes_menu.clean_draw_update()
            return
        
        if getattr(state, "podcast_url", None) != None:
            self.episodes = self.podcasts_util.get_episodes(state.podcast_url)
            if len(self.episodes) != 0:
                self.total_pages = math.ceil(len(self.episodes) / PAGE_SIZE_EPISODES)
                self.turn_page(state)
                return

        self.set_loading(self.title)
        if state.name != self.title or len(self.episodes) == 0:
            self.title = state.name
            if self.util.connected_to_internet:
                self.episodes = self.podcasts_util.get_episodes(state.url)
            else:
                self.episodes = self.podcasts_util.get_episodes_from_disk(state.url)
                
        self.total_pages = math.ceil(len(self.episodes) / PAGE_SIZE_EPISODES)
                            
        self.turn_page(state)
        self.reset_loading()
    
    def turn_page(self, state=None):
        """ Turn screen page
        
        :param state: button state
        """
        filelist = Page(self.episodes, MENU_ROWS_EPISODES, MENU_COLUMNS_EPISODES)
        
        if state == None:
            pass
            filelist.current_page_index = self.current_page - 1
            index = -1
        else:            
            if getattr(state, "status", None) == STATUS_LOADED:
                if hasattr(state, "original_url") and len(state.original_url.strip()) > 0:
                    filelist.set_current_item_by_url(state.original_url)
                else:
                    filelist.set_current_item_by_file_name(state.file_name)
            else:
                filelist.set_current_item_by_url(state.url)
            
            index = filelist.current_item_index            

        self.current_item = self.config[PODCASTS][PODCAST_EPISODE_NAME]        
        self.current_page = filelist.current_page_index + 1
        
        page = filelist.get_current_page()
        d = self.episodes_menu.make_dict(page)
        self.episodes_menu.set_items(d, filelist.current_page_index, self.select_episode, False)
        self.set_title(self.current_page)
        self.episodes_menu.unselect()
        self.episodes_menu.select_by_index(index)
        
        for b in self.episodes_menu.buttons.values():
            b.parent_screen = self

        self.navigator.get_button_by_name(KEY_PAGE_DOWN).change_label(str(filelist.get_left_items_number()))
        self.navigator.get_button_by_name(KEY_PAGE_UP).change_label(str(filelist.get_right_items_number()))
        self.episodes_menu.clean_draw_update()
        
        if hasattr(self, "update_observer"):
            self.episodes_menu.add_menu_observers(self.update_observer, self.redraw_observer)

        self.link_borders()

        menu_selected = self.menu.get_selected_index()
        if menu_selected == None:
            if self.current_item == None or len(self.current_item) == 0:
                self.menu.select_by_index(0)
                item = self.menu.get_selected_item()
                if item != None:
                    self.current_item = item.state.name

        for b in self.menu.buttons.values():
            b.parent_screen = self
            if self.current_item == b.state.name:
                self.menu.select_by_index(b.state.index)
                self.navigator.unselect()
                return
    
    def select_episode(self, state):
        """ Select podacst episode
        
        :param state: button state
        """
        if getattr(state, "long_press", None) == True:
            if state.status == STATUS_LOADED:
                self.podcasts_util.delete_episode(state)
                if not self.util.connected_to_internet:
                    for i, c in enumerate(self.episodes):
                        if c.name == state.name:
                            del self.episodes[i]
                            break
                    if len(self.episodes) == 0:
                        self.title = " "
                        self.set_title(0)
                    self.turn_page(state)
                else:
                    state.icon_base = state.event_origin.components[1].content = self.podcasts_util.available_icon
                    state.status = STATUS_AVAILABLE
            elif state.status == STATUS_AVAILABLE:
                if self.podcasts_util.is_podcast_folder_available():                
                    state.icon_base = state.event_origin.components[1].content = self.podcasts_util.loading_icon
                    state.status = STATUS_LOADING
                    self.add_save_episode_listener(state) 
                    self.podcasts_util.save_episode(state, self.notify_save_episode_listeners)                              
            self.clean_draw_update()     
        else:
            self.current_item = state.name
            podcast_player = self.listeners[KEY_PLAYER]
            podcast_player(state)                    

    def add_save_episode_listener(self, listener):
        """ Add save episode listener
        
        :param listener: event listener
        """
        if listener not in self.save_episode_listeners:
            self.save_episode_listeners.append(listener)
            
    def notify_save_episode_listeners(self):
        """ Notify all save episode listeners """
        
        for index, listener in enumerate(self.save_episode_listeners):
            listener.icon_base = listener.event_origin.components[1].content = self.podcasts_util.loaded_icon
            listener.status = STATUS_LOADED
            self.clean_draw_update()
            if hasattr(self, "redraw_observer"):
                self.redraw_observer()
            del self.save_episode_listeners[index]

    def handle_event(self, event):
        """ Handle screen event

        :param event: the event to handle
        """
        self.handle_event_common(event)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        MenuScreen.add_screen_observers(self, update_observer, redraw_observer)
        self.update_observer = update_observer
        self.redraw_observer = redraw_observer
        self.add_loading_listener(redraw_observer)
        self.navigator.add_observers(self.update_observer, self.redraw_observer)
        
Пример #25
0
class BookAuthor(MenuScreen):
    """ Authors screen """
    def __init__(self, util, listeners, ch, f, go_author, parser, base_url,
                 voice_assistant, d):
        """ Initializer
        
        :param util: utility object
        :param listeners: screen listeners
        :param ch: selected character
        :param f: selected filter
        :param go_authors: callback
        :param parser: authors parser
        :param base_url: url
        :param d: dictionary with menu button flags 
        """
        self.util = util
        self.factory = Factory(util)
        self.base_url = base_url
        self.config = util.config

        self.parser = parser
        self.current_author_char = ch
        self.current_author_filter = f
        self.go_author = go_author
        self.author_cache = {}
        self.title = self.config[LABELS][KEY_AUTHORS]

        MenuScreen.__init__(self, util, listeners, MENU_ROWS, MENU_COLUMNS,
                            voice_assistant, d, self.turn_page)
        m = self.create_book_author_menu_button

        font_size = int(((self.menu_layout.h / MENU_ROWS) / 100) *
                        self.config[FONT_HEIGHT_PERCENT])
        self.authors_menu = MultiPageMenu(util,
                                          self.next_page,
                                          self.previous_page,
                                          self.set_title,
                                          self.reset_title,
                                          self.go_to_page,
                                          m,
                                          MENU_ROWS,
                                          MENU_COLUMNS,
                                          None, (0, 0, 0),
                                          self.menu_layout,
                                          font_size=font_size)
        self.set_menu(self.authors_menu)

        self.navigator = BookNavigator(util, self.layout.BOTTOM, listeners,
                                       d[4])
        self.add_component(self.navigator)

    def create_book_author_menu_button(self, s, constr, action, scale,
                                       font_size):
        """ Create Author Menu button

        :param s: button state
        :param constr: bounding box
        :param action: button event listener
        :param show_img: True - show image, False - don't show image
        :param show_label: True - show label, False - don't show label
        
        :return: genre menu button
        """
        s.bounding_box = constr
        s.img_x = None
        s.img_y = None
        s.auto_update = True
        s.show_bgr = True
        s.show_img = False
        s.show_label = True
        s.text_color_normal = self.config[COLORS][COLOR_BRIGHT]
        s.text_color_selected = self.config[COLORS][COLOR_CONTRAST]
        s.text_color_disabled = self.config[COLORS][COLOR_MEDIUM]
        s.text_color_current = s.text_color_normal
        s.fixed_height = font_size

        button = Button(self.util, s)
        button.add_release_listener(action)
        return button

    def create_book_author_items(self, authors):
        """ Create dictionary with author books

        :param authors: list of author books

        :return: dictionary with author books
        """
        items = {}
        for i, g in enumerate(authors):
            state = State()
            state.name = g[AUTHOR_NAME]
            state.url = g[AUTHOR_URL] + "/"
            try:
                state.l_name = state.name + " (" + g[AUTHOR_BOOKS] + ")"
            except:
                state.l_name = state.name
            state.bgr = self.config[COLORS][COLOR_DARK]
            state.img_x = None
            state.img_y = None
            state.auto_update = True
            state.show_bgr = True
            state.show_img = False
            state.show_label = True
            state.comparator_item = state.name
            state.index = i
            items[state.name] = state
        return items

    def set_current(self, ch=None, f=None):
        """ Apply selected character and filter
        
        :param ch: selected character
        :param f: selected filter
        """
        if not ch and not f:
            return

        self.set_loading(self.config[LABELS][KEY_AUTHORS])

        self.total_pages = 0
        self.current_page = 1
        self.current_author_char = ch
        self.current_author_filter = f

        try:
            self.author_cache[ch]
        except:
            self.get_authors()

        self.turn_page()
        self.reset_loading()

    def get_authors(self):
        """ Get authors from parser """

        self.parser.author_parser.current_author_char = self.current_author_char
        self.parser.author_parser.url = self.base_url
        authors = self.parser.get_authors()
        if authors:
            self.author_cache[self.current_author_char] = authors

    def turn_page(self):
        """ Turn authors page """

        self.authors_menu.set_items({}, 0, self.go_author)

        filtered_authors = []
        for a in self.author_cache[self.current_author_char]:
            if self.current_author_filter:
                if a[AUTHOR_NAME].startswith(self.current_author_filter):
                    filtered_authors.append(a)
            else:
                filtered_authors.append(a)

        start = (self.current_page - 1) * PAGE_SIZE
        end = self.current_page * PAGE_SIZE
        page = filtered_authors[start:end]
        self.author_dict = self.create_book_author_items(page)
        self.authors_menu.set_items(self.author_dict, 0, self.go_author, False)
        self.authors_menu.align_content(ALIGN_LEFT)
        self.authors_menu.select_by_index(0)
        self.authors_menu.clean_draw_update()

        self.total_pages = math.ceil(len(filtered_authors) / PAGE_SIZE)

        left = str(self.current_page - 1)
        if self.total_pages == 0:
            right = "0"
        else:
            right = str(self.total_pages - self.current_page)
        self.navigator.left_button.change_label(left)
        self.navigator.right_button.change_label(right)
        self.set_title(self.current_page)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        self.navigator.add_observers(update_observer, redraw_observer)
        self.authors_menu.add_menu_loaded_listener(redraw_observer)
        self.authors_menu.add_menu_observers(update_observer,
                                             redraw_observer,
                                             release=False)
Пример #26
0
class BookAuthor(MenuScreen):
    """ Authors screen """
    def __init__(self, util, listeners, ch, f, go_author, parser, base_url,
                 voice_assistant, d):
        """ Initializer
        
        :param util: utility object
        :param listeners: screen listeners
        :param ch: selected character
        :param f: selected filter
        :param go_authors: callback
        :param parser: authors parser
        :param base_url: url
        :param d: dictionary with menu button flags 
        """
        self.util = util
        self.factory = Factory(util)
        self.base_url = base_url
        self.config = util.config

        self.parser = parser
        self.current_author_char = ch
        self.current_author_filter = f
        self.go_author = go_author
        self.author_cache = {}
        self.title = self.config[LABELS][KEY_AUTHORS]

        MenuScreen.__init__(self, util, listeners, MENU_ROWS, MENU_COLUMNS,
                            voice_assistant, d, self.turn_page)
        m = self.factory.create_book_author_menu_button

        self.authors_menu = MultiPageMenu(util, self.next_page,
                                          self.previous_page, self.set_title,
                                          self.reset_title, self.go_to_page, m,
                                          MENU_ROWS, MENU_COLUMNS, None,
                                          (0, 0, 0), self.menu_layout)
        self.set_menu(self.authors_menu)

    def set_current(self, ch=None, f=None):
        """ Apply selected character and filter
        
        :param ch: selected character
        :param f: selected filter
        """
        if not ch and not f:
            return

        self.set_loading(self.config[LABELS][KEY_AUTHORS])

        self.total_pages = 0
        self.current_page = 1
        self.current_author_char = ch
        self.current_author_filter = f

        try:
            self.author_cache[ch]
        except:
            self.get_authors()

        self.turn_page()
        self.reset_loading()

    def get_authors(self):
        """ Get authors from parser """

        self.parser.author_parser.current_author_char = self.current_author_char
        self.parser.author_parser.url = self.base_url
        authors = self.parser.get_authors()
        if authors:
            self.author_cache[self.current_author_char] = authors

    def turn_page(self):
        """ Turn authors page """

        self.authors_menu.set_items({}, 0, self.go_author)

        filtered_authors = []
        for a in self.author_cache[self.current_author_char]:
            if self.current_author_filter:
                if a[AUTHOR_NAME].startswith(self.current_author_filter):
                    filtered_authors.append(a)
            else:
                filtered_authors.append(a)

        start = (self.current_page - 1) * PAGE_SIZE
        end = self.current_page * PAGE_SIZE
        page = filtered_authors[start:end]
        self.author_dict = self.factory.create_book_author_items(page)
        self.authors_menu.set_items(self.author_dict, 0, self.go_author, False)
        self.authors_menu.align_content(ALIGN_LEFT)
        self.authors_menu.select_by_index(0)
        self.authors_menu.clean_draw_update()

        self.total_pages = math.ceil(len(filtered_authors) / PAGE_SIZE)

        left = str(self.current_page - 1)
        if self.total_pages == 0:
            right = "0"
        else:
            right = str(self.total_pages - self.current_page)
        self.navigator.left_button.change_label(left)
        self.navigator.right_button.change_label(right)
        self.set_title(self.current_page)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        self.navigator.add_observers(update_observer, redraw_observer)
        self.authors_menu.add_menu_loaded_listener(redraw_observer)
        self.authors_menu.add_menu_observers(update_observer,
                                             redraw_observer,
                                             release=False)
Пример #27
0
class RadioGroupScreen(MenuScreen):
    """ Radio group screen """
    def __init__(self, util, listeners, voice_assistant):
        self.util = util
        self.config = util.config
        self.groups_list = self.util.get_stations_folders()
        self.factory = Factory(util)
        d = [MENU_ROWS, MENU_COLUMNS]
        MenuScreen.__init__(self,
                            util,
                            listeners,
                            MENU_ROWS,
                            MENU_COLUMNS,
                            voice_assistant,
                            d,
                            self.turn_page,
                            page_in_title=False)
        self.total_pages = math.ceil(len(self.groups_list) / PAGE_SIZE)
        self.title = util.get_stations_top_folder()
        m = self.create_genre_menu_button
        label_area = (
            (self.menu_layout.h / MENU_ROWS) / 100) * (100 - ICON_AREA)
        font_size = int((label_area / 100) * FONT_HEIGHT)
        self.groups_menu = MultiPageMenu(util,
                                         self.next_page,
                                         self.previous_page,
                                         self.set_title,
                                         self.reset_title,
                                         self.go_to_page,
                                         m,
                                         MENU_ROWS,
                                         MENU_COLUMNS,
                                         None, (0, 0, 0, 0),
                                         self.menu_layout,
                                         align=ALIGN_CENTER,
                                         font_size=font_size)
        self.groups_menu.add_listener(listeners[KEY_GENRE])
        self.set_menu(self.groups_menu)

        color_dark_light = self.config[COLORS][COLOR_DARK_LIGHT]
        self.navigator = RadioGroupNavigator(self.util, self.layout.BOTTOM,
                                             listeners, color_dark_light,
                                             self.total_pages)
        self.add_component(self.navigator)

        current_name = self.get_current_group_name()

        if current_name == None:
            self.current_page = 1
        else:
            try:
                current_group_index = self.groups_list.index(current_name)
                self.current_page = int(current_group_index / PAGE_SIZE) + 1
            except:
                current_group_index = 0

        self.turn_page()

    def create_genre_menu_button(self, s, constr, action, scale, font_size):
        """ Create Genre Menu button

        :param s: button state
        :param constr: scaling constraints
        :param action: button event listener
        :param scale: True - scale images, False - don't scale images

        :return: genre menu button
        """
        s.padding = BUTTON_PADDING
        s.image_area_percent = ICON_AREA
        s.fixed_height = font_size
        s.v_align = CENTER

        return self.factory.create_menu_button(s,
                                               constr,
                                               action,
                                               scale,
                                               font_size=font_size)

    def get_current_group_name(self):
        key = STATIONS + "." + self.config[CURRENT][LANGUAGE]
        name = None
        try:
            name = self.config[key][CURRENT_STATIONS]
        except:
            pass
        return name

    def get_page(self):
        start = (self.current_page - 1) * PAGE_SIZE
        end = self.current_page * PAGE_SIZE
        tmp_layout = self.groups_menu.get_layout(self.groups_list)
        button_rect = tmp_layout.constraints[0]
        image_box = self.factory.get_icon_bounding_box(button_rect,
                                                       ICON_LOCATION,
                                                       ICON_AREA, ICON_SIZE,
                                                       BUTTON_PADDING)
        groups_dict = self.util.load_stations_folders(image_box)

        return self.util.get_radio_group_slice(groups_dict, start, end)

    def turn_page(self):
        """ Turn book genre page """

        group_page = self.get_page()
        self.groups_menu.set_items(group_page, 0, self.change_group, False)
        current_name = self.get_current_group_name()

        try:
            self.current_genre = group_page[current_name]
            self.groups_menu.item_selected(self.current_genre)
        except:
            keys = list(group_page.keys())
            self.groups_menu.item_selected(group_page[keys[0]])

        if self.navigator and self.total_pages > 1:
            self.navigator.left_button.change_label(str(self.current_page - 1))
            self.navigator.right_button.change_label(
                str(self.total_pages - self.current_page))

        for b in self.groups_menu.buttons.values():
            b.parent_screen = self

        self.set_title(self.current_page)
        self.groups_menu.clean_draw_update()

    def change_group(self, state):
        """ Change group event listener
         
        :param state: button state
        """
        if not self.visible:
            return
        self.current_genre = state

        key = STATIONS + "." + self.config[CURRENT][LANGUAGE]
        self.config[key][CURRENT_STATIONS] = state.genre
        state.source = GENRE
        self.groups_menu.notify_listeners(state)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        self.navigator.add_observers(update_observer, redraw_observer)
        self.groups_menu.add_menu_observers(update_observer,
                                            redraw_observer,
                                            release=False)
Пример #28
0
class BookGenre(MenuScreen):
    """ Bokk genre screen """
    def __init__(self, util, listeners, go_book_by_genre, genres, base_url,
                 voice_assistant, d):
        self.util = util
        self.go_book_by_genre = go_book_by_genre
        self.config = util.config
        self.genres_list = genres
        self.base_url = base_url
        self.factory = Factory(util)
        MenuScreen.__init__(self, util, listeners, MENU_ROWS, MENU_COLUMNS,
                            voice_assistant, d, self.turn_page)
        self.total_pages = math.ceil(len(genres) / PAGE_SIZE)
        self.title = self.config[LABELS][KEY_CHOOSE_GENRE]
        m = self.create_book_genre_menu_button
        font_size = int(((self.menu_layout.h / MENU_ROWS) / 100) *
                        self.config[FONT_HEIGHT_PERCENT])
        self.genre_menu = MultiPageMenu(util,
                                        self.next_page,
                                        self.previous_page,
                                        self.set_title,
                                        self.reset_title,
                                        self.go_to_page,
                                        m,
                                        MENU_ROWS,
                                        MENU_COLUMNS,
                                        None, (0, 0, 0, 0),
                                        self.menu_layout,
                                        font_size=font_size)
        self.set_menu(self.genre_menu)
        self.navigator = BookNavigator(util, self.layout.BOTTOM, listeners,
                                       d[4])
        self.add_component(self.navigator)
        self.turn_page()

    def create_book_genre_menu_button(self,
                                      s,
                                      constr,
                                      action,
                                      show_img=True,
                                      show_label=True):
        """ Create Genre Menu button

        :param s: button state
        :param constr: bounding box
        :param action: button event listener
        :param show_img: True - show image, False - don't show image
        :param show_label: True - show label, False - don't show label

        :return: genre menu button
        """
        s.bounding_box = constr
        s.img_x = None
        s.img_y = None
        s.auto_update = True
        s.show_bgr = True
        s.show_img = show_img
        s.show_label = show_label
        s.text_color_normal = self.config[COLORS][COLOR_BRIGHT]
        s.text_color_selected = self.config[COLORS][COLOR_CONTRAST]
        s.text_color_disabled = self.config[COLORS][COLOR_MEDIUM]
        s.text_color_current = s.text_color_normal
        s.label_text_height = 35
        s.bgr = self.config[BACKGROUND][MENU_BGR_COLOR]

        button = Button(self.util, s)
        button.add_release_listener(action)
        return button

    def turn_page(self):
        """ Turn book genre page """

        start = (self.current_page - 1) * PAGE_SIZE
        end = self.current_page * PAGE_SIZE
        page = self.genres_list[start:end]
        self.genres_dict = self.factory.create_book_genre_items(
            page, self.base_url)
        self.genre_menu.set_items(self.genres_dict, 0, self.go_book_by_genre,
                                  False)
        self.genre_menu.align_content(ALIGN_LEFT)

        for b in self.genre_menu.buttons.values():
            b.parent_screen = self

        self.genre_menu.select_by_index(0)
        self.genre_menu.clean_draw_update()

        self.navigator.left_button.change_label(str(self.current_page - 1))
        self.navigator.right_button.change_label(
            str(self.total_pages - self.current_page))
        self.set_title(self.current_page)

    def add_screen_observers(self, update_observer, redraw_observer):
        """ Add screen observers
        
        :param update_observer: observer for updating the screen
        :param redraw_observer: observer to redraw the whole screen
        """
        self.navigator.add_observers(update_observer, redraw_observer)
        self.genre_menu.add_menu_observers(update_observer,
                                           redraw_observer,
                                           release=False)