示例#1
0
 def display(self) -> None:
     html.text_input(self._varprefix + "name")
     html.br()
     html.begin_radio_group(horizontal=True)
     html.radiobutton(self._varprefix + "match",
                      "exact",
                      True,
                      label=_("exact match"))
     html.radiobutton(self._varprefix + "match",
                      "regex",
                      False,
                      label=_("regular expression, substring match"))
     html.end_radio_group()
     html.br()
     html.open_span(class_="min_max_row")
     html.write_text(_("Min. Version: "))
     html.text_input(self._varprefix + "version_from", size=9)
     html.write_text("   ")
     html.write_text(_("Max. Vers.: "))
     html.text_input(self._varprefix + "version_to", size=9)
     html.close_span()
     html.br()
     html.checkbox(
         self._varprefix + "negate",
         False,
         label=_("Negate: find hosts <b>not</b> having this package"))
示例#2
0
 def display(self, value: FilterHTTPVariables) -> None:
     html.text_input(self._varprefix + "name")
     html.br()
     display_filter_radiobuttons(
         varname=self._varprefix + "match",
         options=[
             ("exact", _("exact match")),
             ("regex", _("regular expression, substring match")),
         ],
         default="exact",
         value=value,
     )
     html.br()
     html.open_span(class_="min_max_row")
     html.write_text(_("Min.&nbsp;Version: "))
     html.text_input(
         self._varprefix + "version_from",
         default_value=value.get(self._varprefix + "version_from", ""),
         size=9,
     )
     html.write_text(" &nbsp; ")
     html.write_text(_("Max.&nbsp;Vers.: "))
     html.text_input(
         self._varprefix + "version_to",
         default_value=value.get(self._varprefix + "version_from", ""),
         size=9,
     )
     html.close_span()
     html.br()
     html.checkbox(
         self._varprefix + "negate",
         False,
         label=_("Negate: find hosts <b>not</b> having this package"),
     )
示例#3
0
    def _show_subtree(self, tree, path, show_host):
        # Check if we have an assumed state: comparing assumed state (tree[1]) with state (tree[0])
        if tree[1] and tree[0] != tree[1]:
            addclass: Optional[str] = "assumed"
            effective_state = tree[1]
        else:
            addclass = None
            effective_state = tree[0]

        is_leaf = self._is_leaf(tree)
        if is_leaf:
            leaf = "leaf"
            mc = None
        else:
            leaf = "noleaf"
            mc = self._get_mousecode(path)

        classes = [
            "bibox_box",
            leaf,
            "open" if self._is_open(path) else "closed",
            "state",
            "state%d" % effective_state["state"],
            addclass,
        ]

        omit = self._omit_root and len(path) == 1
        if not omit:
            html.open_span(
                id_="%d:%s" %
                (self._expansion_level or 0, self._path_id(path)),
                class_=classes,
                onclick=mc,
            )

            if is_leaf:
                self._show_leaf(tree, show_host)
            else:
                html.write_text(tree[2]["title"].replace(" ", "&nbsp;"))

            html.close_span()

        if not is_leaf and not self._omit_content(path):
            html.open_span(
                class_="bibox",
                style="display: none;"
                if not self._is_open(path) and not omit else "",
            )
            for node in tree[3]:
                new_path = path + [node[2]["title"]]
                self._show_subtree(node, new_path, show_host)
            html.close_span()
示例#4
0
    def _show_subtree(self, tree, path, show_host):
        if self._is_leaf(tree):
            self._show_leaf(tree, show_host)
            return

        html.open_span(class_="title")

        is_empty = len(tree[3]) == 0
        if is_empty:
            mc = None
        else:
            mc = self._get_mousecode(path)

        css_class = "open" if self._is_open(path) else "closed"

        with self._show_node(tree,
                             show_host,
                             mousecode=mc,
                             img_class=css_class):
            if tree[2].get("icon"):
                html.write_html(html.render_icon(tree[2]["icon"]))
                html.write_text("&nbsp;")

            if tree[2].get("docu_url"):
                html.icon_button(
                    tree[2]["docu_url"],
                    _("Context information about this rule"),
                    "url",
                    target="_blank",
                )
                html.write_text("&nbsp;")

            html.write_text(tree[2]["title"])

        if not is_empty:
            html.open_ul(
                id_="%d:%s" %
                (self._expansion_level or 0, self._path_id(path)),
                class_=["subtree", css_class],
            )

            if not self._omit_content(path):
                for node in tree[3]:
                    if not node[2].get("hidden"):
                        new_path = path + [node[2]["title"]]
                        html.open_li()
                        self._show_subtree(node, new_path, show_host)
                        html.close_li()

            html.close_ul()

        html.close_span()
