The result of running black .
changed ago.py changed setup.py changed test_ago.py
This commit is contained in:
parent
36102bba88
commit
b2f6af9d70
3 changed files with 127 additions and 105 deletions
52
ago.py
52
ago.py
|
|
@ -1,9 +1,7 @@
|
|||
from datetime import (
|
||||
datetime,
|
||||
timedelta,
|
||||
)
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
units = ("year", "day", "hour", "minute", "second", "millisecond", "microsecond")
|
||||
|
||||
units = ('year', 'day', 'hour', 'minute', 'second', 'millisecond', 'microsecond')
|
||||
|
||||
def get_delta_from_subject(subject):
|
||||
subject_type = type(subject)
|
||||
|
|
@ -19,20 +17,24 @@ def get_delta_from_subject(subject):
|
|||
delta = datetime.now() - dt
|
||||
return delta
|
||||
|
||||
|
||||
def delta2dict(delta):
|
||||
"""Accepts a delta, returns a dictionary of units"""
|
||||
delta = abs(delta)
|
||||
return {
|
||||
'year' : int(delta.days / 365),
|
||||
'day' : int(delta.days % 365),
|
||||
'hour' : int(delta.seconds / 3600),
|
||||
'minute' : int(delta.seconds / 60) % 60,
|
||||
'second' : delta.seconds % 60,
|
||||
'millisecond' : delta.microseconds/1000,
|
||||
'microsecond' : delta.microseconds%1000,
|
||||
"year": int(delta.days / 365),
|
||||
"day": int(delta.days % 365),
|
||||
"hour": int(delta.seconds / 3600),
|
||||
"minute": int(delta.seconds / 60) % 60,
|
||||
"second": delta.seconds % 60,
|
||||
"millisecond": delta.microseconds / 1000,
|
||||
"microsecond": delta.microseconds % 1000,
|
||||
}
|
||||
|
||||
def human(subject, precision=2, past_tense='{} ago', future_tense='in {}', abbreviate=False):
|
||||
|
||||
def human(
|
||||
subject, precision=2, past_tense="{} ago", future_tense="in {}", abbreviate=False
|
||||
):
|
||||
"""
|
||||
Accept a subject, return a human readable timedelta string.
|
||||
|
||||
|
|
@ -47,26 +49,28 @@ def human(subject, precision=2, past_tense='{} ago', future_tense='in {}', abbre
|
|||
delta = get_delta_from_subject(subject)
|
||||
the_tense = future_tense if delta < timedelta(0) else past_tense
|
||||
|
||||
d = delta2dict( delta )
|
||||
d = delta2dict(delta)
|
||||
|
||||
hlist = []
|
||||
count = 0
|
||||
|
||||
# start building up the output in the hlist.
|
||||
for unit in units:
|
||||
if count >= precision: break # met precision
|
||||
if d[ unit ] == 0: continue # skip 0's
|
||||
if count >= precision:
|
||||
break # met precision
|
||||
if d[unit] == 0:
|
||||
continue # skip 0's
|
||||
if abbreviate:
|
||||
if unit == 'millisecond':
|
||||
abr = 'ms'
|
||||
elif unit == 'microsecond':
|
||||
abr = 'um'
|
||||
if unit == "millisecond":
|
||||
abr = "ms"
|
||||
elif unit == "microsecond":
|
||||
abr = "um"
|
||||
else:
|
||||
abr = unit[0]
|
||||
hlist.append('{}{}'.format(d[unit], abr))
|
||||
hlist.append("{}{}".format(d[unit], abr))
|
||||
else:
|
||||
s = '' if d[ unit ] == 1 else 's' # handle plurals
|
||||
hlist.append('{} {}{}'.format(d[unit], unit, s))
|
||||
s = "" if d[unit] == 1 else "s" # handle plurals
|
||||
hlist.append("{} {}{}".format(d[unit], unit, s))
|
||||
count += 1
|
||||
|
||||
return the_tense.format(', '.join(hlist))
|
||||
return the_tense.format(", ".join(hlist))
|
||||
|
|
|
|||
30
setup.py
30
setup.py
|
|
@ -2,26 +2,22 @@
|
|||
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
name = 'ago',
|
||||
version = '0.0.92',
|
||||
description = 'ago: Human readable timedeltas',
|
||||
keywords = 'ago human readable time deltas timedelta datetime timestamp',
|
||||
long_description = open('README.rst').read(),
|
||||
|
||||
author = 'Russell Ballestrini',
|
||||
author_email = 'russell@ballestrini.net',
|
||||
url = 'https://bitbucket.org/russellballestrini/ago/src',
|
||||
|
||||
platforms = ['All'],
|
||||
license = 'Public Domain',
|
||||
|
||||
py_modules = ['ago'],
|
||||
include_package_data = True,
|
||||
setup(
|
||||
name="ago",
|
||||
version="0.0.92",
|
||||
description="ago: Human readable timedeltas",
|
||||
keywords="ago human readable time deltas timedelta datetime timestamp",
|
||||
long_description=open("README.rst").read(),
|
||||
author="Russell Ballestrini",
|
||||
author_email="russell@ballestrini.net",
|
||||
url="https://bitbucket.org/russellballestrini/ago/src",
|
||||
platforms=["All"],
|
||||
license="Public Domain",
|
||||
py_modules=["ago"],
|
||||
include_package_data=True,
|
||||
)
|
||||
|
||||
# setup keyword args: http://peak.telecommunity.com/DevCenter/setuptools
|
||||
|
||||
# built and uploaded to pypi with this:
|
||||
# python setup.py sdist bdist_egg register upload
|
||||
|
||||
|
|
|
|||
150
test_ago.py
150
test_ago.py
|
|
@ -8,117 +8,139 @@ from ago import delta2dict
|
|||
|
||||
# datetime objects
|
||||
PRESENT = datetime.now()
|
||||
PAST = PRESENT - timedelta( 492, 58711, 45 ) # days, secs, microseconds
|
||||
FUTURE = PRESENT + timedelta( 2, 12447, 967742 ) # days, secs, microseconds
|
||||
PAST = PRESENT - timedelta(492, 58711, 45) # days, secs, microseconds
|
||||
FUTURE = PRESENT + timedelta(2, 12447, 967742) # days, secs, microseconds
|
||||
|
||||
# timedelta objects
|
||||
PAST_DELTA = PRESENT - PAST
|
||||
PAST_DELTA = PRESENT - PAST
|
||||
FUTURE_DELTA = PRESENT - FUTURE
|
||||
ONE_YEAR_FOUR_HOURS_DELTA = timedelta( 365, 14400, 0 )
|
||||
ONE_YEAR_FOUR_HOURS_DELTA = timedelta(365, 14400, 0)
|
||||
|
||||
|
||||
def test_human_passed_datetime_is_string():
|
||||
assert isinstance(human( PAST ), str)
|
||||
assert isinstance(human(PAST), str)
|
||||
|
||||
|
||||
def test_human_passed_timedelta_is_string():
|
||||
assert isinstance(human( PAST_DELTA ), str)
|
||||
assert isinstance(human(PAST_DELTA), str)
|
||||
|
||||
|
||||
def test_delta2dict_is_dict():
|
||||
assert isinstance(delta2dict( PAST_DELTA ), dict)
|
||||
assert isinstance(delta2dict(PAST_DELTA), dict)
|
||||
|
||||
|
||||
def test_ago_in_past_human():
|
||||
assert 'ago' in human( PAST )
|
||||
assert "ago" in human(PAST)
|
||||
|
||||
|
||||
def test_in_in_future_human():
|
||||
assert 'in' in human( FUTURE )
|
||||
assert "in" in human(FUTURE)
|
||||
|
||||
|
||||
def test_no_coma_in_one_precision():
|
||||
assert ',' not in human( PAST, precision = 1 )
|
||||
assert ',' not in human( FUTURE, precision = 1 )
|
||||
assert "," not in human(PAST, precision=1)
|
||||
assert "," not in human(FUTURE, precision=1)
|
||||
|
||||
|
||||
def test_coma_in_three_precision():
|
||||
assert ',' in human( PAST, precision = 3 )
|
||||
assert ',' in human( FUTURE, precision = 3 )
|
||||
assert "," in human(PAST, precision=3)
|
||||
assert "," in human(FUTURE, precision=3)
|
||||
|
||||
|
||||
def test_coma_in_out_of_bounds_precision():
|
||||
assert ',' in human( PAST, precision = 10 )
|
||||
assert ',' in human( FUTURE, precision = 10 )
|
||||
assert "," in human(PAST, precision=10)
|
||||
assert "," in human(FUTURE, precision=10)
|
||||
|
||||
|
||||
def test_zero_day_is_skipped_display_hour():
|
||||
_result = human( ONE_YEAR_FOUR_HOURS_DELTA, precision = 2 )
|
||||
assert 'year' in _result
|
||||
_result = human(ONE_YEAR_FOUR_HOURS_DELTA, precision=2)
|
||||
assert "year" in _result
|
||||
# day is 0 so it is skipped, so we should show hours ...
|
||||
assert 'hour' in _result
|
||||
assert "hour" in _result
|
||||
|
||||
|
||||
def test_one_day_singular():
|
||||
assert 's' not in human( timedelta(1) )
|
||||
assert "s" not in human(timedelta(1))
|
||||
|
||||
|
||||
def test_two_day_plural():
|
||||
assert 's' in human( timedelta(2) )
|
||||
assert "s" in human(timedelta(2))
|
||||
|
||||
|
||||
def test_abbreviation():
|
||||
assert '2d ago' in human( timedelta(2), abbreviate=True )
|
||||
assert '3d, 12h ago' in human( timedelta(3.5), abbreviate=True )
|
||||
assert '2h, 24m ago' in human( timedelta(.1), abbreviate=True )
|
||||
assert '1y, 35d ago' in human( timedelta(400), abbreviate=True )
|
||||
assert "2d ago" in human(timedelta(2), abbreviate=True)
|
||||
assert "3d, 12h ago" in human(timedelta(3.5), abbreviate=True)
|
||||
assert "2h, 24m ago" in human(timedelta(.1), abbreviate=True)
|
||||
assert "1y, 35d ago" in human(timedelta(400), abbreviate=True)
|
||||
|
||||
|
||||
def test_timestamp_integer():
|
||||
result = human(1474485467933/1000, precision=6)
|
||||
assert('minute' in result)
|
||||
assert('second' in result)
|
||||
assert('ago' in result)
|
||||
result = human(1474485467933 / 1000, precision=6)
|
||||
assert "minute" in result
|
||||
assert "second" in result
|
||||
assert "ago" in result
|
||||
|
||||
|
||||
def test_timestamp_float():
|
||||
result = human(1474485467933/1000.0, precision=6)
|
||||
assert('minute' in result)
|
||||
assert('second' in result)
|
||||
assert('ago' in result)
|
||||
result = human(1474485467933 / 1000.0, precision=6)
|
||||
assert "minute" in result
|
||||
assert "second" in result
|
||||
assert "ago" in result
|
||||
|
||||
|
||||
def test_past_tense():
|
||||
output = human( PAST,
|
||||
past_tense = 'titanic sunk {} ago',
|
||||
future_tense = 'titanic will sink in {} from now'
|
||||
output = human(
|
||||
PAST,
|
||||
past_tense="titanic sunk {} ago",
|
||||
future_tense="titanic will sink in {} from now",
|
||||
)
|
||||
assert 'titanic sunk' in output
|
||||
assert "titanic sunk" in output
|
||||
|
||||
|
||||
def test_future_tense():
|
||||
output = human( FUTURE,
|
||||
past_tense = 'titanic sunk {} ago',
|
||||
future_tense = 'titanic will sink in {} from now'
|
||||
output = human(
|
||||
FUTURE,
|
||||
past_tense="titanic sunk {} ago",
|
||||
future_tense="titanic will sink in {} from now",
|
||||
)
|
||||
assert 'titanic will sink in' in output
|
||||
assert "titanic will sink in" in output
|
||||
|
||||
|
||||
def test_valid_past_dict():
|
||||
past_dict = delta2dict( PAST_DELTA )
|
||||
assert past_dict['year'] == 1
|
||||
assert past_dict['day'] == 127
|
||||
assert past_dict['hour'] == 16
|
||||
assert past_dict['minute'] == 18
|
||||
assert past_dict['microsecond'] == 45
|
||||
past_dict = delta2dict(PAST_DELTA)
|
||||
assert past_dict["year"] == 1
|
||||
assert past_dict["day"] == 127
|
||||
assert past_dict["hour"] == 16
|
||||
assert past_dict["minute"] == 18
|
||||
assert past_dict["microsecond"] == 45
|
||||
|
||||
|
||||
def test_valid_future_dict():
|
||||
past_dict = delta2dict( FUTURE_DELTA )
|
||||
assert past_dict['year'] == 0
|
||||
assert past_dict['day'] == 2
|
||||
assert past_dict['hour'] == 3
|
||||
assert past_dict['minute'] == 27
|
||||
assert past_dict['millisecond'] == 967
|
||||
assert past_dict['microsecond'] == 742
|
||||
past_dict = delta2dict(FUTURE_DELTA)
|
||||
assert past_dict["year"] == 0
|
||||
assert past_dict["day"] == 2
|
||||
assert past_dict["hour"] == 3
|
||||
assert past_dict["minute"] == 27
|
||||
assert past_dict["millisecond"] == 967
|
||||
assert past_dict["microsecond"] == 742
|
||||
|
||||
|
||||
def example_usage():
|
||||
"""Test and example usage"""
|
||||
|
||||
print('\nTest past tense:\n')
|
||||
print(delta2dict( PAST_DELTA ))
|
||||
print('Commented ' + human( PAST_DELTA, 1 ))
|
||||
print(human( PAST, past_tense = "Commented {} ago" ))
|
||||
print("\nTest past tense:\n")
|
||||
print(delta2dict(PAST_DELTA))
|
||||
print("Commented " + human(PAST_DELTA, 1))
|
||||
print(human(PAST, past_tense="Commented {} ago"))
|
||||
|
||||
print(human( ONE_YEAR_FOUR_HOURS_DELTA, past_tense = "Posted {} ago" ))
|
||||
print(human(ONE_YEAR_FOUR_HOURS_DELTA, past_tense="Posted {} ago"))
|
||||
|
||||
print('\nTest future tense:\n')
|
||||
print(delta2dict( FUTURE_DELTA ))
|
||||
print('Shutdown ' + human( FUTURE_DELTA, 5 ))
|
||||
print(human( FUTURE, future_tense = 'Shutdown in {} from now' ))
|
||||
print('')
|
||||
print("\nTest future tense:\n")
|
||||
print(delta2dict(FUTURE_DELTA))
|
||||
print("Shutdown " + human(FUTURE_DELTA, 5))
|
||||
print(human(FUTURE, future_tense="Shutdown in {} from now"))
|
||||
print("")
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if __name__ == "__main__":
|
||||
example_usage()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue