From 5cdf1c41e0ab382d6f0eb442bc32d8fdf7cc626c Mon Sep 17 00:00:00 2001 From: Pedro Rivotti <44579232+pedrorivotti@users.noreply.github.com> Date: Fri, 4 Jan 2019 17:05:35 +0000 Subject: [PATCH] Add option to specify start of the week (#240) * Add function that offsets week start * Apply offset when week option is used * Add tests * Update configuration docs * Add default fallback value --- docs/user-guide/configuration.md | 8 ++++++++ tests/test_utils.py | 22 ++++++++++++++++++++-- watson/cli.py | 14 +++++++++++--- watson/utils.py | 17 +++++++++++++++++ 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/docs/user-guide/configuration.md b/docs/user-guide/configuration.md index 9b5a7656..a3f5c987 100644 --- a/docs/user-guide/configuration.md +++ b/docs/user-guide/configuration.md @@ -149,6 +149,13 @@ Globally configure how `dates` should be formatted. All [python's `strftime` dir Globally configure how `time` should be formatted. All [python's `strftime` directives](http://strftime.org) are supported. +#### `options.week_start` + +Globally configure which day corresponds to the start of a week. Allowable +values are `monday` (default), `tuesday`, `wednesday`, `thursday`, `friday`, + `saturday`, and `sunday`. + + ### Default tags Tags can be automatically added for selected projects. This is convenient when @@ -211,6 +218,7 @@ stop_on_start = true stop_on_restart = false date_format = %Y.%m.%d time_format = %H:%M:%S%z +week_start = monday log_current = false pager = true report_current = false diff --git a/tests/test_utils.py b/tests/test_utils.py index 1d77cea6..021e82f0 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """Unit tests for the 'utils' module.""" +import arrow import functools import os import datetime @@ -13,8 +14,8 @@ import pytest from dateutil.tz import tzutc -from watson.utils import (get_start_time_for_period, make_json_writer, - safe_save, parse_tags, PY2) +from watson.utils import (apply_weekday_offset, get_start_time_for_period, + make_json_writer, safe_save, parse_tags, PY2) from . import mock_datetime @@ -41,6 +42,23 @@ def test_get_start_time_for_period(now, mode, start_time): assert get_start_time_for_period(mode).datetime == start_time +@pytest.mark.parametrize("monday_start, week_start, new_start", [ + ("2018 12 3", "monday", "2018 12 3"), + ("2018 12 3", "tuesday", "2018 12 4"), + ("2018 12 3", "wednesday", "2018 12 5"), + ("2018 12 3", "thursday", "2018 12 6"), + ("2018 12 3", "friday", "2018 11 30"), + ("2018 12 3", "saturday", "2018 12 1"), + ("2018 12 3", "sunday", "2018 12 2"), + ("2018 12 3", "typo", "2018 12 3"), +]) +def test_apply_weekday_offset(monday_start, week_start, new_start): + with mock_datetime(_dt(2018, 12, 6), datetime): + original_start = arrow.get(monday_start, "YYYY MM D") + result = arrow.get(new_start, "YYYY MM D") + assert apply_weekday_offset(original_start, week_start) == result + + def test_make_json_writer(): fp = StringIO() writer = make_json_writer(lambda: {'foo': 42}) diff --git a/watson/cli.py b/watson/cli.py index 17bb05fc..7b0b1bd4 100644 --- a/watson/cli.py +++ b/watson/cli.py @@ -14,9 +14,9 @@ from . import watson as _watson from .frames import Frame -from .utils import (format_timedelta, get_frame_from_argument, - get_start_time_for_period, options, safe_save, - sorted_groupby, style, parse_tags) +from .utils import (apply_weekday_offset, format_timedelta, + get_frame_from_argument, get_start_time_for_period, + options, safe_save, sorted_groupby, style, parse_tags) class MutuallyExclusiveOption(click.Option): @@ -57,6 +57,14 @@ def convert(self, value, param, ctx): # expected by the user, so that midnight is midnight in the local # timezone, not in UTC. Cf issue #16. date.tzinfo = tz.tzlocal() + + # Add an offset to match the week beginning specified in the + # configuration + if param.name == "week": + week_start = ctx.obj.config.get( + "options", "week_start", "monday") + date = apply_weekday_offset( + start_time=date, week_start=week_start) return date diff --git a/watson/utils.py b/watson/utils.py index 16250420..3b46b6a9 100644 --- a/watson/utils.py +++ b/watson/utils.py @@ -161,6 +161,23 @@ def get_start_time_for_period(period): return start_time +def apply_weekday_offset(start_time, week_start): + """ + Apply the offset required to move the start date `start_time` of a week + starting on Monday to that of a week starting on `week_start`. + """ + weekdays = dict(zip( + ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", + "sunday"], range(0, 7))) + + new_start = week_start.lower() + if new_start not in weekdays: + return start_time + now = datetime.datetime.now() + offset = weekdays[new_start] - 7 * (weekdays[new_start] > now.weekday()) + return start_time.replace(days=offset) + + def make_json_writer(func, *args, **kwargs): """ Return a function that receives a file-like object and writes the return