Skip to content

Commit

Permalink
add setting to specify user timezone (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
viseshrp authored Apr 7, 2023
1 parent fc7ed1a commit 997a57a
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 22 deletions.
10 changes: 7 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# History

## 0.7.0 (2023-04-05)
## 0.7.0 (2023-04-06)

- fix usage of date/time formatting
- add option and environment variable alternative for settings.
- add setting to specify timezone for display
- setting : `TIME_ZONE`
- option: `--time-zone <value>`
- environment variable: `WORKEDON_TIME_ZONE`
- add option and environment variable alternative for settings
- BREAKING (for advanced users only): removed the `db` and `conf`
subcommands and moved their options under the main `workedon`
command to free up reserved keywords `db` and `conf`.
Expand All @@ -13,6 +16,7 @@
- `workedon db --version` is now `workedon --db-version`
- `workedon conf --print-path` is now `workedon --print-settings-path`
- `workedon conf --print` is now `workedon --print-settings`
- fix usage of date/time formatting

## 0.6.3 (2023-04-02)

Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ The currently available settings are:
- Setting this overrides `DATE_FORMAT` and `TIME_FORMAT`.
- Option: `--datetime-format <value>`
- Environment variable: `WORKEDON_DATETIME_FORMAT`
- `TIME_ZONE` : Sets the time zone of the output.
- Must be a valid
[timezone string](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
- Default is the auto-detected timezone using the
[tzlocal](https://github.com/regebro/tzlocal) library.
- Option: `--time-zone <value>`
- Environment variable: `WORKEDON_TIME_ZONE`

Order of priority is Option > Environment variable > Setting.

Expand Down Expand Up @@ -193,6 +200,8 @@ Options:
Python strftime string.
--datetime-format TEXT Sets the datetime format of the output. Must be a
valid Python strftime string.
--time-zone TEXT Sets the timezone of the output. Must be a valid
timezone string.
--help Show this message and exit.
```
<!-- [[[end]]] -->
Expand Down
21 changes: 20 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import re

from click.testing import CliRunner
import dateparser
import pytest

from workedon import __version__, cli, exceptions
Expand Down Expand Up @@ -153,6 +152,26 @@ def test_save_and_fetch_date_opt_env(opt, env, monkeypatch, cleanup):
assert date_object.year != datetime.now().year


@pytest.mark.parametrize(
"opt, env",
[
("", "WORKEDON_TIME_ZONE"),
("--time-zone", ""),
],
)
def test_save_and_fetch_timezone_opt_env(opt, env, monkeypatch, cleanup):
result = CliRunner().invoke(cli.main, ["testing timezone opt"])
assert result.output.startswith("Work saved.")
tz = "Asia/Tokyo"
if env:
monkeypatch.setenv(env, tz)
opts = []
if opt:
opts = [opt, tz]
result = CliRunner().invoke(cli.what, opts)
assert "JST" in result.output


@pytest.mark.parametrize(
"work, option",
[
Expand Down
9 changes: 9 additions & 0 deletions workedon/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ def settings_options(func):
envvar="WORKEDON_DATETIME_FORMAT",
help="Sets the datetime format of the output. Must be a valid Python strftime string.",
)
@click.option(
"--time-zone",
"TIME_ZONE",
required=False,
default="",
type=click.STRING,
envvar="WORKEDON_TIME_ZONE",
help="Sets the timezone of the output. Must be a valid timezone string.",
)
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
Expand Down
1 change: 0 additions & 1 deletion workedon/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class Settings(dict):
# upper case settings are user-configurable
def __init__(self):
super().__init__()
self.user_tz = str(get_localzone()) # for user display
self.internal_tz = "UTC" # for internal storage and manipulation
self.internal_dt_format = "%Y-%m-%d %H:%M:%S%z"

Expand Down
3 changes: 3 additions & 0 deletions workedon/default_settings.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from tzlocal import get_localzone

DATE_FORMAT = "%a %b %d %Y"
TIME_FORMAT = "%H:%M %z %Z"
DATETIME_FORMAT = ""
TIME_ZONE = str(get_localzone())
2 changes: 1 addition & 1 deletion workedon/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def __str__(self):
Uses a git log like structure.
"""
if self.timestamp and self.uuid:
user_time = self.timestamp.astimezone(zoneinfo.ZoneInfo(settings.user_tz))
user_time = self.timestamp.astimezone(zoneinfo.ZoneInfo(settings.TIME_ZONE))
timestamp = user_time.strftime(
settings.DATETIME_FORMAT
if settings.DATETIME_FORMAT
Expand Down
21 changes: 8 additions & 13 deletions workedon/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@


class InputParser:
LANGUAGES = ["en"]
DATE_PARSER_SETTINGS = {
"STRICT_PARSING": False,
"NORMALIZE": True,
"RETURN_AS_TIMEZONE_AWARE": True,
"PREFER_DATES_FROM": "past",
"RELATIVE_BASE": now(),
}

def __init__(self):
self._date_parser = DateDataParser(
languages=self.LANGUAGES, settings=self.DATE_PARSER_SETTINGS
languages=["en"],
settings={
"STRICT_PARSING": False,
"NORMALIZE": True,
"RETURN_AS_TIMEZONE_AWARE": True,
"PREFER_DATES_FROM": "past",
"RELATIVE_BASE": now(),
},
)

def _as_datetime(self, date_time):
Expand Down Expand Up @@ -46,6 +44,3 @@ def parse(self, work_desc):
raise InvalidWorkError
date_time = self.parse_datetime(date_time)
return work, date_time


parser = InputParser()
2 changes: 1 addition & 1 deletion workedon/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def now():
"""
Current datetime in user's local timezone
"""
return datetime.now(zoneinfo.ZoneInfo(settings.user_tz))
return datetime.now(zoneinfo.ZoneInfo(settings.TIME_ZONE))


def get_default_time():
Expand Down
5 changes: 3 additions & 2 deletions workedon/workedon.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
StartDateGreaterError,
)
from .models import Work, init_db
from .parser import parser
from .parser import InputParser
from .utils import now, to_internal_dt

try:
Expand All @@ -27,7 +27,7 @@ def save_work(work):
Save work from user input
"""
work_desc = " ".join(work).strip()
text, dt = parser.parse(work_desc)
text, dt = InputParser().parse(work_desc)
data = {"work": text}
if dt:
data["timestamp"] = to_internal_dt(dt)
Expand All @@ -50,6 +50,7 @@ def _generate_work(result):


def _get_date_range(start_date, end_date, since, period, on, at):
parser = InputParser()
curr_dt = now()
# past week is the default
start = curr_dt - datetime.timedelta(days=7)
Expand Down

0 comments on commit 997a57a

Please sign in to comment.