コード例 #1
0
    def onInit(self):  # pylint: disable=invalid-name
        self.set_info()
        self.prepare_progress_control()

        if get_setting_bool('stopAfterClose'):
            self.getControl(3013).setLabel(localize(30033))  # Stop
        else:
            self.getControl(3013).setLabel(localize(30034))  # Close
コード例 #2
0
ファイル: buttons.py プロジェクト: basilstotz/puavo-os
    def open_menu(self, widget, event):
        if self.disabled:
            return

        if event.button in (1, 2, 3):
            # Clicked the popup menu indicator
            if self.__enable_popup and self.__popup_hover:
                self.__menu = Gtk.Menu()

                if self.__have_desktop_dir:
                    # Can't do this without the desktop directory
                    desktop_item = Gtk.MenuItem(
                        utils.localize(STRINGS['popup_add_to_desktop'],
                                       self.__language))
                    desktop_item.connect(
                        'activate', lambda x: self.__special_operation(
                            self.parent.add_program_to_desktop))
                    desktop_item.show()
                    self.__menu.append(desktop_item)

                panel_item = Gtk.MenuItem(
                    utils.localize(STRINGS['popup_add_to_panel'],
                                   self.__language))
                panel_item.connect(
                    'activate', lambda x: self.__special_operation(
                        self.parent.add_program_to_panel))
                panel_item.show()
                self.__menu.append(panel_item)

                if self.is_fave:
                    # special entry for fave buttons
                    remove_fave = Gtk.MenuItem(
                        utils.localize(STRINGS['popup_remove_from_faves'],
                                       self.__language))
                    remove_fave.connect(
                        'activate', lambda x: self.__special_operation(
                            self.parent.remove_program_from_faves))
                    remove_fave.show()
                    self.__menu.append(remove_fave)

                # Need to do things when the menu closes...
                self.__menu.connect('deactivate', self.__cancel_menu)

                # ...and if autohiding is enabled (like it usually is) we
                # must NOT hide the window when the menu opens!
                self.parent.disable_out_of_focus_hide()

                self.__popup_open = True
                self.__menu.popup(parent_menu_shell=None,
                                  parent_menu_item=None,
                                  func=None,
                                  data=None,
                                  button=event.button,
                                  activate_time=event.time)
                return True

        # Clicked on something else
        return False
コード例 #3
0
    def open_menu(self, widget, event):
        if self.disabled:
            return

        if event.button == 3:
            self.menu = Gtk.Menu()

            desktop_item = Gtk.MenuItem(
                localize(self.MENU_ITEMS['add_to_desktop'],
                         self.parent.language))
            desktop_item.connect(
                'activate', lambda x: self.__special_operation(
                    self.parent.add_program_to_desktop))
            desktop_item.show()
            self.menu.append(desktop_item)

            panel_item = Gtk.MenuItem(
                localize(self.MENU_ITEMS['add_to_panel'],
                         self.parent.language))
            panel_item.connect(
                'activate', lambda x: self.__special_operation(
                    self.parent.add_program_to_panel))
            panel_item.show()
            self.menu.append(panel_item)

            if self.is_fave:
                # special entry for fave buttons
                remove_fave = Gtk.MenuItem(
                    localize(self.MENU_ITEMS['remove_from_faves'],
                             self.parent.language))
                remove_fave.connect(
                    'activate', lambda x: self.__special_operation(
                        self.parent.remove_program_from_faves))
                remove_fave.show()
                self.menu.append(remove_fave)

            # Need to do things when the menu closes...
            self.menu.connect('deactivate', self.__cancel_menu)

            # ...and if autohiding is enabled (like it usually is) we
            # must NOT hide the window when the menu opens!
            self.parent.disable_out_of_focus_hide()

            self.menu_open = True
            self.menu.popup(parent_menu_shell=None,
                            parent_menu_item=None,
                            func=None,
                            data=None,
                            button=event.button,
                            activate_time=event.time)
コード例 #4
0
    def __create_button(self, y, data):
        button = buttons.SidebarButton(
            self, self.__settings,
            utils.localize(data['title'], self.__settings.language),
            self.__icons[data['icon']],
            utils.localize(data.get('description', ''),
                           self.__settings.language), data['command'])

        button.connect('clicked', self.__clicked_sidebar_button)
        button.show()
        self.container.put(button, 0, y)

        # the next available Y coordinate
        return y + button.get_preferred_button_size()[1]
コード例 #5
0
ファイル: sidebar.py プロジェクト: Peeveli/puavo-os
    def __clicked_changelog(self, *unused):
        try:
            web_window(
                url=utils.expand_variables(get_changelog_url() + '&theme=$(user_theme)', self.__variables),
                title=utils.localize(STRINGS['sb_changelog_window_title'], self.__settings.language),
                width=1000,
                height=650,
                enable_js=True)     # Markdown is used on the page, need JS
        except Exception as exception:
            logging.error(str(exception))
            self.__parent.error_message(
                utils.localize(STRINGS['sb_changelog_link_failed'], self.__settings.language),
                str(exception))

        self.__parent.autohide()
コード例 #6
0
    def __create_hostinfo(self):
        label_top = WINDOW_HEIGHT - MAIN_PADDING - HOSTINFO_LABEL_HEIGHT

        utils_gui.create_separator(container=self.container,
                                   x=0,
                                   y=label_top - MAIN_PADDING,
                                   w=SIDEBAR_WIDTH,
                                   h=1,
                                   orientation=Gtk.Orientation.HORIZONTAL)

        hostname_label = Gtk.Label()
        hostname_label.set_size_request(SIDEBAR_WIDTH, HOSTINFO_LABEL_HEIGHT)
        hostname_label.set_ellipsize(Pango.EllipsizeMode.END)
        hostname_label.set_justify(Gtk.Justification.CENTER)
        hostname_label.set_alignment(0.5, 0.5)
        hostname_label.set_use_markup(True)

        # FIXME: "big" and "small" are not good sizes, we need to be explicit
        hostname_label.set_markup(
            '<big>{0}</big>\n<small><a href="{3}" title="{4}">{1}</a> ({2})</small>'
            .format(
                utils.get_file_contents('/etc/puavo/hostname'),
                utils.get_file_contents('/etc/puavo-image/release'),
                utils.get_file_contents('/etc/puavo/hosttype'), '',
                utils.localize(STRINGS['sb_changelog_title'],
                               self.__settings.language)))

        hostname_label.connect('activate-link', self.__clicked_changelog)
        hostname_label.show()
        self.container.put(hostname_label, 0, label_top)
コード例 #7
0
ファイル: main.py プロジェクト: basilstotz/puavo-os
    def __show_empty_message(self, msg):
        if isinstance(msg, dict):
            msg = utils.localize(msg, self.__settings.language)

        self.__empty.set_markup(
            '<span color="#888" size="large"><i>{0}</i></span>'.format(msg))
        self.__empty.show()
コード例 #8
0
    def __clicked_avatar_button(self, _):
        print('Clicked the user avatar button')

        try:
            web_window(url=utils.expand_variables(
                'https://$(puavo_domain)/users/profile/edit?lang=$(user_language)',
                self.__variables),
                       title=utils.localize(STRINGS['sb_avatar_hover'],
                                            self.__settings.language),
                       width=1000,
                       height=650,
                       enable_js=True)  # The profile editor needs JavaScript
        except Exception as exception:
            logging.error(str(exception))
            self.__parent.error_message(
                utils.localize(STRINGS['sb_avatar_link_failed'],
                               self.__settings.language), str(exception))

        self.__parent.autohide()
コード例 #9
0
    def get_all_operations(self, broker_account_started_at: datetime) \
                -> List[tinvest.schemas.Operation]:
        """Возвращает все операции в портфеле с указанной даты"""
        from_ = localize(broker_account_started_at)
        now = get_now()

        operations = (self._client.\
            get_operations(broker_account_id=self._broker_account_id, from_=from_, to=now)\
            .payload.operations)
        return operations
コード例 #10
0
def handle_incoming_messages():
    #Information
    data = request.json
    userid = data['entry'][0]['messaging'][0]['sender']['id']
    timestamp = data['entry'][0]['messaging'][0]['timestamp']
    msg = ''
    if 'text' in data['entry'][0]['messaging'][0]['message']:
        msg = data['entry'][0]['messaging'][0]['message']['text']
    #/Information
    user = botutils.User(userid, 0)
    utils.localize(user)

    if msg.startswith('/'):
        command_task = threading.Thread(target=bot.runCommand, name='command_task', args=(user, msg))
        command_task.start()

    else:
        if easter_slug.on_message(user, msg) == 0:
            chatting_slug.on_message(user, msg)

    return 'ok'
コード例 #11
0
ファイル: setu.py プロジェクト: missainnocte/meido_vernus
 def _ret(s):
     r = requests.get(SETU_API).json()
     for img in r.get('data'):
         p = LOCAL_SERVER + localize(img.get('url'))
         send(s, target, [{
             'type': 'Plain',
             'text': '色图time!'
         }, {
             'type': 'Image',
             'url': p
         }])
         log.info('完成发送色图到{}, 色图: {}'.format(target, img.get('url')))
コード例 #12
0
ファイル: main.py プロジェクト: basilstotz/puavo-os
    def add_program_to_panel(self, program):
        logging.info('Adding program "%s" (id="%s") to the bottom panel',
                     program.name, program.name)

        try:
            utils_gui.create_panel_link(program)
        except Exception as exception:
            logging.error('Panel icon creation failed')
            logging.error(str(exception))

            self.error_message(
                utils.localize(STRINGS['panel_link_failed'],
                               self.__settings.language), str(exception))
コード例 #13
0
ファイル: dialog.py プロジェクト: MoojMidge/service.upnext
    def set_info(self):
        if self.item.get('rating') is None:
            rating = ''
        else:
            rating = str(round(float(self.item.get('rating')), 1))

        self.setProperty(
            'stop_close_label',
            utils.localize(
                constants.STOP_STRING_ID if self.stop_enable
                else constants.CLOSE_STRING_ID
            )
        )
        self.setProperty('shuffle_enable', str(self.shuffle is not None))
        self.setProperty('shuffle_on', str(self.shuffle))

        if self.item is not None:
            art = self.item.get('art')
            self.setProperty('fanart', art.get('tvshow.fanart', ''))
            self.setProperty('landscape', art.get('tvshow.landscape', ''))
            self.setProperty('clearart', art.get('tvshow.clearart', ''))
            self.setProperty('clearlogo', art.get('tvshow.clearlogo', ''))
            self.setProperty('poster', art.get('tvshow.poster', ''))
            self.setProperty('thumb', art.get('thumb', ''))
            self.setProperty('plot', self.item.get('plot', ''))
            self.setProperty('tvshowtitle', self.item.get('showtitle', ''))
            self.setProperty('title', self.item.get('title', ''))
            season = str(self.item.get('season', ''))
            self.setProperty('season', season)
            episode = str(self.item.get('episode', ''))
            self.setProperty('episode', episode)
            self.setProperty(
                'seasonepisode',
                '{0}x{1}'.format(season, episode) if season else episode
            )
            firstaired, firstaired_string = utils.localize_date(
                self.item.get('firstaired', '')
            )
            self.setProperty('firstaired', firstaired_string)
            self.setProperty('premiered', firstaired_string)
            self.setProperty(
                'year',
                str(firstaired.year) if firstaired else firstaired_string
            )
            self.setProperty('rating', rating)
            self.setProperty('playcount', str(self.item.get('playcount', 0)))
            self.setProperty('runtime', str(self.item.get('runtime', '')))
コード例 #14
0
    def __create_avatar(self):
        self.__must_download_avatar = True

        default_avatar = path_join(self.__settings.res_dir,
                                   'default_avatar.png')
        existing_avatar = path_join(self.__settings.user_dir, 'avatar.jpg')

        if self.__settings.is_guest or self.__settings.is_webkiosk:
            # Always use the default avatar for guests and webkiosk sessions
            logging.info('Not loading avatar for a guest/webkiosk session')
            avatar_image = default_avatar
            self.__must_download_avatar = False
        elif file_exists(existing_avatar):
            logging.info(
                'A previously-downloaded user avatar file exists, using it')
            avatar_image = existing_avatar
        else:
            # We need to download this avatar image right away, use the
            # default avatar until the download is complete
            logging.info(
                'Not a guest/webkiosk session and no previously-'
                'downloaded avatar available, using the default image')
            avatar_image = default_avatar

        if self.__settings.is_guest or self.__settings.is_webkiosk:
            avatar_tooltip = None
        else:
            avatar_tooltip = \
                utils.localize(STRINGS['sb_avatar_hover'], self.__settings.language)

        self.__avatar = buttons.AvatarButton(self, self.__settings, getuser(),
                                             avatar_image, avatar_tooltip)

        # No profile editing for guest users
        if self.__settings.is_guest or self.__settings.is_webkiosk:
            logging.info('Disabling the avatar button for guest user')
            self.__avatar.disable()
        else:
            self.__avatar.connect('clicked', self.__clicked_avatar_button)

        self.container.put(self.__avatar, 0, MAIN_PADDING)
        self.__avatar.show()