示例#5
0
    def show(self, page_state: PageState) -> None:
        html.open_div(class_=self._get_css_classes(page_state))

        html.open_div(class_="text")

        html.open_span()
        html.span(page_state.top_line, id_="page_state_top_line")
        html.span("", id_="headinfo")
        html.close_span()

        html.span(page_state.bottom_line)
        html.close_div()

        html.open_div(class_="icon_container")
        html.icon(page_state.icon_name, id_="page_state_icon")
        html.close_div()

        html.close_div()
示例#6
0
def render_mobile_list(rows, view, group_cells, cells, num_columns,
                       show_checkboxes):
    if not html.mobile:
        html.show_error(_("This view can only be used in mobile mode."))
        return

    # Force relative timestamp always. This saves space.
    painter_options = PainterOptions.get_instance()
    painter_options.set("ts_format", "rel")

    html.open_ul(class_="mobilelist", **{"data-role": "listview"})

    # Paint data rows
    for row in rows:
        html.open_li()
        rendered_cells = [cell.render(row) for cell in cells]
        if rendered_cells:  # First cell (assumedly state) is left
            rendered_class, rendered_content = rendered_cells[0]
            html.open_p(class_=["ui-li-aside", "ui-li-desc", rendered_class])
            html.write(rendered_content)
            html.close_p()

            if len(rendered_cells) > 1:
                content = HTML(" &middot; ").join([
                    rendered_cell[1]
                    for rendered_cell in rendered_cells[1:num_columns + 1]
                ])
                html.h3(content)

                for rendered_cell, cell in zip(
                        rendered_cells[num_columns + 1:],
                        cells[num_columns + 1:]):
                    rendered_class, rendered_content = rendered_cell
                    html.open_p(class_="ui-li-desc")
                    cell.paint_as_header()
                    html.write_text(': ')
                    html.open_span(class_=rendered_class)
                    html.write(rendered_content)
                    html.close_span()
                    html.close_p()

        html.close_li()
    html.close_ul()
    html.javascript('$("ul.mobilelist a").attr("data-ajax", "false");')
示例#7
0
    def _render_headers(self, actions_enabled: bool, actions_visible: bool,
                        empty_columns: List[bool]) -> None:
        if self.options["omit_headers"]:
            return

        table_id = self.id

        html.open_tr()
        first_col = True
        for nr, header in enumerate(self.headers):
            if self.options["omit_empty_columns"] and empty_columns[nr]:
                continue

            if header.help_txt:
                header_title: Union[int, HTML, str] = html.render_span(
                    header.title, title=header.help_txt)
            else:
                header_title = header.title

            if not isinstance(header.css, list):
                css_class: CSSSpec = [header.css]
            else:
                css_class = header.css

            assert isinstance(css_class, list)
            css_class = [("header_%s" % c) for c in css_class if c is not None]

            if not self.options["sortable"] or not header.sortable:
                html.open_th(class_=css_class)
            else:
                css_class.insert(0, "sort")
                reverse = 0
                sort = html.request.get_ascii_input('_%s_sort' % table_id)
                if sort:
                    sort_col, sort_reverse = map(int, sort.split(',', 1))
                    if sort_col == nr:
                        reverse = 1 if sort_reverse == 0 else 0

                action_uri = html.makeactionuri([('_%s_sort' % table_id,
                                                  '%d,%d' % (nr, reverse))])
                html.open_th(class_=css_class,
                             title=_("Sort by %s") % header.title,
                             onclick="location.href='%s'" % action_uri)

            # Add the table action link
            if first_col:
                first_col = False
                if actions_enabled:
                    if not header_title:
                        header_title = "&nbsp;"  # Fixes layout problem with white triangle

                    if actions_visible:
                        state = '0'
                        help_txt = _('Hide table actions')
                        img = 'table_actions_on'
                    else:
                        state = '1'
                        help_txt = _('Display table actions')
                        img = 'table_actions_off'

                    html.open_div(class_=["toggle_actions"])
                    html.icon_button(html.makeuri([('_%s_actions' % table_id,
                                                    state)]),
                                     help_txt,
                                     img,
                                     cssclass='toggle_actions')
                    html.open_span()
                    html.write(header_title)
                    html.close_span()
                    html.close_div()
                else:
                    html.write(header_title)
            else:
                html.write(header_title)

            html.close_th()
        html.close_tr()
示例#8
0
    def _render_headers(self, actions_enabled, actions_visible, empty_columns):
        if self.options["omit_headers"]:
            return

        table_id = self.id

        html.open_tr()
        first_col = True
        for nr, (header, css, help_txt, sortable) in enumerate(self.headers):
            if self.options["omit_empty_columns"] and empty_columns[nr]:
                continue

            text = header

            if help_txt:
                header = '<span title="%s">%s</span>' % (
                    html.attrencode(help_txt), header)

            css_class = "header_%s" % css if css else None

            if not self.options["sortable"] or not sortable:
                html.open_th(class_=css_class)
            else:
                reverse = 0
                sort = html.request.var('_%s_sort' % table_id)
                if sort:
                    sort_col, sort_reverse = map(int, sort.split(',', 1))
                    if sort_col == nr:
                        reverse = 1 if sort_reverse == 0 else 0

                action_uri = html.makeactionuri([('_%s_sort' % table_id,
                                                  '%d,%d' % (nr, reverse))])
                html.open_th(class_=["sort", css_class],
                             title=_("Sort by %s") % text,
                             onclick="location.href='%s'" % action_uri)

            # Add the table action link
            if first_col:
                first_col = False
                if actions_enabled:
                    if not header:
                        header = "&nbsp;"  # Fixes layout problem with white triangle
                    if actions_visible:
                        state = '0'
                        help_txt = _('Hide table actions')
                        img = 'table_actions_on'
                    else:
                        state = '1'
                        help_txt = _('Display table actions')
                        img = 'table_actions_off'
                    html.open_div(class_=["toggle_actions"])
                    html.icon_button(html.makeuri([('_%s_actions' % table_id,
                                                    state)]),
                                     help_txt,
                                     img,
                                     cssclass='toggle_actions')
                    html.open_span()
                    html.write(header)
                    html.close_span()
                    html.close_div()
                else:
                    html.write(header)
            else:
                html.write(header)

            html.close_th()
        html.close_tr()
