def _render_tag_group(tg_id, tag, object_type, with_link, label_type, label_source): span = html.render_tag(html.render_div( html.render_span("%s:%s" % (tg_id, tag), class_=["tagify__tag-text"])), class_=["tagify--noAnim", label_source]) if not with_link: return span if label_type == "tag_group": type_filter_vars = [ ("%s_tag_0_grp" % object_type, tg_id), ("%s_tag_0_op" % object_type, "is"), ("%s_tag_0_val" % object_type, tag), ] elif label_type == "label": type_filter_vars = [ ("%s_label" % object_type, json.dumps([{ "value": "%s:%s" % (tg_id, tag) }]).decode("utf-8")), ] else: raise NotImplementedError() url = html.makeuri_contextless([ ("filled_in", "filter"), ("search", "Search"), ("view_name", "searchhost" if object_type == "host" else "searchsvc"), ] + type_filter_vars, filename="view.py") return html.render_a(span, href=url)
def list_logs(site, host_name, logfile_names): with table_element(empty_text=_("No logs found for this host.")) as table: for file_name in logfile_names: table.row() file_display = form_file_to_ext(file_name) uri = makeuri(request, [('site', site), ('host', host_name), ('file', file_display)]) logfile_link = html.render_a(file_display, href=uri) try: log_chunks = parse_file(site, host_name, file_name) if not log_chunks: continue # Logfile vanished worst_log = get_worst_chunk(log_chunks) last_log = get_last_chunk(log_chunks) state = worst_log['level'] state_name = form_level(state) table.cell(_("Level"), state_name, css="state%d" % state) table.cell(_("Logfile"), logfile_link) table.cell(_("Last Entry"), form_datetime(last_log['datetime'])) table.cell(_("Entries"), len(log_chunks), css="number") except Exception: if config.debug: raise table.cell(_("Level"), "") table.cell(_("Logfile"), logfile_link) table.cell(_("Last Entry"), "") table.cell(_("Entries"), _("Corrupted"))
def paint_aggr_hosts(row, link_to_view): h = [] for site, host in row["aggr_hosts"]: url = html.makeuri([("view_name", link_to_view), ("site", site), ("host", host)]) h.append(html.render_a(host, url)) return "", HTML(" ").join(h)
def _pnp_icon(self, row, what): url = self._pnp_graph_icon_link(row, what) if not metrics.cmk_graphs_possible(row["site"]): # Directly ask PNP for all data, don't try to use the new graph fetching mechanism # to keep the number of single requests low force_pnp_graphing = True else: # Don't show the icon with Check_MK graphing. The hover makes no sense and there is no # mobile view for graphs, so the graphs on the bottom of the host/service view are enough # for the moment. if html.is_mobile(): return force_pnp_graphing = False return html.render_a( content=html.render_icon('pnp', ''), href=url, onmouseout="cmk.hover.hide()", onmouseover="cmk.graph_integration.show_hover_graphs(event, %s, %s, %s, %s, %s);" % ( json.dumps(row['site']), json.dumps(row["host_name"]), json.dumps(row.get('service_description', '_HOST_')), json.dumps(self._pnp_popup_url(row, what)), json.dumps(force_pnp_graphing), ))
def _limit_labels(self, labels): show_all, limit = HTML(""), 3 if len(labels) > limit and html.request.var("_show_all") != "1": show_all = HTML(" ") + html.render_a("... (%s)" % _("show all"), href=makeuri(global_request, [("_show_all", "1")])) labels = dict(sorted(labels.items())[:limit]) return labels, show_all
def _render_tag_tree_level(self, tree_spec, path, cwd, title, tree) -> None: if not self._is_tag_subdir( path=path, cwd=cwd) and not self._is_tag_subdir(path=cwd, cwd=path): return container: ContextManager[bool] = nullcontext(False) if path != cwd and self._is_tag_subdir(path, cwd): bullet = self._tag_tree_bullet(self._tag_tree_worst_state(tree), path, False) if self._tag_tree_has_svc_problems(tree): bullet += html.render_icon_button( self._tag_tree_url(tree_spec, path, "svcproblems"), _("Show the service problems contained in this branch"), "svc_problems", target="main", ) if path: container = foldable_container( treename="tag-tree", id_=".".join(map(str, path)), isopen=False, title=bullet + title, icon="foldable_sidebar", ) with container: for (node_title, node_value), subtree in sorted( tree.get("_children", {}).items()): subpath = path + [node_value or ""] url = self._tag_tree_url(tree_spec, subpath, "allhosts") if "_num_hosts" in subtree: node_title += " (%d)" % subtree["_num_hosts"] node_title = html.render_a(node_title, href=url, target="main") if "_children" not in subtree: if self._is_tag_subdir(path, cwd): html.write_html( self._tag_tree_bullet(subtree.get("_state", 0), subpath, True)) if subtree.get("_svc_problems"): url = self._tag_tree_url(tree_spec, subpath, "svcproblems") html.icon_button( url, _("Show the service problems contained in this branch" ), "svc_problems", target="main", ) html.write_html(node_title) html.br() else: self._render_tag_tree_level(tree_spec, subpath, cwd, node_title, subtree)
def render_object_ref( object_ref: Optional[ObjectRef]) -> Union[str, HTML, None]: url, title = _get_object_reference(object_ref) if title and not url: return title if not title: return None return html.render_a(title, href=url)
def _get_rendered_metric_value(self, metric, render_options, tooltip_titles, service_url): rendered_value = metric["unit"]["render"](metric["value"]) if render_options["show_unit"] != "true": rendered_value = " ".join(rendered_value.split()[:-1]) return html.render_a( content=rendered_value, href=service_url if render_options["link_to_svc_detail"] == "true" else "", title=", ".join(tooltip_titles) if tooltip_titles else "")
def paint(self, value, hostname): parts = [ html.render_a( hn, "wato.py?" + html.urlencode_vars([("mode", "edit_host"), ("host", hn)])) for hn in value ] return "", HTML(", ").join(parts)
def _limit_labels(self, labels): show_all, limit = "", 3 if len(labels) > limit and html.request.var("_show_all") != "1": show_all = " %s" % html.render_a("... (%s)" % _("show all"), href=html.makeuri( [("_show_all", "1")])) labels = dict(sorted(labels.items())[:limit]) return labels, show_all
def text_with_links_to_user_translated_html( elements: Iterable[Tuple[str, Optional[str]]], separator: str = "", ) -> HTML: return HTML(separator).join( html.render_a(user_translation, href=url ) if url else escape_html_permissive(user_translation) for txt, url in elements for user_translation in [_u(txt)] if txt)
def _make_wato_page_state() -> PageState: changes_info = get_pending_changes_info() return PageState( top_line=changes_info or _("No pending changes"), bottom_line=html.render_a(_("View changes"), href="wato.py?mode=changelog"), icon_name="wato_changes" if changes_info else "wato_nochanges", )
def page(self): with table_element("roles") as table: users = userdb.load_users() for rid, role in sorted(self._roles.items(), key=lambda a: (a[1]["alias"], a[0])): table.row() # Actions table.cell(_("Actions"), css="buttons") edit_url = watolib.folder_preserving_link([("mode", "edit_role"), ("edit", rid)]) clone_url = make_action_link([("mode", "roles"), ("_clone", rid)]) delete_url = make_confirm_link( url=make_action_link([("mode", "roles"), ("_delete", rid)]), message=_("Do you really want to delete the role %s?") % rid, ) html.icon_button(edit_url, _("Properties"), "edit") html.icon_button(clone_url, _("Clone"), "clone") if not role.get("builtin"): html.icon_button(delete_url, _("Delete this role"), "delete") # ID table.cell(_("Name"), rid) # Alias table.cell(_("Alias"), role["alias"]) # Type table.cell( _("Type"), _("builtin") if role.get("builtin") else _("custom")) # Modifications table.cell( _("Modifications"), html.render_span( str(len(role["permissions"])), title= _("That many permissions do not use the factory defaults." ))) # Users table.cell( _("Users"), HTML(", ").join([ html.render_a( user.get("alias", user_id), watolib.folder_preserving_link([ ("mode", "edit_user"), ("edit", user_id) ])) for (user_id, user) in users.items() if rid in user["roles"] ]))
def show(self): host, service = self._dashlet_spec["context"].values() metric = self._dashlet_spec["metric"] if "metric" in self._dashlet_spec else "" site = self._get_site_by_host_name(host) metric_spec = {"site": site, "host": host, "service": service, "metric": metric} svc_url = "view.py?view_name=service&site=%s&host=%s&service=%s" % ( html.urlencode(site), html.urlencode(host), html.urlencode(service)) links = { "site": html.render_a(site, "view.py?view_name=sitehosts&site=%s" % (html.urlencode(site))), "host": html.render_a( host, "view.py?view_name=host&site=%s&host=%s" % (html.urlencode(site), html.urlencode(host))), "service": html.render_a(service, svc_url) } render_options = self._dashlet_spec["metric_render_options"] metrics = self._query_for_metrics_of_host(site, host, service) t_metrics = self._get_translated_metrics_from_perf_data(metrics) chosen_metric_name, metric_choices = self._get_chosen_metric(t_metrics, metric) svc_state = metrics["svc_state"] html.open_div(class_="metric") if metrics: if chosen_metric_name: chosen_metric = t_metrics[chosen_metric_name] titles = self._get_titles(metric_spec, links, render_options) self._render_metric_content(chosen_metric, render_options, titles, svc_state, svc_url) else: html.open_div(class_="no_metric_match") if metric_choices: # TODO: Fix this handling of no available/matching metric # after the implementation of host/site contexts warning_txt = _("The given metric \"%s\" could not be found.\ For the selected service \"%s\" you can choose from the following metrics:" % (metric, service)) warning_txt += html.render_ul("".join( [str(html.render_li(b)) for _a, b in metric_choices])) html.show_warning(warning_txt) else: html.show_warning(_("No metric could be found.")) html.close_div() else: html.show_warning(_("There are no metrics meeting your context filters.")) html.close_div()
def _render_rule_reason(self, title, title_url, reason, reason_url, is_default, setting): if title_url: title = html.render_a(title, href=title_url) forms.section(title) if reason: reason = html.render_a(reason, href=reason_url) html.open_table(class_="setting") html.open_tr() if is_default: html.td(html.render_i(reason), class_="reason") html.td(setting, class_=["settingvalue", "unused"]) else: html.td(reason, class_="reason") html.td(setting, class_=["settingvalue", "used"]) html.close_tr() html.close_table()
def render(self, row, cell): url = html.makeuri_contextless( [ ("crash_id", row["crash_id"]), ("site", row["site"]), ], filename="crash.py", ) return (None, html.render_a(row["crash_id"], href=url))
def query_limit_exceeded_warn(limit: Optional[int], user_config: 'LoggedInUser') -> None: """Compare query reply against limits, warn in the GUI about incompleteness""" text = HTML(_("Your query produced more than %d results. ") % limit) if html.request.get_ascii_input( "limit", "soft") == "soft" and user_config.may("general.ignore_soft_limit"): text += html.render_a(_('Repeat query and allow more results.'), target="_self", href=makeuri(request, [("limit", "hard")])) elif html.request.get_ascii_input("limit") == "hard" and user_config.may( "general.ignore_hard_limit"): text += html.render_a(_('Repeat query without limit.'), target="_self", href=makeuri(request, [("limit", "none")])) text += " " + _( "<b>Note:</b> the shown results are incomplete and do not reflect the sort order.") html.show_warning(text)
def _render_tag_tree_level(self, tree_spec, path, cwd, title, tree): if (not self._is_tag_subdir(path=path, cwd=cwd) and not self._is_tag_subdir(path=cwd, cwd=path)): return if path != cwd and self._is_tag_subdir(path, cwd): bullet = self._tag_tree_bullet(self._tag_tree_worst_state(tree), path, False) if self._tag_tree_has_svc_problems(tree): bullet += html.render_icon_button( self._tag_tree_url(tree_spec, path, "svcproblems"), _("Show the service problems contained in this branch"), "svc_problems", target="main") if path: html.begin_foldable_container( "tag-tree", ".".join(map(str, path)), False, HTML(bullet + title), icon="foldable_sidebar", ) for (node_title, node_value), subtree in sorted(tree.get("_children", {}).items()): subpath = path + [node_value or ""] url = self._tag_tree_url(tree_spec, subpath, "allhosts") if "_num_hosts" in subtree: node_title += " (%d)" % subtree["_num_hosts"] node_title = html.render_a(node_title, href=url, target="main") if "_children" not in subtree: if self._is_tag_subdir(path, cwd): html.write( self._tag_tree_bullet(subtree.get("_state", 0), subpath, True)) if subtree.get("_svc_problems"): url = self._tag_tree_url(tree_spec, subpath, "svcproblems") html.icon_button( url, _("Show the service problems contained in this branch" ), "svc_problems", target="main") html.write(node_title) html.br() else: self._render_tag_tree_level(tree_spec, subpath, cwd, node_title, subtree) if path and path != cwd and self._is_tag_subdir(path, cwd): html.end_foldable_container()
def _tag_tree_bullet(self, state, path, leaf) -> HTML: code = html.render_div( " ", class_=["tagtree", "leafstatebullet" if leaf else "statebullet", "state%d" % state]) if not leaf: code += html.render_a(code, href="javascript:virtual_host_tree_enter('%s');" % "|".join(path), title=_("Display the tree only below this node")) return code + " "
def render_html_graph_title(graph_artwork, graph_render_options): title = HTML(" / ").join([ (html.render_a(txt, href=url) if url else txt) for txt, url in _render_graph_title_elements(graph_artwork, graph_render_options) ]) if title: return html.render_div( title, class_=["title", "inline" if graph_render_options["show_title"] == "inline" else None]) return ""
def _show_row_cells(self, table, name, group): super(ModeContactgroups, self)._show_row_cells(table, name, group) table.cell(_("Members")) html.write_html( HTML(", ").join([ html.render_a(alias, href=watolib.folder_preserving_link([("mode", "edit_user"), ("edit", userid)])) for userid, alias in self._members.get(name, []) ]))
def render_availability_table(group_title, availability_table, what, avoptions): av_table = availability.layout_availability_table(what, group_title, availability_table, avoptions) # TODO: If summary line is activated, then sorting should now move that line to the # top. It should also stay at the bottom. This would require an extension to the # table.py module. with table_element("av_items", av_table["title"], css="availability", searchable=False, limit=None, omit_headers="omit_headers" in avoptions["labelling"]) as table: show_urls, show_timeline = False, False for row in av_table["rows"]: table.row() # Column with icons timeline_url = None if row["urls"]: show_urls = True table.cell("", css="buttons") for image, tooltip, url in row["urls"]: html.icon_button(url, tooltip, image) if image == "timeline": timeline_url = url # Column with host/service or aggregate name for title, (name, url) in zip(av_table["object_titles"], row["object"]): table.cell(title, html.render_a(name, url)) if "timeline" in row: show_timeline = True table.cell(_("Timeline"), css="timeline") html.open_a(href=timeline_url) render_timeline_bar(row["timeline"], "inline") html.close_a() # Columns with the actual availability data for (title, help_txt), (text, css) in zip(av_table["cell_titles"], row["cells"]): table.cell(title, text, css=css, help_txt=help_txt) if "summary" in av_table: table.row(css="summary", fixed=True) if show_urls: table.cell("", "") # Empty cell in URLs column table.cell("", _("Summary"), css="heading") for _x in xrange(1, len(av_table["object_titles"])): table.cell("", "") # empty cells, of more object titles than one if show_timeline: table.cell("", "") for (title, help_txt), (text, css) in zip(av_table["cell_titles"], av_table["summary"]): table.cell(title, text, css="heading " + css, help_txt=help_txt)
def render_link(text, url, target="main", onclick=None): # Convert relative links into absolute links. We have three kinds # of possible links and we change only [3] # [1] protocol://hostname/url/link.py # [2] /absolute/link.py # [3] relative.py if not (":" in url[:10]) and not url.startswith("javascript") and url[0] != '/': url = config.url_prefix() + "check_mk/" + url return html.render_a(text, href=url, class_="link", target=target or '',\ onfocus = "if (this.blur) this.blur();",\ onclick = onclick or None)
def query_limit_exceeded_with_warn(rows, limit, user_config): """Compare query reply against limits, warn in the GUI about incompleteness""" if not row_limit_exceeded(rows, limit): return False text = _("Your query produced more than %d results. ") % limit if html.get_ascii_input("limit", "soft") == "soft" and user_config.may("general.ignore_soft_limit"): text += html.render_a(_('Repeat query and allow more results.'), target="_self", href=html.makeuri([("limit", "hard")])) elif html.get_ascii_input("limit") == "hard" and user_config.may("general.ignore_hard_limit"): text += html.render_a(_('Repeat query without limit.'), target="_self", href=html.makeuri([("limit", "none")])) text += " " + _( "<b>Note:</b> the shown results are incomplete and do not reflect the sort order.") html.show_warning(text) return True
def _render_tag_group( tag_group_id_or_label_key: Union[TaggroupID, str], tag_id_or_label_value: Union[TagID, str], object_type: str, with_link: bool, label_type: str, label_source: str, ) -> HTML: span = html.render_tag( html.render_div( html.render_span( "%s:%s" % ( tag_group_id_or_label_key, tag_id_or_label_value, ), class_=["tagify__tag-text"], )), class_=["tagify--noAnim", label_source], ) if not with_link: return span if label_type == "tag_group": type_filter_vars: HTTPVariables = [ ("%s_tag_0_grp" % object_type, tag_group_id_or_label_key), ("%s_tag_0_op" % object_type, "is"), ("%s_tag_0_val" % object_type, tag_id_or_label_value), ] elif label_type == "label": type_filter_vars = [ ( "%s_label" % object_type, json.dumps([{ "value": "%s:%s" % (tag_group_id_or_label_key, tag_id_or_label_value) }]), ), ] else: raise NotImplementedError() url_vars: HTTPVariables = [ ("filled_in", "filter"), ("search", "Search"), ("view_name", "searchhost" if object_type == "host" else "searchsvc"), ] url = makeuri_contextless(request, url_vars + type_filter_vars, filename="view.py") return html.render_a(span, href=url)
def _show_row_cells(self, table: Table, name: GroupName, group: GroupSpec) -> None: super()._show_row_cells(table, name, group) table.cell(_("Members")) html.write_html( HTML(", ").join([ html.render_a( alias, href=watolib.folder_preserving_link([("mode", "edit_user"), ("edit", userid)]), ) for userid, alias in self._members.get(name, []) ]))
def test_ABCHTMLGenerator(request_context): with output_funnel.plugged(): with output_funnel.plugged(): html.open_div() text = output_funnel.drain() assert text.rstrip("\n").rstrip(" ") == "<div>" with output_funnel.plugged(): # html.open_div().write("test").close_div() html.open_div() html.write_text("test") html.close_div() assert compare_html(output_funnel.drain(), "<div>test</div>") with output_funnel.plugged(): # html.open_table().open_tr().td("1").td("2").close_tr().close_table() html.open_table() html.open_tr() html.td("1") html.td("2") html.close_tr() html.close_table() assert compare_html( output_funnel.drain(), "<table><tr><td>1</td><td>2</td></tr></table>") with output_funnel.plugged(): html.div("test", **{"</div>malicious_code<div>": "trends"}) assert compare_html( output_funnel.drain(), "<div </div>malicious_code<div>=trends>test</div>", ) a = "\u2665" with output_funnel.plugged(): assert html.render_a("test", href="www.test.case") html.render_a("test", href="www.test.case") html.render_a("test", href="www.test.case") html.render_a("test", href="www.test.case") try: assert html.render_a( "test", href=str("www.test.case"), id_=str("something"), class_=str("test_%s") % a, ) except Exception as e: traceback.print_exc() print(e)
def test_ABCHTMLGenerator(register_builtin_html): with html.plugged(): with html.plugged(): html.open_div() text = html.drain() assert text.rstrip('\n').rstrip(' ') == "<div>" with html.plugged(): #html.open_div().write("test").close_div() html.open_div() html.write("test") html.close_div() assert compare_html(html.drain(), "<div>test</div>") with html.plugged(): #html.open_table().open_tr().td("1").td("2").close_tr().close_table() html.open_table() html.open_tr() html.td("1") html.td("2") html.close_tr() html.close_table() assert compare_html( html.drain(), "<table><tr><td>1</td><td>2</td></tr></table>") with html.plugged(): html.div("test", **{"</div>malicious_code<div>": "trends"}) assert compare_html( html.drain(), "<div </div>malicious_code<div>=trends>test</div>") a = u"\u2665" with html.plugged(): assert html.render_a("test", href="www.test.case") html.render_a(u"test", href="www.test.case") html.render_a("test", href=u"www.test.case") html.render_a(u"test", href=u"www.test.case") try: assert html.render_a(u"test", href=six.text_type("www.test.case"), id_=six.text_type("something"), class_=six.text_type("test_%s") % a) except Exception as e: traceback.print_exc() print(e)
def get_host_list_links(site, hosts): entries = [] for host in hosts: args = [ ("view_name", "hoststatus"), ("site", site), ("host", host), ] if html.request.var("display_options"): args.append(("display_options", html.request.var("display_options"))) url = html.makeuri_contextless(args, filename="view.py") link = unicode(html.render_a(host, href=url)) entries.append(link) return entries
def get_host_list_links(site: SiteId, hosts: List[Union[str]]) -> List[str]: entries = [] for host in hosts: args: HTTPVariables = [ ("view_name", "hoststatus"), ("site", site), ("host", host), ] if request.var("display_options"): args.append(("display_options", request.var("display_options"))) url = makeuri_contextless(request, args, filename="view.py") link = str(html.render_a(host, href=url)) entries.append(link) return entries