コード例 #15
0
def _copy_episode_details(upnext_info):
    # If next episode information is not provided, fake it
    if not upnext_info.get('next_episode'):
        episode = upnext_info['current_episode']
        episode['episodeid'] = constants.UNKNOWN_DATA
        episode['art'] = {}
        # Next provided episode may not be the next consecutive episode so we
        # can't assume that the episode can simply be incremented, instead set
        # title to indicate the next episode in the UpNext popup
        # episode['episode'] = utils.get_int(episode, 'episode') + 1
        episode['title'] = utils.localize(constants.NEXT_STRING_ID)
        # Change season and episode info to empty string to avoid episode
        # formatting issues ("S-1E-1") in UpNext popup
        episode['season'] = ''
        episode['episode'] = ''
        episode['plot'] = ''
        episode['playcount'] = 0
        episode['rating'] = 0
        episode['firstaired'] = ''
        episode['runtime'] = 0
        upnext_info['next_episode'] = episode

    # If current episode information is not provided, fake it
    elif not upnext_info.get('current_episode'):
        episode = upnext_info['next_episode']
        episode['episodeid'] = constants.UNKNOWN_DATA
        episode['art'] = {}
        episode['title'] = ''
        episode['season'] = ''
        episode['episode'] = ''
        episode['plot'] = ''
        episode['playcount'] = 0
        episode['rating'] = 0
        episode['firstaired'] = ''
        episode['runtime'] = 0
        upnext_info['current_episode'] = episode

    return upnext_info
コード例 #16
0
ファイル: main.py プロジェクト: basilstotz/puavo-os
    def add_program_to_desktop(self, program):
        """Creates a desktop shortcut to a program."""

        if not self.__settings.desktop_dir:
            return

        # Create the link file
        # TODO: use the *original* .desktop file if it exists
        name = os.path.join(self.__settings.desktop_dir,
                            '{0}.desktop'.format(program.name))

        logging.info('Adding program "%s" to the desktop, destination="%s"',
                     program.name, name)

        try:
            utils_gui.create_desktop_link(name, program)
        except Exception as exception:
            logging.error('Desktop link creation failed:')
            logging.error(str(exception))

            self.error_message(
                utils.localize(STRINGS['desktop_link_failed'],
                               self.__settings.language), str(exception))
コード例 #17
0
ファイル: main.py プロジェクト: basilstotz/puavo-os
    def clicked_program_button(self, button):
        program = button.data
        program.uses += 1

        logging.info('Clicked program button "%s", usage counter is %d',
                     program.menudata_id, program.uses)

        self.__faves.update(self.menudata.programs, self.__settings)

        if program.command is None:
            logging.error('No command defined for program "%s"', program.name)
            return

        # Try to launch the program. Use Gio's services, as Gio understands the
        # "Exec=" keys and we don't have to spawn shells with pipes and "sh".
        try:
            if self.__settings.prod_mode:
                # Spy the user and log what programs they use. This information
                # is then sent to various TLAs around the world and used in all
                # sorts of nefarious classified black operations.
                syslog.syslog(
                    syslog.LOG_INFO,
                    'Launching program "{0}", command="{1}"'.format(
                        program.menudata_id, program.command))

                # Just kidding. The reason program starts are logged to syslog
                # is actually really simple: you can grep the log and count
                # which programs are actually used and how many times.

                # Of course this only logs programs that are started through
                # Puavomenu, but we decided to ignore this for now.

            logging.info('Executing "%s"', program.command)

            if program.program_type in (PROGRAM_TYPE_DESKTOP,
                                        PROGRAM_TYPE_CUSTOM):
                # Set the program name to empty string ('') to force some (KDE)
                # programs to use their default window titles. These programs
                # have command-line parameters like "-qwindowtitle" or "-caption"
                # and Gio, when launching the program, sets the "%c" argument
                # (in the Exec= key) to the program's name it takes from the
                # command (program.command). This is Wrong(TM), but during
                # testing I noticed that if we leave it empty (*NOT* None
                # because that triggers the unwanted behavior!) then these
                # programs will use their own default titles.
                Gio.AppInfo.create_from_commandline(program.command, '',
                                                    0).launch()
            elif program.program_type == PROGRAM_TYPE_WEB:
                Gio.AppInfo.launch_default_for_uri(program.command, None)
            else:
                raise RuntimeError('Unknown program type "{0}"'.format(
                    program.program_type))

            # Of course, we never check the return value here, so we
            # don't know if the command actually worked...

            self.autohide()

            if self.__settings.reset_view_after_start:
                # Go back to the default view
                self.reset_view()

        except Exception as exception:
            logging.error('Could not launch program "%s": %s', program.command,
                          str(exception))
            self.error_message(
                utils.localize(STRINGS['program_launching_failed'],
                               self.__settings.language), str(exception))
            return False
コード例 #18
0
ファイル: main.py プロジェクト: basilstotz/puavo-os
    def __init__(self, settings):
        """This is where the magic happens."""

        start_time = time.clock()

        super().__init__()

        self.__settings = settings

        # Ensure the window is not visible until it's ready
        self.set_visible(False)

        self.set_type_hint(Gtk.WindowType.TOPLEVEL)

        # ----------------------------------------------------------------------
        # Set up a domain socket for show/hide messages from the panel
        # button shell extension. This is done early, because if it
        # fails, we simply exit. We can't do *anything* without it.
        # (The only other choice would be to always display the menu,
        # never allowing the user to hide it because without the socket
        # it cannot be reopened.)

        try:
            # Clean leftovers
            os.unlink(self.__settings.socket)
        except OSError:
            pass

        try:
            self.__socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
            self.__socket.bind(self.__settings.socket)
        except Exception as exception:
            # Oh dear...
            logging.error('Unable to create a domain socket for IPC!')
            logging.error('Reason: %s', str(exception))
            logging.error('Socket name: "%s"', self.__settings.socket)
            logging.error('This is a fatal error, stopping here.')

            syslog.syslog(syslog.LOG_CRIT,
                          'PuavoMenu IPC socket "%s" creation failed: %s',
                          self.__settings.socket, str(exception))

            syslog.syslog(syslog.LOG_CRIT,
                          'PuavoMenu stops here. Contact Opinsys support.')

            exit(1)

        # Start listening the socket. Use glib's watch functions, then
        # we don't need to use threads (which work too, but are harder
        # to clean up and we'll run into problems with multihtreaded
        # xlib programs).

        # https://developer.gnome.org/pygobject/stable/glib-functions.html#
        #   function-glib--io-add-watch
        GLib.io_add_watch(self.__socket, GLib.IO_IN, self.__socket_watcher)

        # ----------------------------------------------------------------------

        # Exit stuff. By default the program cannot be exited normally.
        self.__exit_permitted = False
        self.connect('delete-event', self.__try_exit)

        # Program, menu and category data
        self.menudata = None

        # Current category (index to menudata.category_index)
        self.current_category = -1

        # The current menu, if any (None if on category top-level)
        self.current_menu = None

        # The current menu/program buttons in the current
        # category and menu, if any
        self.__buttons = []

        # Storage for 48x48 -pixel program and menu icons. Maintained
        # separately from the menu data.
        self.__icons = iconcache.IconCache(48, 48 * 20)

        # Background image for top-level menus
        try:
            if self.__settings.dark_theme:
                image_name = 'folder_dark.png'
            else:
                image_name = 'folder.png'

            # WARNING: Hardcoded image size!
            self.__menu_background = \
                utils_gui.load_image_at_size(self.__settings.res_dir + image_name, 150, 110)
        except Exception as exception:
            logging.error("Can't load the menu background image: %s",
                          str(exception))
            self.__menu_background = None

        # ----------------------------------------------------------------------
        # Create the window elements

        # Set window style
        if self.__settings.prod_mode:
            self.set_skip_taskbar_hint(True)
            self.set_skip_pager_hint(True)
            self.set_deletable(False)  # no close button
            self.set_decorated(False)
        else:
            # makes developing slightly easier
            self.set_skip_taskbar_hint(False)
            self.set_skip_pager_hint(False)
            self.set_deletable(True)
            self.set_decorated(True)
            self.__exit_permitted = True

        # Don't mess with the real menu when running in development mode
        if self.__settings.prod_mode:
            self.set_title('PuavoMenuUniqueName')
        else:
            self.set_title('DevModePuavoMenu')

        self.set_resizable(False)
        self.set_size_request(WINDOW_WIDTH, WINDOW_HEIGHT)
        self.set_position(Gtk.WindowPosition.CENTER)

        # Top-level container for all widgets. This is needed, because
        # a window can contain only one child widget and we can have
        # dozens of them. Every widget has a fixed position and size,
        # because the menu isn't user-resizable.
        self.__main_container = Gtk.Fixed()
        self.__main_container.set_size_request(WINDOW_WIDTH, WINDOW_HEIGHT)

        if not self.__settings.prod_mode:
            # Create the devtools popup menu
            self.menu_signal = \
                self.connect('button-press-event', self.__devtools_menu)

        # ----------------------------------------------------------------------
        # Menus/programs list

        # TODO: Gtk.Notebook isn't the best choice for this

        # Category tabs
        self.__category_buttons = Gtk.Notebook()
        self.__category_buttons.set_size_request(CATEGORIES_WIDTH, -1)
        self.__category_buttons.connect('switch-page', self.__clicked_category)
        self.__main_container.put(self.__category_buttons, PROGRAMS_LEFT,
                                  MAIN_PADDING)

        # The back button
        self.__back_button = Gtk.Button()
        self.__back_button.set_label('<<')
        self.__back_button.connect('clicked', self.__clicked_back_button)
        self.__back_button.set_size_request(BACK_BUTTON_WIDTH, -1)
        self.__main_container.put(self.__back_button, BACK_BUTTON_X,
                                  BACK_BUTTON_Y)

        # The search box

        # filter unwanted characters from queries
        self.__translation_table = \
            dict.fromkeys(map(ord, "*^?{[]}/\\_+=\"\'#%&()'`@$<>|~"),
                          None)

        self.__search = Gtk.SearchEntry()
        self.__search.set_size_request(SEARCH_WIDTH, SEARCH_HEIGHT)
        self.__search.set_max_length(10)  # you won't need more than this
        self.__search_changed_signal = \
            self.__search.connect('changed', self.__do_search)
        self.__search_keypress_signal = \
            self.__search.connect('key-press-event', self.__search_keypress)
        self.__search.set_placeholder_text(
            utils.localize(STRINGS['search_placeholder'],
                           self.__settings.language))
        self.__main_container.put(
            self.__search,
            PROGRAMS_LEFT + PROGRAMS_WIDTH - SEARCH_WIDTH - MAIN_PADDING,
            MAIN_PADDING)

        # Menu label and description
        self.__menu_title = Gtk.Label()
        self.__menu_title.set_size_request(PROGRAMS_WIDTH, -1)
        self.__menu_title.set_ellipsize(Pango.EllipsizeMode.END)
        self.__menu_title.set_justify(Gtk.Justification.CENTER)
        self.__menu_title.set_alignment(0.0, 0.0)
        self.__menu_title.set_use_markup(True)
        self.__main_container.put(
            self.__menu_title,
            BACK_BUTTON_X + BACK_BUTTON_WIDTH + MAIN_PADDING,
            BACK_BUTTON_Y + 3)

        # The main programs list
        self.__programs_container = Gtk.ScrolledWindow()
        self.__programs_container.set_size_request(PROGRAMS_WIDTH,
                                                   PROGRAMS_HEIGHT)
        self.__programs_container.set_policy(Gtk.PolicyType.NEVER,
                                             Gtk.PolicyType.AUTOMATIC)
        self.__programs_container.set_shadow_type(Gtk.ShadowType.NONE)
        self.__programs_icons = Gtk.Fixed()
        self.__programs_container.add_with_viewport(self.__programs_icons)
        self.__main_container.put(self.__programs_container, PROGRAMS_LEFT,
                                  PROGRAMS_TOP)

        # Placeholder for empty categories, menus and search results
        self.__empty = Gtk.Label()
        self.__empty.set_size_request(PROGRAMS_WIDTH, PROGRAMS_HEIGHT)
        self.__empty.set_use_markup(True)
        self.__empty.set_justify(Gtk.Justification.CENTER)
        self.__empty.set_alignment(0.5, 0.5)
        self.__main_container.put(self.__empty, PROGRAMS_LEFT, PROGRAMS_TOP)

        # Faves list
        self.__faves_sep = Gtk.Separator(
            orientation=Gtk.Orientation.HORIZONTAL)
        self.__faves_sep.set_size_request(PROGRAMS_WIDTH, 1)
        self.__main_container.put(
            self.__faves_sep, PROGRAMS_LEFT,
            PROGRAMS_TOP + PROGRAMS_HEIGHT + MAIN_PADDING)

        self.__faves = faves.FavesList(self, self.__settings)
        self.__faves.set_size_request(PROGRAMS_WIDTH,
                                      PROGRAM_BUTTON_HEIGHT + 2)
        self.__main_container.put(self.__faves, PROGRAMS_LEFT, FAVES_TOP)

        # ----------------------------------------------------------------------
        # The sidebar: the user avatar, buttons, host infos

        utils_gui.create_separator(container=self.__main_container,
                                   x=SIDEBAR_LEFT - MAIN_PADDING,
                                   y=MAIN_PADDING,
                                   w=1,
                                   h=WINDOW_HEIGHT - (MAIN_PADDING * 2),
                                   orientation=Gtk.Orientation.VERTICAL)

        self.__sidebar = sidebar.Sidebar(self, self.__settings)

        self.__main_container.put(self.__sidebar.container, SIDEBAR_LEFT,
                                  SIDEBAR_TOP)

        # ----------------------------------------------------------------------
        # Setup GTK signal handlers

        # Listen for Esc keypresses for manually hiding the window
        self.__main_keypress_signal = \
            self.connect('key-press-event', self.__check_for_esc)

        self.__focus_signal = None

        if not self.__settings.autohide:
            # Keep the window on top of everything and show it
            self.set_visible(True)
            self.set_keep_above(True)
        else:
            # In auto-hide mode, hide the window when it loses focus
            self.enable_out_of_focus_hide()

        self.__search.connect('focus-out-event', self.__search_out)

        # ----------------------------------------------------------------------
        # UI done

        self.add(self.__main_container)
        self.__main_container.show()

        # DO NOT CALL self.show_all() HERE, the window has hidden elements
        # that are shown/hidden on demand. And we don't even have any
        # menu data yet to show.

        end_time = time.clock()
        utils.log_elapsed_time('Window init time', start_time, end_time)

        # ----------------------------------------------------------------------
        # Load menu data

        # Finally, load the menu data and show the UI
        self.load_menu_data()

        # This is a bad, bad situation that should never happen in production.
        # It will happen one day.
        if self.menudata is None or len(self.menudata.programs) == 0:
            if self.__settings.prod_mode:
                self.__show_empty_message(STRINGS['menu_no_data_at_all_prod'])
            else:
                self.__show_empty_message(STRINGS['menu_no_data_at_all_dev'])
コード例 #19
0
ファイル: buttons.py プロジェクト: Peeveli/puavo-os
    def __init__(self,
                 parent,
                 settings,
                 label,
                 icon=None,
                 tooltip=None,
                 data=None,
                 is_fave=False,
                 is_installer=False,
                 enable_popup=True):

        super().__init__(parent, settings, label, icon, tooltip, data)

        self.is_fave = is_fave

        # Need this for localize()
        self.__language = settings.language

        if settings.desktop_dir is None:
            self.__have_desktop_dir = False
        else:
            self.__have_desktop_dir = True

        # Setup the popup menu
        self.__enable_popup = enable_popup
        self.__popup_hover = False
        self.__popup_open = False
        self.__hover_signal = None

        # Setup "installer" buttons
        self.__is_installer = is_installer

        if self.__is_installer:
            # No popup menus for installers, they are not going to work
            # from the panel or the desktop...
            self.__enable_popup = False

            # UGLY UGLY UGLY
            color = '#888' if settings.dark_theme else '#444'

            markup = '{0}\n<span foreground="{1}"><i><small>[{2}]</small></i></span>' \
                     .format(label,
                             color,
                             utils.localize(STRINGS['button_puavopkg_installer_suffix'],
                                            settings.language))

            self.label_layout.set_markup(markup)

            self.set_property('tooltip-text',
                utils.localize(STRINGS['button_puavopkg_installer_tooltip'], settings.language))

        self.__menu = None
        self.__menu_signal = self.connect('button-press-event',
                                          self.open_menu)

        # We want mouse motion events
        self.set_events(self.get_events()
                        | Gdk.EventMask.POINTER_MOTION_MASK)

        # Setup the popup indicator box. Compute its coordinates.
        self.__indicator_x1 = PROGRAM_BUTTON_WIDTH - self.INDICATOR_WIDTH - self.INDICATOR_EDGE
        self.__indicator_x2 = self.__indicator_x1 + self.INDICATOR_WIDTH
        self.__indicator_y1 = self.INDICATOR_EDGE
        self.__indicator_y2 = self.__indicator_y1 + self.INDICATOR_HEIGHT
