mirror of
https://github.com/GothenburgBitFactory/timewarrior.git
synced 2025-06-26 10:54:28 +02:00
Make report 'totals.py' display data when no time range specified
Use interval array to determine whether there is data to display Move interval truncation outside the loop, combine/rework 'no data' messages Close #450 Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
This commit is contained in:
parent
8e8df2aaa8
commit
c80442c878
4 changed files with 48 additions and 21 deletions
1
AUTHORS
1
AUTHORS
|
@ -102,3 +102,4 @@ Thanks to the following, who submitted detailed bug reports and excellent sugges
|
|||
Rafael Oliveira
|
||||
agentcoffee
|
||||
eq0cdk
|
||||
squirrellyDave
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
(thanks to Shaun Ruffel)
|
||||
- #441 Return report return code
|
||||
(thanks to lospatchos)
|
||||
- #450 Report 'totals.py' does not display data when no time range specified
|
||||
(thanks to squirrellyDave)
|
||||
- #458 Add man documentation for configuring tag colors.
|
||||
(thanks to Lim Ding Wen)
|
||||
- #463 Add colors to summary
|
||||
|
@ -23,8 +25,9 @@
|
|||
(Thanks to Stanisław Wysocki)
|
||||
- #491 Tracking an interval in the future while actively tracking time results in a database inconsistency
|
||||
(thanks to agentcoffee)
|
||||
- #505 report 'totals.py' does not truncate intervals to report range
|
||||
- #505 Report 'totals.py' does not truncate intervals to report range
|
||||
(thanks to eq0cdk)
|
||||
|
||||
------ current release ---------------------------
|
||||
|
||||
1.4.3 (2021-05-28) - fc618636aacba6e52d447b482aeef58b375dfc8c
|
||||
|
|
|
@ -69,33 +69,59 @@ def calculate_totals(input_stream):
|
|||
else:
|
||||
body += line
|
||||
|
||||
if "temp.report.start" not in configuration:
|
||||
return ["There is no data in the database"]
|
||||
j = json.loads(body)
|
||||
|
||||
if "temp.report.start" in configuration:
|
||||
report_start_utc = datetime.datetime.strptime(configuration["temp.report.start"], DATEFORMAT)
|
||||
report_start_utc = report_start_utc.replace(tzinfo=from_zone)
|
||||
report_start = report_start_utc.astimezone(tz=to_zone)
|
||||
else:
|
||||
report_start_utc = None
|
||||
report_start = None
|
||||
|
||||
if "temp.report.end" in configuration:
|
||||
report_end_utc = datetime.datetime.strptime(configuration["temp.report.end"], DATEFORMAT)
|
||||
report_end_utc = report_end_utc.replace(tzinfo=from_zone)
|
||||
report_end = report_end_utc.astimezone(to_zone)
|
||||
else:
|
||||
report_end_utc = datetime.datetime.now(tz=from_zone)
|
||||
report_end = report_end_utc.astimezone(tz=to_zone)
|
||||
else:
|
||||
report_end_utc = None
|
||||
report_end = None
|
||||
|
||||
if len(j) == 0:
|
||||
if report_start is not None and report_end is not None:
|
||||
return ["No data in the range {:%Y-%m-%d %H:%M:%S} - {:%Y-%m-%d %H:%M:%S}".format(report_start, report_end)]
|
||||
elif report_start is None and report_end is not None:
|
||||
return ["No data in the range until {:%Y-%m-%d %H:%M:%S}".format(report_end)]
|
||||
elif report_start is not None and report_end is None:
|
||||
return ["No data in the range since {:%Y-%m-%d %H:%M:%S}".format(report_start)]
|
||||
else:
|
||||
return ["No data to display"]
|
||||
|
||||
if "start" in j[0]:
|
||||
if report_start_utc is not None:
|
||||
j[0]["start"] = max(report_start_utc, datetime.datetime.strptime(j[0]["start"], DATEFORMAT).replace(tzinfo=from_zone)).strftime(DATEFORMAT)
|
||||
else:
|
||||
return ["Cannot display an past open range"]
|
||||
|
||||
if "end" in j[-1]:
|
||||
if report_end_utc is not None:
|
||||
j[-1]["end"] = min(report_end_utc, datetime.datetime.strptime(j[-1]["end"], DATEFORMAT).replace(tzinfo=from_zone)).strftime(DATEFORMAT)
|
||||
else:
|
||||
report_end = datetime.datetime.strptime(j[-1]["end"], DATEFORMAT).replace(tzinfo=from_zone)
|
||||
else:
|
||||
if report_end_utc is not None:
|
||||
j[-1]["end"] = report_end_utc.strftime(DATEFORMAT)
|
||||
else:
|
||||
j[-1]["end"] = datetime.datetime.now(tz=from_zone).strftime(DATEFORMAT)
|
||||
report_end = datetime.datetime.now(tz=to_zone)
|
||||
|
||||
# Sum the seconds tracked by tag.
|
||||
totals = dict()
|
||||
untagged = None
|
||||
j = json.loads(body)
|
||||
|
||||
for object in j:
|
||||
start = max(report_start_utc, datetime.datetime.strptime(object["start"], DATEFORMAT).replace(tzinfo=from_zone))
|
||||
|
||||
if "end" in object:
|
||||
end = min(report_end_utc, datetime.datetime.strptime(object["end"], DATEFORMAT).replace(tzinfo=from_zone))
|
||||
else:
|
||||
end = min(report_end_utc, datetime.datetime.now(tz=from_zone))
|
||||
start = datetime.datetime.strptime(object["start"], DATEFORMAT).replace(tzinfo=from_zone)
|
||||
end = datetime.datetime.strptime(object["end"], DATEFORMAT).replace(tzinfo=from_zone)
|
||||
|
||||
tracked = end - start
|
||||
|
||||
|
@ -117,9 +143,6 @@ def calculate_totals(input_stream):
|
|||
if len(tag) > max_width:
|
||||
max_width = len(tag)
|
||||
|
||||
if len(totals) == 0 and untagged is None:
|
||||
return ["No data in the range {:%Y-%m-%d %H:%M:%S} - {:%Y-%m-%d %H:%M:%S}".format(report_start, report_end)]
|
||||
|
||||
# Compose report header.
|
||||
output = [
|
||||
"",
|
||||
|
|
|
@ -53,7 +53,7 @@ class TestTotals(TestCase):
|
|||
|
||||
out = calculate_totals(input_stream)
|
||||
|
||||
self.assertEqual(['There is no data in the database'], out)
|
||||
self.assertEqual(['No data to display'], out)
|
||||
|
||||
def test_totals_with_filled_database(self):
|
||||
"""totals extension should print report for filled database"""
|
||||
|
@ -254,7 +254,7 @@ class TestTotals(TestCase):
|
|||
|
||||
out = calculate_totals(input_stream)
|
||||
|
||||
self.assertEqual(['There is no data in the database'], out)
|
||||
self.assertEqual(['No data to display'], out)
|
||||
|
||||
def test_totals_colored_with_filled_database(self):
|
||||
"""totals extension should print report for filled database (colored)"""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue