mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Time filter improvements (#359)
* Adjust target directory so that ansible-test knows what to run when filters change. * Divide by multiple instead of multiplying with product of 1/factor to improve numerical robustness. * Allow to say what a year or month is (in days). * Add changelog fragment announcing the time filters. * Make sure unknown keyword args result in errors. * Fix formatting screw-up.
This commit is contained in:
parent
801b1edcbe
commit
0399127d11
4 changed files with 49 additions and 27 deletions
2
changelogs/fragments/filter-time.yml
Normal file
2
changelogs/fragments/filter-time.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- A new filter ``to_time_unit`` with specializations ``to_milliseconds``, ``to_seconds``, ``to_minutes``, ``to_hours``, ``to_days``, ``to_weeks``, ``to_months`` and ``to_years`` has been added. For example ``'2d 4h' | community.general.to_hours`` evaluates to 52.
|
|
@ -56,20 +56,23 @@ def multiply(factors):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def divide(divisors):
|
def to_time_unit(human_time, unit='ms', **kwargs):
|
||||||
result = 1
|
|
||||||
for divisor in divisors:
|
|
||||||
result = result / divisor
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def to_time_unit(human_time, unit='ms'):
|
|
||||||
''' Return a time unit from a human readable string '''
|
''' Return a time unit from a human readable string '''
|
||||||
unit = UNIT_TO_SHORT_FORM.get(unit, unit)
|
unit = UNIT_TO_SHORT_FORM.get(unit, unit)
|
||||||
if unit not in UNIT_FACTORS:
|
if unit not in UNIT_FACTORS:
|
||||||
available_units = sorted(list(UNIT_FACTORS.keys()) + list(UNIT_TO_SHORT_FORM.keys()))
|
available_units = sorted(list(UNIT_FACTORS.keys()) + list(UNIT_TO_SHORT_FORM.keys()))
|
||||||
raise AnsibleFilterError("to_time_unit() can not convert to the following unit: %s. "
|
raise AnsibleFilterError("to_time_unit() can not convert to the following unit: %s. "
|
||||||
"Available units: %s" % (unit, ', '.join(available_units)))
|
"Available units: %s" % (unit, ', '.join(available_units)))
|
||||||
|
|
||||||
|
unit_factors = UNIT_FACTORS
|
||||||
|
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('to_time_unit() got unknown keyword arguments: %s' % ', '.join(kwargs.keys()))
|
||||||
|
|
||||||
result = 0
|
result = 0
|
||||||
for h_time_string in human_time.split():
|
for h_time_string in human_time.split():
|
||||||
res = re.match(r'(-?\d+)(\w+)', h_time_string)
|
res = re.match(r'(-?\d+)(\w+)', h_time_string)
|
||||||
|
@ -81,53 +84,53 @@ def to_time_unit(human_time, unit='ms'):
|
||||||
h_time_unit = res.group(2)
|
h_time_unit = res.group(2)
|
||||||
|
|
||||||
h_time_unit = UNIT_TO_SHORT_FORM.get(h_time_unit, h_time_unit)
|
h_time_unit = UNIT_TO_SHORT_FORM.get(h_time_unit, h_time_unit)
|
||||||
if h_time_unit not in UNIT_FACTORS:
|
if h_time_unit not in unit_factors:
|
||||||
raise AnsibleFilterError(
|
raise AnsibleFilterError(
|
||||||
"to_time_unit() can not interpret following string: %s" % human_time)
|
"to_time_unit() can not interpret following string: %s" % human_time)
|
||||||
|
|
||||||
time_in_milliseconds = h_time_int * multiply(UNIT_FACTORS[h_time_unit])
|
time_in_milliseconds = h_time_int * multiply(unit_factors[h_time_unit])
|
||||||
result += time_in_milliseconds
|
result += time_in_milliseconds
|
||||||
return round(result * divide(UNIT_FACTORS[unit]), 12)
|
return round(result / multiply(unit_factors[unit]), 12)
|
||||||
|
|
||||||
|
|
||||||
def to_milliseconds(human_time):
|
def to_milliseconds(human_time, **kwargs):
|
||||||
''' Return milli seconds from a human readable string '''
|
''' Return milli seconds from a human readable string '''
|
||||||
return to_time_unit(human_time, 'ms')
|
return to_time_unit(human_time, 'ms', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def to_seconds(human_time):
|
def to_seconds(human_time, **kwargs):
|
||||||
''' Return seconds from a human readable string '''
|
''' Return seconds from a human readable string '''
|
||||||
return to_time_unit(human_time, 's')
|
return to_time_unit(human_time, 's', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def to_minutes(human_time):
|
def to_minutes(human_time, **kwargs):
|
||||||
''' Return minutes from a human readable string '''
|
''' Return minutes from a human readable string '''
|
||||||
return to_time_unit(human_time, 'm')
|
return to_time_unit(human_time, 'm', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def to_hours(human_time):
|
def to_hours(human_time, **kwargs):
|
||||||
''' Return hours from a human readable string '''
|
''' Return hours from a human readable string '''
|
||||||
return to_time_unit(human_time, 'h')
|
return to_time_unit(human_time, 'h', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def to_days(human_time):
|
def to_days(human_time, **kwargs):
|
||||||
''' Return days from a human readable string '''
|
''' Return days from a human readable string '''
|
||||||
return to_time_unit(human_time, 'd')
|
return to_time_unit(human_time, 'd', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def to_weeks(human_time):
|
def to_weeks(human_time, **kwargs):
|
||||||
''' Return weeks from a human readable string '''
|
''' Return weeks from a human readable string '''
|
||||||
return to_time_unit(human_time, 'w')
|
return to_time_unit(human_time, 'w', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def to_months(human_time):
|
def to_months(human_time, **kwargs):
|
||||||
''' Return months from a human readable string '''
|
''' Return months from a human readable string '''
|
||||||
return to_time_unit(human_time, 'mo')
|
return to_time_unit(human_time, 'mo', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def to_years(human_time):
|
def to_years(human_time, **kwargs):
|
||||||
''' Return years from a human readable string '''
|
''' Return years from a human readable string '''
|
||||||
return to_time_unit(human_time, 'y')
|
return to_time_unit(human_time, 'y', **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class FilterModule(object):
|
class FilterModule(object):
|
||||||
|
|
|
@ -38,24 +38,29 @@
|
||||||
- "('1week' | community.general.to_days) == 7"
|
- "('1week' | community.general.to_days) == 7"
|
||||||
- "('2weeks' | community.general.to_days) == 14"
|
- "('2weeks' | community.general.to_days) == 14"
|
||||||
- "('1mo' | community.general.to_days) == 30"
|
- "('1mo' | community.general.to_days) == 30"
|
||||||
|
- "('1mo' | community.general.to_days(month=28)) == 28"
|
||||||
|
|
||||||
- name: test to_weeks filter
|
- name: test to_weeks filter
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "('1y' | community.general.to_weeks | int) == 52"
|
- "('1y' | community.general.to_weeks | int) == 52"
|
||||||
- "('7d' | community.general.to_weeks) == 1"
|
- "('7d' | community.general.to_weeks) == 1"
|
||||||
|
- "('1mo' | community.general.to_weeks(month=28)) == 4"
|
||||||
|
|
||||||
- name: test to_months filter
|
- name: test to_months filter
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "('30d' | community.general.to_months) == 1"
|
- "('30d' | community.general.to_months) == 1"
|
||||||
- "('1year' | community.general.to_months | int) == 12"
|
- "('1year' | community.general.to_months | int) == 12"
|
||||||
|
- "('5years' | community.general.to_months(month=30, year=360)) == 60"
|
||||||
|
- "('1years' | community.general.to_months(month=2, year=34)) == 17"
|
||||||
|
|
||||||
- name: test to_years filter
|
- name: test to_years filter
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "('365d' | community.general.to_years | int) == 1"
|
- "('365d' | community.general.to_years | int) == 1"
|
||||||
- "('12mo' | community.general.to_years | round(0, 'ceil')) == 1"
|
- "('12mo' | community.general.to_years | round(0, 'ceil')) == 1"
|
||||||
|
- "('24mo' | community.general.to_years(month=30, year=360)) == 2"
|
||||||
|
|
||||||
- name: test fail unknown unit
|
- name: test fail unknown unit
|
||||||
debug:
|
debug:
|
||||||
|
@ -80,3 +85,15 @@
|
||||||
that:
|
that:
|
||||||
- res is failed
|
- res is failed
|
||||||
- "'to_time_unit() can not interpret following string' in res.msg"
|
- "'to_time_unit() can not interpret following string' in res.msg"
|
||||||
|
|
||||||
|
- name: test fail unknown kwarg
|
||||||
|
debug:
|
||||||
|
msg: "{{ '1s' | community.general.to_time_unit('s', second=23) }}"
|
||||||
|
ignore_errors: yes
|
||||||
|
register: res
|
||||||
|
|
||||||
|
- name: test fail unknown kwarg
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- res is failed
|
||||||
|
- "'to_time_unit() got unknown keyword arguments' in res.msg"
|
Loading…
Reference in a new issue