コード例 #20
0
ファイル: substates.py プロジェクト: JacksonDCollins/JBot
    def step(self, tick):
        # if self.target == self.master.ball.location:
        # 	self.master.ball.step(tick)
        # 	self.target = self.master.ball.location

        # if self.agent.team == 0: print(utils.steer(self.target, self.car), utils.angle2D(self.target, self.car), self.target.tuple, self.car.location.tuple)

        # self.controls.yaw = utils.steer(self.target, self.car)
        self.controls.throttle, self.controls.boost = utils.throttle(
            self.car, self.speed)

        turn_radius = utils.turn_radius(self.car, self.target)
        angle_to_target = utils.angle2D(self.target, self.car)

        point = utils.point_on_circle(self.car,
                                      utils.sign(angle_to_target) * math.pi /
                                      2, turn_radius)  #, self.car.rotation)
        circle = []
        for i in range(0, 366, 6):
            n = utils.point_on_circle(point, math.radians(i),
                                      turn_radius)  #, point.rotation)
            circle.append(n.tuple)
        self.agent.renderer.draw_polyline_3d(circle, self.agent.renderer.red())

        # ball_prediction = self.agent.get_ball_prediction_struct()
        # if ball_prediction is not None:
        # 	# for i in range(0, ball_prediction.num_slices):
        # 	if self.target == self.master.ball.location:
        # 		self.target = structs.Vector3(ball_prediction.slices[10].physics.location)
        # 		turn_radius = utils.turn_radius(self.car, self.target)

        # goal_to_ball_uv = (self.agent.game_info.their_goal.location - self.agent.game_info.ball.location).normalize()
        # yaw = math.atan2(goal_to_ball_uv.x, goal_to_ball_uv.z) #math.atan((goal_to_ball_uv.x/(-goal_to_ball_uv.y)))#
        # pitch = 0#math.atan(math.hypot(goal_to_ball_uv.x, goal_to_ball_uv.y)/goal_to_ball_uv.z)

        # target_ang = structs.Rotator(pitch, yaw, 0)

        # circle_point = utils.point_on_circle(self.target, math.pi/2, turn_radius, target_ang)
        # circle = []
        # for i in range(0, 366, 6):
        # 	n = utils.point_on_circle(circle_point, math.radians(i), turn_radius)
        # 	circle.append(n.tuple)
        # self.agent.renderer.draw_polyline_3d(circle, self.agent.renderer.black())

        # x1 = point.x
        # y1 = point.y
        # x2 = circle_point.x
        # y2 = circle_point.y

        # gamma = -math.atan((y2-y1)/(x2-x1))
        # beta = math.asin((turn_radius-turn_radius)/math.sqrt((x2-x1)**2 + (y2-y1)**2))
        # alpha = gamma-beta

        # x3 = x1 - turn_radius*math.cos((math.pi/2)-alpha)
        # y3 = y1 - turn_radius*math.sin((math.pi/2)-alpha)
        # x4 = x2 + turn_radius*math.cos((math.pi/2)-alpha)
        # y4 = y2 + turn_radius*math.sin((math.pi/2)-alpha)

        # tang1 = structs.Vector3(x3, y3, 100)
        # tang2 = structs.Vector3(x4, y4, 100)

        # if self.last_target_ang != target_ang:
        # 	print('ye')
        # 	self.cur_hit = 0
        # 	self.last_target_ang = target_ang

        # self.to_hit = [tang1, tang2, self.agent.game_info.ball.location]

        # self.agent.renderer.draw_rect_3d(self.to_hit[0].tuple, 20, 20, True, self.agent.renderer.black())
        # self.agent.renderer.draw_rect_3d(self.to_hit[1].tuple, 20, 20, True, self.agent.renderer.black())

        # point_to_target = utils.distance2D(self.target, point)
        # if point_to_target < turn_radius:
        # 	#inside circle
        # 	if abs(utils.angle2D(self.target, self.car)) < math.pi/2:
        # 		to_target = utils.localize(self.target, self.car).normalize(turn_radius)
        # 		self.target = self.car.location - to_target
        # 		self.controls.boost = 0
        # 		self.controls.throttle = 0
        # 	else:
        # 		to_target = utils.localize(self.target, self.car).normalize(turn_radius)
        # 		self.target = self.car.location - to_target
        # 		self.controls.boost = 0
        # 		self.controls.handbrake = 1

        # point2 = structs.Vector3(x,y,z)

        # self.agent.renderer.draw_rect_3d(point.tuple, 10, 10, True, self.agent.renderer.blue())

        if isinstance(self.master, states.quickShoot):
            if self.path:
                if not self.path.on_path(self.car.location):
                    # self.path = None
                    print('yes')
                else:
                    curvetarget = self.path.evaluate(0.1)
                    curvetarget = structs.Vector3(curvetarget[0],
                                                  curvetarget[1], 0)
                    self.controls.steer = utils.steer(curvetarget, self.car)
                    self.agent.renderer.draw_rect_3d(
                        curvetarget.tuple, 10, 10, True,
                        self.agent.renderer.blue())
            if not self.path:
                b_prediction = self.agent.get_ball_prediction_struct()

                target = utils.find_point_on_line(
                    self.agent.game_info.their_goal.location, self.target,
                    -.05)
                self.path = structs.Path(self.agent, [
                    self.car.location,
                    utils.point_on_circle(self.car, 0, 500), 'TP', target,
                    self.target
                ], utils.sign(angle_to_target), self.car.rotation, self.car)

                angletotarget = utils.map(
                    abs(utils.angle2D(self.target, self.car)), 0, math.pi, 0,
                    math.pi)
                curvetarget = self.path.evaluate(0.1)
                curvetarget = structs.Vector3(curvetarget[0], curvetarget[1],
                                              0)
                self.agent.renderer.draw_rect_3d(curvetarget.tuple, 10, 10,
                                                 True,
                                                 self.agent.renderer.blue())

                self.controls.steer = utils.steer(curvetarget, self.car)

        elif utils.distance2D(point, self.target) < turn_radius:
            to_target = utils.localize(self.target,
                                       self.car).normalize(turn_radius)
            self.target = self.car.location - to_target
            self.controls.boost = False
            self.controls.steer = utils.steer(self.target, self.car)

        else:
            self.controls.steer = utils.steer(self.target, self.car)

        if self.path:
            # print(self.path.on_path(self.car.location))
            self.agent.renderer.draw_polyline_3d(
                self.path.get_path_points(np.linspace(0, 1.0, 100)),
                self.agent.renderer.green())
        self.agent.renderer.draw_rect_3d(self.target.tuple, 10, 10, True,
                                         self.agent.renderer.red())
        self.agent.renderer.draw_line_3d(self.car.location.flatten().tuple,
                                         self.target.flatten().tuple,
                                         self.agent.renderer.green())

        self.expired = True
        return self.controls
