Пример #1
0
def update_timeperiod(params):
    """Update a time period"""

    body = params['body']
    name = params['name']
    if name == "24X7":
        raise ProblemException(405, http.client.responses[405],
                               "You cannot change the built-in time period")

    time_period = load_timeperiod(name)
    if time_period is None:
        raise ProblemException(404, http.client.responses[404],
                               f"Time period {name} not found")

    if "exceptions" in body:
        time_period = dict(
            (key, time_period[key])
            for key in [*defines.weekday_ids(), "alias", "exclude"]
            if key in time_period)
        time_period["exceptions"] = _format_exceptions(body["exceptions"])

    if "alias" in body:
        time_period['alias'] = body['alias']

    if "active_time_ranges" in body:
        time_period.update(_daily_time_ranges(body['active_time_ranges']))

    if "exclude" in body:
        time_period["exclude"] = body["exclude"]

    save_timeperiod(name, time_period)
    return Response(status=204)
Пример #2
0
    def _to_valuespec(self, tp_spec):
        if not tp_spec:
            return {}

        exceptions = []
        for exception_name, time_ranges in tp_spec.items():
            if exception_name not in defines.weekday_ids() + [
                    "alias", "exclude"
            ]:
                exceptions.append(
                    (exception_name,
                     self._time_ranges_to_valuespec(time_ranges)))

        vs_spec = {
            "name":
            unique_default_name_suggestion(self._name or "time_period",
                                           list(self._timeperiods.keys())),
            "alias":
            timeperiod_spec_alias(tp_spec),
            "weekdays":
            self._weekdays_to_valuespec(tp_spec),
            "exclude":
            tp_spec.get("exclude", []),
            "exceptions":
            sorted(exceptions),
        }

        return vs_spec
Пример #3
0
    def _from_vars(self):
        self._timeperiods = watolib.timeperiods.load_timeperiods()
        self._name = request.var("edit")  # missing -> new group
        # TODO: Nuke the field below? It effectively hides facts about _name for mypy.
        self._new = self._name is None

        if self._name in watolib.timeperiods.builtin_timeperiods():
            raise MKUserError("edit",
                              _("Builtin timeperiods can not be modified"))

        if self._new:
            clone_name = request.var("clone")
            if request.var("mode") == "import_ical":
                self._timeperiod = {}
            elif clone_name:
                self._name = clone_name

                self._timeperiod = self._get_timeperiod(self._name)
            else:
                # initialize with 24x7 config
                self._timeperiod = {
                    day: [("00:00", "24:00")]
                    for day in defines.weekday_ids()
                }
        else:
            self._timeperiod = self._get_timeperiod(self._name)
Пример #4
0
def _daily_time_ranges(active_time_ranges: List[Dict[str, Any]]) -> Dict[str, List[TIME_RANGE]]:
    """Convert the user provided time ranges to the Checkmk format

    Args:
        active_time_ranges:
            The list of specific time ranges

    Returns:
        A dict which contains the week days as keys and their associating time ranges as values

    Examples:
        >>> _daily_time_ranges(
        ... [{"day": "monday", "time_ranges": [{"start": dt.time(12), "end": dt.time(14)}]}])
        {'monday': [('12:00', '14:00')], 'tuesday': [], 'wednesday': [], 'thursday': [], \
'friday': [], 'saturday': [], 'sunday': []}

    """

    result: Dict[str, List[TIME_RANGE]] = {day: [] for day in defines.weekday_ids()}
    for active_time_range in active_time_ranges:
        period = active_time_range["day"]  # weekday or week
        time_ranges = [
            _format_time_range(time_range) for time_range in active_time_range["time_ranges"]
        ]
        if period == "all":
            for day_time_ranges in result.values():
                day_time_ranges.extend(time_ranges)
        else:  # specific day
            result[period].extend(time_ranges)
    return result
Пример #5
0
    def _weekdays_to_valuespec(self, tp_spec):
        if self._has_same_time_specs_during_whole_week(tp_spec):
            return ("whole_week", self._time_ranges_to_valuespec(tp_spec.get("monday", [])))

        return ("day_specific", {
            day: self._time_ranges_to_valuespec(tp_spec.get(day, []))
            for day in defines.weekday_ids()
        })
Пример #6
0
    def action(self):
        if not html.check_transaction():
            return

        vs_ical = self._vs_ical()
        ical = vs_ical.from_html_vars("ical")
        vs_ical.validate_value(ical, "ical")

        filename, _ty, content = ical['file']

        try:
            data = self._parse_ical(content, ical['horizon'])
        except Exception as e:
            if config.debug:
                raise
            raise MKUserError('ical_file', _('Failed to parse file: %s') % e)

        # TODO: This is kind of a hack that we "fake" a HTTP request structure here.
        # Find a better way to hand over the whole data structure directly to the
        # edit_timeperiod code

        html.request.set_var('timeperiod_p_alias',
                             data.get('descr', data.get('name', filename)))

        for day in defines.weekday_ids():
            html.request.set_var('%s_0_from' % day, '')
            html.request.set_var('%s_0_until' % day, '')

        # Default to whole day
        if not ical["times"]:
            ical["times"] = [((0, 0), (24, 0))]

        html.request.set_var('timeperiod_p_exceptions_count',
                             "%d" % len(data['events']))
        for index, event in enumerate(data['events']):
            index += 1
            html.request.set_var('timeperiod_p_exceptions_%d_0' % index,
                                 event['date'])
            html.request.set_var('timeperiod_p_exceptions_indexof_%d' % index,
                                 "%d" % index)

            html.request.set_var('timeperiod_p_exceptions_%d_1_count' % index,
                                 "%d" % len(ical["times"]))
            for n, time_spec in enumerate(ical["times"]):
                n += 1
                start_time = ":".join("%02d" % x for x in time_spec[0])
                end_time = ":".join("%02d" % x for x in time_spec[1])
                html.request.set_var(
                    'timeperiod_p_exceptions_%d_1_%d_from' % (index, n),
                    start_time)
                html.request.set_var(
                    'timeperiod_p_exceptions_%d_1_%d_until' % (index, n),
                    end_time)
                html.request.set_var(
                    'timeperiod_p_exceptions_%d_1_indexof_%d' % (index, n),
                    "%d" % index)

        return "edit_timeperiod"
Пример #7
0
def show_time_period(params):
    """Show a time period"""
    name = params['name']
    time_periods = load_timeperiods()
    if name not in time_periods:
        raise ProblemException(404, http.client.responses[404], f"Time period {name} not found")
    time_period = time_periods[name]

    time_period_readable: Dict[str, Any] = {key: time_period[key] for key in ("alias", "exclude")}
    active_time_ranges = _active_time_ranges_readable(
        {key: time_period[key] for key in defines.weekday_ids()})
    time_period_readable["active_time_ranges"] = active_time_ranges
    time_period_readable["exceptions"] = _exceptions_readable({
        key: time_period[key]
        for key in time_period
        if key not in ['alias', 'exclude', *defines.weekday_ids()]
    })
    return _serve_time_period(time_period_readable)
Пример #8
0
    def _show_add_timeperiod_page(self) -> None:
        # If an ICalendar file is uploaded, we process the htmlvars here, to avoid
        # "Request URI too long exceptions"
        vs_ical = self._vs_ical()
        ical = vs_ical.from_html_vars("ical")
        vs_ical.validate_value(ical, "ical")

        filename, _ty, content = ical["file"]

        try:
            # TODO(ml): If we could open the file in text mode, we would not
            #           need to `decode()` here.
            data = self._parse_ical(content.decode("utf-8"), ical["horizon"])
        except Exception as e:
            if active_config.debug:
                raise
            raise MKUserError("ical_file", _("Failed to parse file: %s") % e)

        get_vars = {
            "timeperiod_p_alias": data.get("descr", data.get("name",
                                                             filename)),
        }

        for day in defines.weekday_ids():
            get_vars["%s_0_from" % day] = ""
            get_vars["%s_0_until" % day] = ""

        # Default to whole day
        if not ical["times"]:
            ical["times"] = [((0, 0), (24, 0))]

        get_vars["timeperiod_p_exceptions_count"] = "%d" % len(data["events"])
        for index, event in enumerate(data["events"]):
            index += 1
            get_vars["timeperiod_p_exceptions_%d_0" % index] = event["date"]
            get_vars["timeperiod_p_exceptions_indexof_%d" %
                     index] = "%d" % index

            get_vars["timeperiod_p_exceptions_%d_1_count" %
                     index] = "%d" % len(ical["times"])
            for n, time_spec in enumerate(ical["times"]):
                n += 1
                start_time = ":".join("%02d" % x for x in time_spec[0])
                end_time = ":".join("%02d" % x for x in time_spec[1])
                get_vars["timeperiod_p_exceptions_%d_1_%d_from" %
                         (index, n)] = start_time
                get_vars["timeperiod_p_exceptions_%d_1_%d_until" %
                         (index, n)] = end_time
                get_vars["timeperiod_p_exceptions_%d_1_indexof_%d" %
                         (index, n)] = "%d" % index

        for var, val in get_vars.items():
            html.request.set_var(var, val)

        html.request.set_var("mode", "edit_timeperiod")

        ModeEditTimeperiod().page()
Пример #9
0
def _to_api_format(
    time_period: TimeperiodSpec, builtin_period: bool = False, internal_format: bool = False
):
    """Convert time_period to API format as specified in request schema

    Args:
        time_period:
            time period which has the internal checkmk format
        builtin_period:
            bool specifying if the time period is a built-in time period
        internal_format:
            bool which determines if the time ranges should be compatible for internal processing

    Examples:
        >>> _to_api_format({'alias': 'Test All days 8x5', '2021-04-01': [('14:00', '15:00')],
        ... 'monday': [('08:00', '12:30'), ('13:30', '17:00')], 'tuesday': [], 'wednesday': [],
        ... 'thursday': [], 'friday': [], 'saturday': [], 'sunday': [], 'exclude': []})
        {'alias': 'Test All days 8x5', 'exclude': [], 'active_time_ranges': \
[{'day': 'monday', 'time_ranges': [{'start': '08:00', 'end': '12:30'}, {'start': '13:30', \
'end': '17:00'}]}], 'exceptions': [{'date': '2021-04-01', 'time_ranges': [{'start': '14:00', 'end': '15:00'}]}]}

    """
    time_period_readable: Dict[str, Any] = {"alias": time_period["alias"]}
    if not builtin_period:
        time_period_readable["exclude"] = time_period.get("exclude", [])

    active_time_ranges = _active_time_ranges_readable(
        {key: time_period[key] for key in defines.weekday_ids()}
    )
    exceptions = _exceptions_readable(
        {
            key: time_period[key]
            for key in time_period
            if key not in ["alias", "exclude", *defines.weekday_ids()]
        }
    )

    if internal_format:
        active_time_ranges = _convert_to_dt(active_time_ranges)
        exceptions = _convert_to_dt(exceptions)

    time_period_readable["active_time_ranges"] = active_time_ranges
    time_period_readable["exceptions"] = exceptions
    return time_period_readable
Пример #10
0
    def action(self) -> ActionResult:
        if not transactions.check_transaction():
            return None

        vs_ical = self._vs_ical()
        ical = vs_ical.from_html_vars("ical")
        vs_ical.validate_value(ical, "ical")

        filename, _ty, content = ical['file']

        try:
            # TODO(ml): If we could open the file in text mode, we would not
            #           need to `decode()` here.
            data = self._parse_ical(content.decode("utf-8"), ical['horizon'])
        except Exception as e:
            if config.debug:
                raise
            raise MKUserError('ical_file', _('Failed to parse file: %s') % e)

        get_vars = {
            'timeperiod_p_alias': data.get('descr', data.get('name',
                                                             filename)),
        }

        for day in defines.weekday_ids():
            get_vars['%s_0_from' % day] = ''
            get_vars['%s_0_until' % day] = ''

        # Default to whole day
        if not ical["times"]:
            ical["times"] = [((0, 0), (24, 0))]

        get_vars['timeperiod_p_exceptions_count'] = "%d" % len(data['events'])
        for index, event in enumerate(data['events']):
            index += 1
            get_vars['timeperiod_p_exceptions_%d_0' % index] = event['date']
            get_vars['timeperiod_p_exceptions_indexof_%d' %
                     index] = "%d" % index

            get_vars['timeperiod_p_exceptions_%d_1_count' %
                     index] = "%d" % len(ical["times"])
            for n, time_spec in enumerate(ical["times"]):
                n += 1
                start_time = ":".join("%02d" % x for x in time_spec[0])
                end_time = ":".join("%02d" % x for x in time_spec[1])
                get_vars['timeperiod_p_exceptions_%d_1_%d_from' %
                         (index, n)] = start_time
                get_vars['timeperiod_p_exceptions_%d_1_%d_until' %
                         (index, n)] = end_time
                get_vars['timeperiod_p_exceptions_%d_1_indexof_%d' %
                         (index, n)] = "%d" % index

        return redirect(mode_url("edit_timeperiod", **get_vars))
Пример #11
0
    def _weekdays_from_valuespec(self, vs_spec):
        weekday_ty, weekday_values = vs_spec["weekdays"]

        if weekday_ty not in ["whole_week", "day_specific"]:
            raise NotImplementedError()

        # produce a data structure equal to the "day_specific" structure
        if weekday_ty == "whole_week":
            weekday_values = {day: weekday_values for day in defines.weekday_ids()}

        return {
            day: self._time_ranges_from_valuespec(weekday_values[day])
            for day, time_ranges in weekday_values.items()
            if time_ranges
        }
Пример #12
0
    def _validate_timeperiod_exception(self, value, varprefix):
        if value in defines.weekday_ids():
            raise MKUserError(varprefix,
                              _("You cannot use weekday names (%s) in exceptions") % value)

        if value in ["name", "alias", "timeperiod_name", "register", "use", "exclude"]:
            raise MKUserError(varprefix, _("<tt>%s</tt> is a reserved keyword."))

        cfg = watolib.ConfigDomainOMD().default_globals()
        if cfg["site_core"] == "cmc":
            try:
                time.strptime(value, "%Y-%m-%d")
            except ValueError:
                raise MKUserError(
                    varprefix, _("You need to provide timeperiod exceptions in YYYY-MM-DD format"))
