Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,18 @@ API Reference
=============

This section documents the internal Python API.

.. automodule:: worktimer.core.database
:members:
:undoc-members:
:show-inheritance:

.. automodule:: worktimer.core.worktimer
:members:
:undoc-members:
:show-inheritance:

.. automodule:: worktimer.core.util
:members:
:undoc-members:
:show-inheritance:
46 changes: 46 additions & 0 deletions tests/core/test_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import pytest

from worktimer.core import util


class TestGetAppDir:

def setup_method(self):
self.app_dir = util.get_app_dir()

def test_includes_app_name(self):
assert "worktimer" in self.app_dir.lower()


class TestNow:

def setup_method(self):
self.now = util.now()

def test_no_microseconds(self):
assert self.now.microsecond == 0


@pytest.mark.parametrize(
"input,expected",
[
(-1, "N/A"),
(0, "Monday"),
(1, "Tuesday"),
(2, "Wednesday"),
(3, "Thursday"),
(4, "Friday"),
(5, "Saturday"),
(6, "Sunday"),
(7, "N/A"),
],
)
class TestWeekdayName:

def test_full_name(self, input, expected):
result = util.weekday_name(input)
assert result == expected

def test_abbreviation(self, input, expected):
result = util.weekday_name(input, True)
assert result == expected[:3]
12 changes: 11 additions & 1 deletion worktimer/cli/cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import click

from worktimer.cli.commands import register_commands


@click.group()
@click.version_option(
Expand All @@ -8,4 +10,12 @@
)
def cli():
"""WorkTimer: Simple tracker of time spent at work"""
pass
from worktimer.core import util

if not util.make_app_dir():
msg = f"ERROR: Failed to create app directory: `{util.get_app_dir()}`"
click.echo(msg)
raise click.Abort()


register_commands(cli)
1 change: 1 addition & 0 deletions worktimer/cli/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .util import register_commands
26 changes: 26 additions & 0 deletions worktimer/cli/commands/day.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from datetime import datetime

import click


@click.command
@click.option(
"-d",
"--date",
help="The date to display, in YYYY-MM-DD format [default: today's date]",
default=lambda: datetime.now().isoformat(),
)
def day(date: str):
"""Display detailed time worked on a given day"""
from .util import create_worktimer

try:
dt = datetime.fromisoformat(date)
except ValueError:
error = click.BadParameter("Format must be YYYY-MM-DD")
error.param_hint = "date"
raise error

wt = create_worktimer()
msg = wt.get_daily_time_worked(dt)
click.echo(msg)
11 changes: 11 additions & 0 deletions worktimer/cli/commands/start.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import click


@click.command
def start():
"""Start the work timer"""
from .util import create_worktimer

wt = create_worktimer()
msg = wt.log_work_start()
click.echo(msg)
11 changes: 11 additions & 0 deletions worktimer/cli/commands/stop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import click


@click.command
def stop():
"""Stop the work timer"""
from .util import create_worktimer

wt = create_worktimer()
msg = wt.log_work_end()
click.echo(msg)
38 changes: 38 additions & 0 deletions worktimer/cli/commands/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
Command utility functions
"""


def create_worktimer():
"""
Create a ready-to-use WorkTimer

:return: A WorkTimer with database and other dependencies already
set up.
:rtype: :class:`worktimer.core.worktimer.WorkTimer`
"""
from worktimer.core import const
from worktimer.core.database import Database
from worktimer.core.worktimer import WorkTimer

db = Database(const.PATH_DB)
wt = WorkTimer(db)
return wt


def register_commands(cli):
"""
Register all commands with the top-level Click group

:param cli: The top-level Click group to hold the commands.
:type cli: :class:`click.Group`
"""
from .day import day
from .start import start
from .stop import stop
from .week import week

cli.add_command(start)
cli.add_command(stop)
cli.add_command(day)
cli.add_command(week)
26 changes: 26 additions & 0 deletions worktimer/cli/commands/week.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from datetime import datetime

import click


@click.command
@click.option(
"-d",
"--date",
help="The date to display, in YYYY-MM-DD format [default: today's date]",
default=lambda: datetime.now().isoformat(),
)
def week(date: str):
"""Display time worked on each day in a given week"""
from .util import create_worktimer

try:
dt = datetime.fromisoformat(date)
except ValueError:
error = click.BadParameter("Format must be YYYY-MM-DD")
error.param_hint = "date"
raise error

wt = create_worktimer()
msg = wt.get_weekly_time_worked(dt)
click.echo(msg)
Empty file added worktimer/core/__init__.py
Empty file.
12 changes: 12 additions & 0 deletions worktimer/core/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""
Application-wide constants
"""

import os

from worktimer.core import util


PATH_APP = util.get_app_dir()
PATH_CONFIG = os.path.join(PATH_APP, "config.json")
PATH_DB = os.path.join(PATH_APP, "worktimer.db")
Loading