コード例 #21
0
ファイル: loader.py プロジェクト: lacostej/puavo-os
def __parse_yml_string(string, lang_id, conditions):
    """Loads menu data from YAML data stored in a string."""

    import yaml

    programs = {}
    menus = {}
    categories = {}

    # use safe_load(), it does not attempt to construct Python classes
    data = yaml.safe_load(string)

    if data is None or not isinstance(data, dict):
        logger.warn('__parse_yml_string(): string produced no data, or the '
                    'data is not a dict')
        return programs, menus, categories

    # data.get('xxx', []) will fail if the list following the key is
    # empty, returning None and crashing the program.
    if data.get('programs') is None:
        data['programs'] = []

    if data.get('menus') is None:
        data['menus'] = []

    if data.get('categories') is None:
        data['categories'] = []

    # --------------------------------------------------------------------------
    # Parse programs

    for i in data['programs']:
        status, name, params = __convert_yaml_node(i)

        if not status:
            continue

        if not __is_valid(name):
            logger.error('Program name "{0}" contains invalid characters, '
                         'ignoring'.format(name))
            continue

        if name in programs:
            logger.warn('Program "{0}" defined multiple times, ignoring '
                        'duplicates'.format(name))
            continue

        # "Reserve" the name so it's used even if we can't parse this
        # program definition, otherwise duplicate entries might slip
        # through
        programs[name] = None

        # Figure out the type
        prog_type = params.get('type', 'desktop')

        if prog_type not in ('desktop', 'custom', 'web'):
            logger.error('Unknown program type "{0}" for "{1}", '
                         'ignoring definition'.format(prog_type, name))
            continue

        p = Program()

        if prog_type == 'desktop':
            p.type = PROGRAM_TYPE_DESKTOP
        elif prog_type == 'custom':
            p.type = PROGRAM_TYPE_CUSTOM
        else:
            p.type = PROGRAM_TYPE_WEB

        p.name = name

        # Conditionally hidden?
        if 'condition' in params and \
                __is_hidden(conditions, params['condition'], name):
            p.hidden = True
            programs[name] = p
            continue

        # Load common parameters
        if 'name' in params:
            p.title = localize(params['name'], lang_id)

            if __is_empty(p.title):
                logger.error('Empty name given for "{0}"'.format(name))
                p.title = None

        if 'description' in params:
            p.description = localize(params['description'], lang_id)

            if __is_empty(p.description):
                logger.warn(
                    'Ignoring empty description for program "{0}"'.format(
                        name))
                p.description = None

        if 'icon' in params:
            p.icon = str(params['icon'])

            if __is_empty(p.icon):
                logger.warn('Ignoring empty icon for "{0}"'.format(name))
                p.icon = None

        p.keywords = __parse_list(params.get('keywords', []))

        # Some per-type additional checks
        if p.type in (PROGRAM_TYPE_CUSTOM, PROGRAM_TYPE_WEB):
            if p.title is None:
                logger.error('Custom program/web link "{0}" has no name at '
                             'all, ignoring definition'.format(name))
                continue

            if p.icon is None:
                # this isn't fatal, it just looks really ugly
                logger.warn('Custom program/web link "{0}" is missing an '
                            'icon definition'.format(name))

        # Load type-specific parameters
        if p.type == PROGRAM_TYPE_DESKTOP:
            if 'command' in params:
                # allow overriding of the "Exec" definition
                p.command = str(params['command'])

                if __is_empty(p.command):
                    logger.warn('Ignoring empty command override for desktop '
                                'program "{0}"'.format(name))
                    p.command = None

        elif p.type == PROGRAM_TYPE_CUSTOM:
            if 'command' not in params or __is_empty(params['command']):
                logger.error(
                    'Custom program "{0}" has no command defined'
                    '(or it\'s empty), ignoring command definition'.format(
                        name))
                continue

            p.command = str(params['command'])

        elif p.type == PROGRAM_TYPE_WEB:
            if ('url' not in params) or __is_empty(params['url']):
                logger.error('Web link "{0}" has no URL defined (or it\'s '
                             'empty), ignoring link definition'.format(name))
                continue

            p.command = str(params['url'])

        # Actually use the reserved slot
        programs[name] = p

    # --------------------------------------------------------------------------
    # Parse menus

    for i in data['menus']:
        status, name, params = __convert_yaml_node(i)

        if not status:
            continue

        if not __is_valid(name):
            logger.error('Menu name "{0}" contains invalid characters, '
                         'ignoring'.format(name))
            continue

        if name in menus:
            logger.error('Menu "{0}" defined multiple times, ignoring '
                         'duplicates'.format(name))
            continue

        # Like programs, reserve the name to prevent duplicates
        menus[name] = None

        m = Menu()
        m.name = name

        # Conditionally hidden?
        if 'condition' in params and \
                __is_hidden(conditions, params['condition'], name):
            m.hidden = True
            menus[name] = m
            continue

        m.title = localize(params.get('name', ''), lang_id)

        if __is_empty(m.title):
            logger.error(
                'Menu "{0}" has no name at all, menu ignored'.format(name))
            continue

        if 'description' in params:
            m.description = localize(params['description'], lang_id)

            if __is_empty(m.description):
                logger.warn(
                    'Ignoring empty description for menu "{0}"'.format(name))
                m.description = None

        if 'icon' in params:
            m.icon = str(params['icon'])

        if __is_empty(m.icon):
            logger.warn('Menu "{0}" has a missing/empty icon'.format(name))
            m.icon = None

        m.programs = __parse_list(params.get('programs', []))

        if __is_empty(m.programs):
            logger.warn(
                'Menu "{0}" has no programs defined for it at all'.format(
                    name))
            m.programs = []

        # Actually use the reserved slot
        menus[name] = m

    # --------------------------------------------------------------------------
    # Parse categories

    for i in data['categories']:
        status, name, params = __convert_yaml_node(i)

        if not status:
            continue

        if not __is_valid(name):
            logger.error('Category name "{0}" contains invalid characters, '
                         'ignoring'.format(name))
            continue

        if name in categories:
            logger.error('Category "{0}" defined multiple times, ignoring '
                         'duplicates'.format(name))
            continue

        # Again reserve the name to prevent duplicates
        categories[name] = None

        c = Category()
        c.name = name

        if 'condition' in params and \
                __is_hidden(conditions, params['condition'], name):
            c.hidden = True
            categories[name] = c
            continue

        c.title = localize(params.get('name', ''), lang_id)

        if __is_empty(c.title):
            logger.error('Category "{0}" has no name at all, '
                         'category ignored'.format(name))
            continue

        if 'position' in params:
            try:
                c.position = int(params['position'])
            except ValueError:
                logger.warn('Cannot interpret "{0}" as a position for '
                            'category "{1}", defaulting to 0'.format(
                                params["position"], name))
                c.position = 0

        c.menus = __parse_list(params.get('menus', []))
        c.programs = __parse_list(params.get('programs', []))

        if __is_empty(c.menus) and __is_empty(c.programs):
            logger.warn('Category "{0}" has no menus or programs defined '
                        'for it at all'.format(name))

        # Actually use the reserved slot
        categories[name] = c

    return programs, menus, categories
コード例 #22
0
    def __clicked_sidebar_button(self, button):
        try:
            command = button.data
            arguments = command.get('args', '')

            # Support plain strings and arrays of strings as arguments
            if isinstance(arguments, list):
                arguments = ' '.join(arguments).strip()

            if len(arguments) == 0:
                logging.error('Sidebar button without a command!')
                self.__parent.error_message(
                    'Nothing to do',
                    'This button has no commands associated with it.')
                return

            self.__parent.autohide()

            # Expand variables
            if command.get('have_vars', False):
                arguments = utils.expand_variables(arguments, self.__variables)

            logging.debug('Sidebar button arguments: "%s"', arguments)

            if command['type'] == 'command':
                logging.info('Executing a command')
                Gio.AppInfo.create_from_commandline(arguments, '', 0).launch()
            elif command['type'] == 'url':
                logging.info('Opening a URL')
                Gio.AppInfo.launch_default_for_uri(arguments, None)
            elif command['type'] == 'webwindow':
                logging.info('Creating a webwindow')

                # Default settings
                title = None
                width = None
                height = None
                enable_js = False

                # Allow the window to be customized
                if 'webwindow' in command:
                    settings = command['webwindow']
                    width = settings.get('width', None)
                    height = settings.get('height', None)
                    title = settings.get('title', None)
                    enable_js = settings.get('enable_js', False)

                    if title:
                        title = utils.localize(title, self.__settings.language)

                web_window(url=arguments,
                           title=title,
                           width=width,
                           height=height,
                           enable_js=enable_js)
        except Exception as exception:
            logging.error('Could not process a sidebar button click!')
            logging.error(str(exception))
            self.__parent.error_message(
                utils.localize(STRINGS['sb_button_failed'],
                               self.__settings.language), str(exception))