Пример #13
0
    def _time_exceptions_from_valuespec(self, vs_spec):
        # TODO: time exceptions is either a list of tuples or a dictionary for
        period_type, exceptions_details = vs_spec["weekdays"]

        if period_type not in ["whole_week", "day_specific"]:
            raise NotImplementedError()

        # produce a data structure equal to the "day_specific" structure
        if period_type == "whole_week":
            time_exceptions = {day: exceptions_details for day in defines.weekday_ids()}
        else:  # specific days
            time_exceptions = exceptions_details

        return {
            day: self._time_ranges_from_valuespec(time_exceptions[day])
            for day, time_ranges in time_exceptions.items()
            if time_ranges
        }
Пример #14
0
    def _to_valuespec(self, tp_spec):
        if not tp_spec:
            return {}

        exceptions = []
        for exception_name, time_ranges in tp_spec.items():
            if exception_name not in defines.weekday_ids() + ["alias", "exclude"]:
                exceptions.append((exception_name, self._time_ranges_to_valuespec(time_ranges)))

        vs_spec = {
            "name": self._name,
            "alias": tp_spec.get("alias", ""),
            "weekdays": self._weekdays_to_valuespec(tp_spec),
            "exclude": tp_spec.get("exclude", []),
            "exceptions": sorted(exceptions),
        }

        return vs_spec
Пример #15
0
    def _from_vars(self):
        self._timeperiods = watolib.timeperiods.load_timeperiods()
        self._name = html.request.var("edit")  # missing -> new group
        self._new = self._name is None

        if self._name in watolib.timeperiods.builtin_timeperiods():
            raise MKUserError("edit", _("Builtin timeperiods can not be modified"))

        if self._new:
            clone_name = html.request.var("clone")
            if clone_name:
                self._name = clone_name

                self._timeperiod = self._get_timeperiod(self._name)
            else:
                # initialize with 24x7 config
                self._timeperiod = {day: [("00:00", "24:00")] for day in defines.weekday_ids()}
        else:
            self._timeperiod = self._get_timeperiod(self._name)
Пример #16
0
    def action(self):
        if not html.check_transaction():
            return

        vs_ical = self._vs_ical()
        ical = vs_ical.from_html_vars("ical")
        vs_ical.validate_value(ical, "ical")

        filename, _ty, content = ical['file']

        try:
            data = self._parse_ical(content, ical['horizon'])
        except Exception as e:
            if config.debug:
                raise
            raise MKUserError('ical_file', _('Failed to parse file: %s') % e)

        html.request.set_var('alias',
                             data.get('descr', data.get('name', filename)))

        for day in defines.weekday_ids():
            html.request.set_var('%s_0_from' % day, '')
            html.request.set_var('%s_0_until' % day, '')

        html.request.set_var('except_count', "%d" % len(data['events']))
        for index, event in enumerate(data['events']):
            index += 1
            html.request.set_var('except_%d_0' % index, event['date'])
            html.request.set_var('except_indexof_%d' % index, "%d" % index)

            if ical["times"]:
                for n, time_spec in enumerate(ical["times"]):
                    start_time = ":".join("%02d" % x for x in time_spec[0])
                    end_time = ":".join("%02d" % x for x in time_spec[1])
                    html.request.set_var('except_%d_1_%d_from' % (index, n),
                                         start_time)
                    html.request.set_var('except_%d_1_%d_until' % (index, n),
                                         end_time)

        return "edit_timeperiod"
Пример #17
0
 def _has_same_time_specs_during_whole_week(self, tp_spec):
     """Put the time ranges of all weekdays into a set to reduce the duplicates to see whether
     or not all days have the same time spec and return True if they have the same."""
     unified_time_ranges = set(
         tuple(tp_spec.get(day, [])) for day in defines.weekday_ids())
     return len(unified_time_ranges) == 1
Пример #18
0
def group_by_wday(t):
    wday = time.localtime(t).tm_wday
    return defines.weekday_ids()[wday], window_start(t, 86400)
Пример #19
0
def _group_by_wday(t: Timestamp) -> Tuple[Timegroup, Timestamp]:
    wday = time.localtime(t).tm_wday
    return Timegroup(defines.weekday_ids()[wday]), _window_start(t, 86400)
Пример #20
0
def group_by_wday(t):
    # type: (Timestamp) -> Tuple[Timegroup, Timestamp]
    wday = time.localtime(t).tm_wday
    return defines.weekday_ids()[wday], window_start(t, 86400)