def render_mobile_dataset(rows, view, group_cells, cells, num_columns, show_checkboxes): if not is_mobile(request, response): html.show_error(_("This view can only be used in mobile mode.")) return painter_options = PainterOptions.get_instance() painter_options.set("ts_format", "both") for row in rows: html.open_table(class_="dataset") for cell in cells: _tdclass, content = cell.render(row) if not content: continue # Omit empty cells html.open_tr(class_="header") html.th(cell.title()) html.close_tr() html.open_tr(class_="data") cell.paint(row) html.close_tr() html.close_table() html.javascript( '$("table.dataset > tbody > tr.data > td").addClass("ui-shadow").not(".state").addClass("nonstatus");\n' '$("table.dataset > tbody > tr.data a").attr("data-ajax", "false");\n')
def page_index() -> None: # Redirect to mobile GUI if we are a mobile device and the index is requested if is_mobile(request, response): raise HTTPRedirect(makeuri(request, [], filename="mobile.py")) title = get_page_heading() content = html.render_iframe("", src=_get_start_url(), name="main") SidebarRenderer().show(title, content)
def mock_livestatus( with_context: bool = False, with_html: bool = False ) -> Generator[MockLiveStatusConnection, None, None]: live = MockLiveStatusConnection() env = EnvironBuilder().get_environ() req = http.Request(env) resp = http.Response() app_context: ContextManager req_context: ContextManager if with_html: html_obj = None else: html_obj = HTMLGenerator( request=req, output_funnel=OutputFunnel(resp), output_format="html", mobile=is_mobile(req, resp), ) if with_context: app_context = AppContext(None, stack=app_stack()) req_context = RequestContext( html_obj=html_obj, req=req, resp=resp, funnel=OutputFunnel(resp), config_obj=make_config_object(get_default_config()), user=LoggedInNobody(), display_options=DisplayOptions(), prefix_logs_with_url=False, stack=request_stack(), url_filter=PrependURLFilter(), ) else: app_context = contextlib.nullcontext() req_context = contextlib.nullcontext() with app_context, req_context, mock.patch( "cmk.gui.sites._get_enabled_and_disabled_sites", new=live.enabled_and_disabled_sites), mock.patch( "livestatus.MultiSiteConnection.expect_query", new=live.expect_query, create=True), mock.patch( "livestatus.SingleSiteConnection._create_socket", new=live.create_socket), mock.patch.dict( os.environ, { "OMD_ROOT": "/", "OMD_SITE": "NO_SITE" }): # We don't want to be polluted by other tests. omd_site.cache_clear() yield live # We don't want to pollute other tests. omd_site.cache_clear()
def page(self) -> None: # Initialize the cmk.gui.i18n for the login dialog. This might be # overridden later after user login cmk.gui.i18n.localize(request.var("lang", config.default_language)) self._do_login() if self._no_html_output: raise MKAuthException(_("Invalid login credentials.")) if is_mobile(request, response): cmk.gui.mobile.page_login() return self._show_login_page()
def render(self, what, row, tags, custom_vars): def may_see_hosts(): return user.may("wato.use") and (user.may("wato.seeall") or user.may("wato.hosts")) if not may_see_hosts() or is_mobile(request, response): return None wato_folder = _wato_folder_from_filename(row["host_filename"]) if wato_folder is None: return None if what == "host": return self._wato_link(wato_folder, row["site"], row["host_name"], "edithost") if row["service_description"] in ["Check_MK inventory", "Check_MK Discovery"]: return self._wato_link(wato_folder, row["site"], row["host_name"], "inventory")
def from_exception(cls, details=None, type_specific_attributes=None): return super().from_exception( details={ "page": requested_file_name(request) + ".py", "vars": { key: "***" if value in ["password", "_password"] else value for key, value in request.itervars() }, "username": user.id, "user_agent": request.user_agent.string, "referer": request.referer, "is_mobile": is_mobile(request, response), "is_ssl_request": request.is_ssl_request, "language": cmk.gui.i18n.get_current_language(), "request_method": request.request_method, }, )
def confirm_with_preview(msg: Union[str, HTML], confirm_options: List[Tuple[str, str]], method: str = "POST") -> Optional[bool]: """Show a confirm dialog to the user BE AWARE: In case you just want to have some action confirmed by the user, you should use the javascript powere confirm dialg (make_confirm, add_confirm_on_submit, ...). This method is used only in places where we explicitly need to show important information to the user before he can decide whether or not to confirm the action. The confirm dialog is normally not a dialog which need to be protected by a transid itselfs. It is only a intermediate step to the real action But there are use cases where the confirm dialog is used during rendering a normal page, for example when deleting a dashlet from a dashboard. In such cases, the transid must be added by the confirm dialog. """ if html.request.var("_do_actions") == _("Cancel"): # User has pressed "Cancel", now invalidate the unused transid transactions.check_transaction() return None # None --> "Cancel" if not any( html.request.has_var(varname) for _title, varname in confirm_options): mobile = is_mobile(request, response) if mobile: html.open_center() html.open_div(class_="really") html.write_text(msg) html.begin_form("confirm", method=method, add_transid=False) html.hidden_fields(add_action_vars=True) for title, varname in confirm_options: html.button(varname, title, "really") html.button("_do_actions", _("Cancel")) html.end_form() html.close_div() if mobile: html.close_center() return False # False --> "Dialog shown, no answer yet" # Now check the transaction. True: "Yes", None --> Browser reload of "yes" page return True if transactions.check_transaction() else None
def _pnp_icon(self, row, what): url = self._graph_icon_link(row, what) # Don't show the icon with Checkmk 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 is_mobile(request, response): return return html.render_a( content=html.render_icon('graph', ''), href=url, onmouseout="cmk.hover.hide()", onmouseover= "cmk.graph_integration.show_hover_graphs(event, %s, %s, %s);" % ( json.dumps(row['site']), json.dumps(row["host_name"]), json.dumps(row['service_description'] if what == "service" else '_HOST_'), ))
def render_mobile_list(rows, view, group_cells, cells, num_columns, show_checkboxes): if not is_mobile(request, response): 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.p(rendered_content, class_=["ui-li-aside", "ui-li-desc", rendered_class]) if len(rendered_cells) > 1: content = HTML(" · ").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.span(rendered_content, class_=rendered_class) html.close_p() html.close_li() html.close_ul() html.javascript('$("ul.mobilelist a").attr("data-ajax", "false");')
def render_mobile_table(rows, view, group_cells, cells, num_columns, show_checkboxes): if not is_mobile(request, response): 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") odd = "odd" html.open_table(class_="mobile data") # Paint header if view.get("column_headers") != "off": html.open_tr() n = 0 for cell in cells: cell.paint_as_header() html.close_tr() # Paint data rows for row in rows: odd = "even" if odd == "odd" else "odd" html.open_tr(class_="%s0" % odd) for n, cell in enumerate(cells): if n > 0 and n % num_columns == 0: html.close_tr() html.open_tr(class_="%s0" % odd) if n == len(cells) - 1 and n % num_columns != (num_columns - 1): colspan = num_columns - (n % num_columns) else: colspan = None cell.paint(row, colspan=colspan) html.close_row() html.close_table() html.javascript('$("table.mobile a").attr("data-ajax", "false");')
def make_request_context( environ: Optional[Mapping[str, Any]] = None) -> RequestContext: req = Request( dict(create_environ(), REQUEST_URI="") if environ is None else environ) resp = Response(mimetype="text/html") funnel = OutputFunnel(resp) return RequestContext( req=req, resp=resp, funnel=funnel, config_obj=make_config_object(get_default_config()), user=LoggedInNobody(), html_obj=HTMLGenerator(req, funnel, output_format="html", mobile=is_mobile(req, resp)), display_options=DisplayOptions(), timeout_manager=TimeoutManager(), theme=Theme(), prefix_logs_with_url=False, stack=request_stack(), url_filter=PrependURLFilter(), )
def __call__(self, environ: WSGIEnvironment, start_response: StartResponse) -> WSGIResponse: req = http.Request(environ) output_format = get_output_format( req.get_ascii_input_mandatory("output_format", "html").lower()) mime_type = get_mime_type_from_output_format(output_format) resp = Response(headers=default_response_headers(req), mimetype=mime_type) funnel = OutputFunnel(resp) timeout_manager = TimeoutManager() timeout_manager.enable_timeout(req.request_timeout) theme = Theme() config_obj = config_module.make_config_object( config_module.get_default_config()) with AppContext(self, stack=app_stack()), RequestContext( req=req, resp=resp, funnel=funnel, config_obj=config_obj, user=LoggedInNobody(), html_obj=HTMLGenerator(req, funnel, output_format, is_mobile(req, resp)), timeout_manager=timeout_manager, display_options=DisplayOptions(), theme=theme, stack=request_stack(), url_filter=PrependURLFilter(), ), patch_json(json): config_module.initialize() theme.from_config(active_config.ui_theme) return self.wsgi_app(environ, start_response)
def paint_time_graph_cmk(row, cell, override_graph_render_options=None): graph_identification = ( "template", { "site": row["site"], "host_name": row["host_name"], "service_description": row.get("service_description", "_HOST_"), }, ) # Load the graph render options from # a) the painter parameters configured in the view # b) the painter options set per user and view painter_params = cell.painter_parameters() painter_params = _transform_old_graph_render_options(painter_params) graph_render_options = painter_params["graph_render_options"] if override_graph_render_options is not None: graph_render_options.update(override_graph_render_options) painter_options = PainterOptions.get_instance() options = painter_options.get_without_default("graph_render_options") if options is not None: graph_render_options.update(options) graph_data_range = {} now = time.time() if "set_default_time_range" in painter_params: duration = painter_params["set_default_time_range"] graph_data_range["time_range"] = now - duration, now else: graph_data_range["time_range"] = now - 3600 * 4, now # Load timerange from painter option (overrides the defaults, if set by the user) painter_option_pnp_timerange = painter_options.get_without_default( "pnp_timerange") if painter_option_pnp_timerange is not None: graph_data_range[ "time_range"] = get_graph_timerange_from_painter_options() if is_mobile(request, response): graph_render_options.update({ "interaction": False, "show_controls": False, "show_pin": False, "show_graph_time": False, "show_time_range_previews": False, "show_legend": False, # Would be much better to autodetect the possible size (like on dashboard) "size": (27, 18), # ex }) if "host_metrics" in row: available_metrics = row["host_metrics"] perf_data = row["host_perf_data"] else: available_metrics = row["service_metrics"] perf_data = row["service_perf_data"] if not available_metrics and perf_data: return "", _( "No historic metrics recorded but performance data is available. " "Maybe performance data processing is disabled.") return "", html_render.render_graphs_from_specification_html( graph_identification, graph_data_range, graph_render_options)