示例#9
0
    def render_snapin(self, snapin: UserSidebarSnapin) -> str:
        snapin_class = snapin.snapin_type
        name = snapin_class.type_name()
        snapin_instance = snapin_class()

        more_id = "sidebar_snapin_%s" % name

        show_more = config.user.get_show_more_setting(more_id)
        html.open_div(id_="snapin_container_%s" % name,
                      class_=["snapin", ("more" if show_more else "less")])

        self._render_snapin_styles(snapin_instance)
        # When not permitted to open/close snapins, the snapins are always opened
        if snapin.visible == SnapinVisibility.OPEN or not config.user.may(
                "general.configure_sidebar"):
            style = None
        else:
            style = "display:none"

        toggle_url = "sidebar_openclose.py?name=%s&state=" % name

        # If the user may modify the sidebar then add code for dragging the snapin
        head_actions: Dict[str, str] = {}
        if config.user.may("general.configure_sidebar"):
            head_actions = {
                "onmouseover": "document.body.style.cursor='move';",
                "onmouseout ": "document.body.style.cursor='';",
                "onmousedown": "cmk.sidebar.snapin_start_drag(event)",
                "onmouseup": "cmk.sidebar.snapin_stop_drag(event)"
            }

        html.open_div(class_=["head", snapin.visible.value], **head_actions)

        show_more = snapin_instance.has_show_more_items()
        may_configure = config.user.may("general.configure_sidebar")

        if show_more or may_configure:

            html.open_div(class_="snapin_buttons")

            if show_more:
                html.open_span(class_="moresnapin")
                html.more_button(more_id, dom_levels_up=4)
                html.close_span()

            if may_configure:
                # Button for closing (removing) a snapin
                html.open_span(class_="closesnapin")
                close_url = "sidebar_openclose.py?name=%s&state=off" % name
                html.icon_button(
                    url=None,
                    title=_("Remove this snapin"),
                    icon="close",
                    onclick="cmk.sidebar.remove_sidebar_snapin(this, '%s')" %
                    close_url)
                html.close_span()

            html.close_div()

        # The heading. A click on the heading mini/maximizes the snapin
        toggle_actions: Dict[str, str] = {}
        if config.user.may("general.configure_sidebar"):
            toggle_actions = {
                "onclick":
                "cmk.sidebar.toggle_sidebar_snapin(this,'%s')" % toggle_url,
                "onmouseover": "this.style.cursor='pointer'",
                "onmouseout": "this.style.cursor='auto'"
            }
        html.b(textwrap.shorten(snapin_class.title(),
                                width=27,
                                placeholder="..."),
               class_=["heading"],
               **toggle_actions)

        if may_configure:
            # Icon for mini/maximizing
            html.span("",
                      class_="minisnapin",
                      title=_("Toggle this snapin"),
                      onclick="cmk.sidebar.toggle_sidebar_snapin(this, '%s')" %
                      toggle_url)

        # End of header
        html.close_div()

        # Now comes the content
        html.open_div(class_="content", id_="snapin_%s" % name, style=style)
        refresh_url = ''
        try:
            # TODO: Refactor this confusing special case. Add deddicated method or something
            # to let the snapins make the sidebar know that there is a URL to fetch.
            url = snapin_instance.show()
            if url is not None:
                # Fetch the contents from an external URL. Don't render it on our own.
                refresh_url = url
                html.javascript(
                    "cmk.ajax.get_url(\"%s\", cmk.utils.update_contents, \"snapin_%s\")"
                    % (refresh_url, name))
        except Exception as e:
            logger.exception("error rendering snapin %s", name)
            write_snapin_exception(e)
        html.close_div()
        html.close_div()
        return refresh_url
示例#10
0
 def render_addto_popup_title(cls, title):
     html.open_li()
     html.open_span()
     html.write("%s:" % title)
     html.close_span()
     html.close_li()
示例#11
0
    def _show_node(self, tree, show_host, mousecode=None, img_class=None):
        # Check if we have an assumed state: comparing assumed state (tree[1]) with state (tree[0])
        if tree[1] and tree[0] != tree[1]:
            addclass: Optional[str] = "assumed"
            effective_state = tree[1]
        else:
            addclass = None
            effective_state = tree[0]

        class_: List[Optional[str]] = [
            "content",  #
            "state",
            "state%d" % (effective_state["state"] if effective_state["state"] is not None else -1),
            addclass,
        ]
        html.open_span(class_=class_)
        html.write_text(self._render_bi_state(effective_state["state"]))
        html.close_span()

        if mousecode:
            if img_class:
                html.img(
                    src=theme.url("images/tree_closed.svg"),
                    class_=["treeangle", img_class],
                    onclick=mousecode,
                )

            html.open_span(class_=["content", "name"])

        icon_name, icon_title = None, None
        if tree[0]["in_downtime"] == 2:
            icon_name = "downtime"
            icon_title = _("This element is currently in a scheduled downtime.")

        elif tree[0]["in_downtime"] == 1:
            # only display host downtime if the service has no own downtime
            icon_name = "derived_downtime"
            icon_title = _("One of the subelements is in a scheduled downtime.")

        if tree[0]["acknowledged"]:
            icon_name = "ack"
            icon_title = _("This problem has been acknowledged.")

        if not tree[0]["in_service_period"]:
            icon_name = "outof_serviceperiod"
            icon_title = _("This element is currently not in its service period.")

        if icon_name and icon_title:
            html.icon(icon_name, title=icon_title, class_=["icon", "bi"])

        yield

        if mousecode:
            if str(effective_state["state"]) in tree[2].get("state_messages", {}):
                html.b(HTML("&diams;"), class_="bullet")
                html.write_text(tree[2]["state_messages"][str(effective_state["state"])])

            html.close_span()

        output: HTML = cmk.gui.view_utils.format_plugin_output(
            effective_state["output"], shall_escape=config.escape_plugin_output
        )
        if output:
            output = html.render_b(HTML("&diams;"), class_="bullet") + output
        else:
            output = HTML()

        html.span(output, class_=["content", "output"])