Ejemplo n.º 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.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
Ejemplo n.º 2
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
Ejemplo n.º 3
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
        font_size = int(((self.menu_layout.h / ROWS) / 100) * FONT_HEIGHT)

        h = self.config[HORIZONTAL_LAYOUT]
        bgr = self.config[BACKGROUND][MENU_BGR_COLOR]
        self.topic_menu = Menu(util, bgr, self.menu_layout, ROWS, COLUMNS, create_item_method=m, align=ALIGN_LEFT, horizontal_layout=h, font_size=font_size)
        self.set_menu(self.topic_menu)

        self.navigator = TopicNavigator(self.util, self.layout.BOTTOM, listeners)
        self.add_navigator(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
Ejemplo n.º 4
0
def say(ctx: Context, *, args: str):
    print(f"[{ctx.target.name if ctx.target else '@'}] ", end="")
    it = StrIterator(args)
    while c := it.peek():
        if c == "@":
            s = Selector.convert(it)
            entities = s.apply(ctx)
            names = map(lambda e: e.name, entities)
            print(f"[{', '.join(names) if len(entities) > 0 else ''}]", end="")
        else:
            next(it)
            print(c, end="")
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
def data_entity(ctx: Context, target: Selector) -> Optional[Entity]:
    return target.apply_one(ctx)
Ejemplo n.º 7
0
def execute_as(ctx: Context, target: Selector):
    for e in target.apply(ctx):
        c = ctx.copy()
        c.target = e
        c.redirect(execute)
Ejemplo n.º 8
0
def kill(ctx: Context, target: Selector):
    for dead in target.apply(ctx):
        del ctx.world.entities[dead.uuid]
Ejemplo n.º 9
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
        font_size = int(((self.menu_layout.h / ROWS) / 100) * FONT_HEIGHT)

        h = self.config[HORIZONTAL_LAYOUT]
        bgr = self.config[BACKGROUND][MENU_BGR_COLOR]
        self.topic_menu = Menu(util, bgr, self.menu_layout, ROWS, COLUMNS, create_item_method=m, align=ALIGN_LEFT, horizontal_layout=h, font_size=font_size)
        self.set_menu(self.topic_menu)

        self.navigator = TopicNavigator(self.util, self.layout.BOTTOM, listeners)
        self.add_navigator(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

        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
                self.current_item = None

        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.navigator.set_parent_screen(self)
        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)
            self.link_borders()
            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)

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

        self.topic_menu.unselect()
        self.link_borders()

        if self.navigator.is_selected():
            return

        for b in self.topic_menu.buttons.values():
            b.parent_screen = self
            if self.current_item == b.state.name:
                self.topic_menu.select_by_index(b.state.index)
                return
        self.navigator.menu_button.set_selected(True)
        self.navigator.menu_button.clean_draw_update()

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

        :return: page dictionary
        """
        page, self.first_item, self.last_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 = []
            first_item = None
            last_item = None
        else:
            first_item = page_items[0]
            last_item = page_items[len(page_items) - 1]

        return (page_items, first_item, last_item)

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

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

        self.current_item = s.name
        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)
Ejemplo n.º 10
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)

        self.navigator = TopicDetailNavigator(self.util, self.layout.BOTTOM,
                                              listeners)
        self.add_navigator(self.navigator)
        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.player_button = self.navigator.get_button_by_name(KEY_PLAYER)

        m = self.factory.create_collection_menu_button
        font_size = int(((self.menu_layout.h / ROWS) / 100) * FONT_HEIGHT)
        h = self.config[HORIZONTAL_LAYOUT]
        bgr = self.config[BACKGROUND][MENU_BGR_COLOR]
        self.collection_list_menu = Menu(util,
                                         bgr,
                                         self.menu_layout,
                                         ROWS,
                                         COLUMNS,
                                         create_item_method=m,
                                         align=ALIGN_LEFT,
                                         horizontal_layout=h,
                                         font_size=font_size)
        self.set_menu(self.collection_list_menu)

        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