1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-02-04 16:01:55 +00:00
community.general/plugins/filter/time.py
Felix Fontein 3478863ef0
Address issues reported by ruff check (#11043)
* Resolve E713 and E714 (not in/is tests).

* Address UP018 (unnecessary str call).

* UP045 requires Python 3.10+.

* Address UP007 (X | Y for type annotations).

* Address UP035 (import Callable from collections.abc).

* Address UP006 (t.Dict -> dict).

* Address UP009 (UTF-8 encoding comment).

* Address UP034 (extraneous parantheses).

* Address SIM910 (dict.get() with None default).

* Address F401 (unused import).

* Address UP020 (use builtin open).

* Address B009 and B010 (getattr/setattr with constant name).

* Address SIM300 (Yoda conditions).

* UP029 isn't in use anyway.

* Address FLY002 (static join).

* Address B034 (re.sub positional args).

* Address B020 (loop variable overrides input).

* Address B017 (assert raise Exception).

* Address SIM211 (if expression with false/true).

* Address SIM113 (enumerate for loop).

* Address UP036 (sys.version_info checks).

* Remove unnecessary UP039.

* Address SIM201 (not ==).

* Address SIM212 (if expr with twisted arms).

* Add changelog fragment.

* Reformat.
2025-11-08 17:05:21 +13:00

145 lines
4.1 KiB
Python

# Copyright (c) 2020, René Moser <mail@renemoser.net>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
import re
from ansible.errors import AnsibleFilterError
UNIT_FACTORS = {
"ms": [],
"s": [1000],
"m": [1000, 60],
"h": [1000, 60, 60],
"d": [1000, 60, 60, 24],
"w": [1000, 60, 60, 24, 7],
"mo": [1000, 60, 60, 24, 30],
"y": [1000, 60, 60, 24, 365],
}
UNIT_TO_SHORT_FORM = {
"millisecond": "ms",
"msec": "ms",
"msecond": "ms",
"sec": "s",
"second": "s",
"hour": "h",
"min": "m",
"minute": "m",
"day": "d",
"week": "w",
"month": "mo",
"year": "y",
}
def multiply(factors):
result = 1
for factor in factors:
result = result * factor
return result
def to_time_unit(human_time, unit="ms", **kwargs):
"""Return a time unit from a human readable string"""
# No need to handle 0
if human_time == "0":
return 0
unit_to_short_form = UNIT_TO_SHORT_FORM
unit_factors = UNIT_FACTORS
unit = unit_to_short_form.get(unit.rstrip("s"), unit)
if unit not in unit_factors:
raise AnsibleFilterError(
f"to_time_unit() can not convert to the following unit: {unit}. Available units (singular or plural):"
f"{', '.join(unit_to_short_form.keys())}. Available short units: {', '.join(unit_factors.keys())}"
)
if "year" in kwargs:
unit_factors["y"] = unit_factors["y"][:-1] + [kwargs.pop("year")]
if "month" in kwargs:
unit_factors["mo"] = unit_factors["mo"][:-1] + [kwargs.pop("month")]
if kwargs:
raise AnsibleFilterError(f"to_time_unit() got unknown keyword arguments: {', '.join(kwargs.keys())}")
result = 0
for h_time_string in human_time.split():
res = re.match(r"(-?\d+)(\w+)", h_time_string)
if not res:
raise AnsibleFilterError(f"to_time_unit() can not interpret following string: {human_time}")
h_time_int = int(res.group(1))
h_time_unit = res.group(2)
h_time_unit = unit_to_short_form.get(h_time_unit.rstrip("s"), h_time_unit)
if h_time_unit not in unit_factors:
raise AnsibleFilterError(f"to_time_unit() can not interpret following string: {human_time}")
time_in_milliseconds = h_time_int * multiply(unit_factors[h_time_unit])
result += time_in_milliseconds
return round(result / multiply(unit_factors[unit]), 12)
def to_milliseconds(human_time, **kwargs):
"""Return milli seconds from a human readable string"""
return to_time_unit(human_time, "ms", **kwargs)
def to_seconds(human_time, **kwargs):
"""Return seconds from a human readable string"""
return to_time_unit(human_time, "s", **kwargs)
def to_minutes(human_time, **kwargs):
"""Return minutes from a human readable string"""
return to_time_unit(human_time, "m", **kwargs)
def to_hours(human_time, **kwargs):
"""Return hours from a human readable string"""
return to_time_unit(human_time, "h", **kwargs)
def to_days(human_time, **kwargs):
"""Return days from a human readable string"""
return to_time_unit(human_time, "d", **kwargs)
def to_weeks(human_time, **kwargs):
"""Return weeks from a human readable string"""
return to_time_unit(human_time, "w", **kwargs)
def to_months(human_time, **kwargs):
"""Return months from a human readable string"""
return to_time_unit(human_time, "mo", **kwargs)
def to_years(human_time, **kwargs):
"""Return years from a human readable string"""
return to_time_unit(human_time, "y", **kwargs)
class FilterModule:
"""Ansible time jinja2 filters"""
def filters(self):
filters = {
"to_time_unit": to_time_unit,
"to_milliseconds": to_milliseconds,
"to_seconds": to_seconds,
"to_minutes": to_minutes,
"to_hours": to_hours,
"to_days": to_days,
"to_weeks": to_weeks,
"to_months": to_months,
"to_years": to_years,
}
return filters