コード例 #23
0
ファイル: loader.py プロジェクト: basilstotz/puavo-os
def build_menu_data(raw_programs, raw_menus, raw_categories, language):
    """Builds the actual menu data from raw menu data."""

    programs = {}
    menus = {}
    categories = {}

    # Build programs
    for menudata_id, src_prog in raw_programs.items():
        if not src_prog:
            continue

        if 'type' not in src_prog:
            logging.error(
                'Program "%s" has no type specified. '
                'This really should not happen.', menudata_id)
            continue

        dst_prog = Program()

        # Type and menudata ID. Python, why did you have to reserve
        # common words as "type" and "id" and not let me use them?
        dst_prog.program_type = src_prog['type']
        dst_prog.menudata_id = menudata_id

        # We can't actually remove hidden things. as they are referenced
        # to in menus and categories and if we remove them here, we'll
        # erroneously report them to be "broken".
        if 'hidden' in src_prog and src_prog['hidden']:
            dst_prog.hidden = True

        # Name (required)
        if 'name' in src_prog and src_prog['name']:
            dst_prog.name = utils.localize(src_prog['name'], language)

        if utils.is_empty(dst_prog.name):
            logging.error('Program "%s" has no name at all, skipping it',
                          menudata_id)
            raw_programs[menudata_id] = None
            continue

        # Description (optional), accept ONLY a localized description
        if 'description' in src_prog and src_prog['description'] and \
           language in src_prog['description']:
            dst_prog.description = \
                utils.localize(src_prog['description'], language)

        # Keywords (optional)
        if 'keywords' in src_prog and language in src_prog['keywords']:
            dst_prog.keywords = list(src_prog['keywords'][language])

        # Command (required)
        if 'command' in src_prog:
            dst_prog.command = src_prog['command']

        if utils.is_empty(dst_prog.command):
            if dst_prog.program_type == PROGRAM_TYPE_WEB:
                logging.error(
                    'Web link "%s" has an empty or missing URL, '
                    'link ignored', menudata_id)
            else:
                logging.error(
                    'Program "%s" has an empty or missing command, '
                    'program ignored', menudata_id)

            raw_programs[menudata_id] = None
            continue

        # Icon
        if 'icon' in src_prog:
            dst_prog.icon_name = src_prog['icon']

        if utils.is_empty(dst_prog.icon_name):
            logging.warning('Program "%s" has no icon defined for it',
                            menudata_id)
        else:
            # Is the icon name a full path to an icon file, or just
            # a generic name?
            _, ext = os.path.splitext(dst_prog.icon_name)

            if (not utils.is_empty(ext)) and (ext in ICON_EXTENSIONS):
                dst_prog.icon_name_is_path = True

        programs[menudata_id] = dst_prog

    # Build menus and add programs to them
    for menudata_id, src_menu in raw_menus.items():
        if not src_menu:
            continue

        dst_menu = Menu()

        dst_menu.menudata_id = menudata_id

        # Like programs, we only flag menus to be hidden
        if 'hidden' in src_menu and src_menu['hidden']:
            dst_menu.hidden = True

        # Name (required)
        if 'name' in src_menu and src_menu['name']:
            dst_menu.name = utils.localize(src_menu['name'], language)

        if utils.is_empty(dst_menu.name):
            logging.error('Menu "%s" has no name at all, skipping it',
                          menudata_id)
            raw_menus[menudata_id] = None
            continue

        # Description (optional)
        if 'description' in src_menu and src_menu['description']:
            dst_menu.description = utils.localize(src_menu['description'],
                                                  language)

        # Icon (required, but it's not fatal if it's missing)
        if 'icon' in src_menu and src_menu['icon']:
            dst_menu.icon_name = src_menu['icon']

        if utils.is_empty(dst_menu.icon_name):
            logging.warning('Menu "%s" has no icon defined for it',
                            menudata_id)

        # List of programs (required, but it's not fatal if it's empty/missing)
        had_something = False

        if 'programs' in src_menu:
            for p_name in src_menu['programs']:
                if p_name not in programs or programs[p_name] is None:
                    logging.warning(
                        'Menu "%s" references to a non-existing program "%s"',
                        menudata_id, p_name)
                    continue

                # Don't whine about an empty menu if all of it's programs
                # are hidden
                had_something = True

                # Silently ignore hidden programs
                if programs[p_name].hidden:
                    continue

                programs[p_name].used = True
                dst_menu.programs.append(programs[p_name])

        if len(dst_menu.programs) == 0 and not had_something:
            logging.warning('Menu "%s" is completely empty', menudata_id)

        menus[menudata_id] = dst_menu

    # Build categories and add menus and programs to them
    for menudata_id, src_cat in raw_categories.items():
        if not src_cat:
            continue

        if 'hidden' in src_cat and src_cat['hidden']:
            continue

        dst_cat = Category()

        dst_cat.menudata_id = menudata_id

        # Name (required)
        if 'name' in src_cat and src_cat['name']:
            dst_cat.name = utils.localize(src_cat['name'], language)

        if utils.is_empty(dst_cat.name):
            logging.error('Category "%s" has no name at all, skipping it',
                          menudata_id)
            raw_categories[menudata_id] = None
            continue

        # Description (optional)
        if 'description' in src_cat and src_cat['description']:
            dst_cat.description = utils.localize(src_cat['description'],
                                                 language)

        # List of menus and programs (technically you need at least one of
        # either, but it's not a fatal error to omit everything, it just
        # looks ugly)
        if 'menus' in src_cat:
            for m_name in src_cat['menus']:
                if m_name not in menus or menus[m_name] is None:
                    logging.warning(
                        'Category "%s" references to a non-existing menu "%s"',
                        menudata_id, m_name)
                    continue

                # Silently ignore hidden menus
                if menus[m_name].hidden:
                    continue

                menus[m_name].used = True
                dst_cat.menus.append(menus[m_name])

        if 'programs' in src_cat:
            for p_name in src_cat['programs']:
                if p_name not in programs or programs[p_name] is None:
                    logging.warning(
                        'Category "%s" references to a non-existing program "%s"',
                        menudata_id, p_name)
                    continue

                # Silently ignore hidden programs
                if programs[p_name].hidden:
                    continue

                programs[p_name].used = True
                dst_cat.programs.append(programs[p_name])

        # Position
        if 'position' in src_cat:
            try:
                dst_cat.position = int(src_cat['position'])
            except ValueError:
                logging.warning(
                    'Cannot interpret "%s" as a position for '
                    'category "%s", defaulting to 0', src_cat['position'],
                    menudata_id)
                dst_cat.position = 0

        if len(dst_cat.menus) == 0 and len(dst_cat.programs) == 0:
            logging.warning('Category "%s" is completely empty', menudata_id)

        categories[menudata_id] = dst_cat

    return programs, menus, categories
コード例 #24
0
 def show(self):
     if self._demolabel is not None:
         return
     # FIXME: Using a different font does not seem to have much of an impact
     self._demolabel = ControlLabel(0, getScreenHeight() // 4, getScreenWidth(), 100, localize(30060) + '\n' + localize(30061), font='font36_title', textColor='0xddee9922', alignment=0x00000002)
     self.window.addControl(self._demolabel)
     self.log('show', 0)