stanwell 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. stanwell-0.1.0/.github/workflows/ci.yml +39 -0
  2. stanwell-0.1.0/.github/workflows/docs.yml +41 -0
  3. stanwell-0.1.0/.github/workflows/release.yml +50 -0
  4. stanwell-0.1.0/.gitignore +28 -0
  5. stanwell-0.1.0/.readthedocs.yaml +16 -0
  6. stanwell-0.1.0/CHANGELOG.md +23 -0
  7. stanwell-0.1.0/LICENSE +21 -0
  8. stanwell-0.1.0/Makefile +31 -0
  9. stanwell-0.1.0/PKG-INFO +17 -0
  10. stanwell-0.1.0/README.md +76 -0
  11. stanwell-0.1.0/docs/_ext/cli_commands.py +64 -0
  12. stanwell-0.1.0/docs/_static/stanwell_favicon.png +0 -0
  13. stanwell-0.1.0/docs/_static/stanwell_logo.png +0 -0
  14. stanwell-0.1.0/docs/api/index.rst +11 -0
  15. stanwell-0.1.0/docs/changelog.rst +2 -0
  16. stanwell-0.1.0/docs/cli.rst +22 -0
  17. stanwell-0.1.0/docs/conf.py +79 -0
  18. stanwell-0.1.0/docs/configuration.rst +78 -0
  19. stanwell-0.1.0/docs/dashboard.rst +55 -0
  20. stanwell-0.1.0/docs/getting_started.rst +139 -0
  21. stanwell-0.1.0/docs/index.rst +56 -0
  22. stanwell-0.1.0/docs/toggl.rst +248 -0
  23. stanwell-0.1.0/pyproject.toml +91 -0
  24. stanwell-0.1.0/src/stanwell/__init__.py +1 -0
  25. stanwell-0.1.0/src/stanwell/analysis/__init__.py +1 -0
  26. stanwell-0.1.0/src/stanwell/analysis/projections.py +167 -0
  27. stanwell-0.1.0/src/stanwell/analysis/scoring.py +231 -0
  28. stanwell-0.1.0/src/stanwell/analysis/tag_analysis.py +579 -0
  29. stanwell-0.1.0/src/stanwell/analysis/working_patterns.py +369 -0
  30. stanwell-0.1.0/src/stanwell/analysis/working_time.py +496 -0
  31. stanwell-0.1.0/src/stanwell/configuration.py +107 -0
  32. stanwell-0.1.0/src/stanwell/data_repository/__init__.py +1 -0
  33. stanwell-0.1.0/src/stanwell/data_repository/data_coverage.py +290 -0
  34. stanwell-0.1.0/src/stanwell/data_repository/data_util.py +45 -0
  35. stanwell-0.1.0/src/stanwell/data_repository/database_schema.py +172 -0
  36. stanwell-0.1.0/src/stanwell/data_repository/db.py +89 -0
  37. stanwell-0.1.0/src/stanwell/data_repository/projects.py +127 -0
  38. stanwell-0.1.0/src/stanwell/data_repository/time_entries.py +183 -0
  39. stanwell-0.1.0/src/stanwell/py.typed +0 -0
  40. stanwell-0.1.0/src/stanwell/toggl/__init__.py +1 -0
  41. stanwell-0.1.0/src/stanwell/toggl/client.py +642 -0
  42. stanwell-0.1.0/src/stanwell/toggl/constants.py +12 -0
  43. stanwell-0.1.0/src/stanwell/toggl/exceptions.py +60 -0
  44. stanwell-0.1.0/src/stanwell/toggl/normalisation.py +219 -0
  45. stanwell-0.1.0/src/stanwell/toggl/sync.py +969 -0
  46. stanwell-0.1.0/src/stanwell/ui/__init__.py +1 -0
  47. stanwell-0.1.0/src/stanwell/ui/cli/__init__.py +1 -0
  48. stanwell-0.1.0/src/stanwell/ui/cli/cli.py +680 -0
  49. stanwell-0.1.0/src/stanwell/ui/cli/cli_util.py +61 -0
  50. stanwell-0.1.0/src/stanwell/ui/dashboard/__init__.py +1 -0
  51. stanwell-0.1.0/src/stanwell/ui/dashboard/constants.py +21 -0
  52. stanwell-0.1.0/src/stanwell/ui/dashboard/context.py +223 -0
  53. stanwell-0.1.0/src/stanwell/ui/dashboard/dashboard.py +94 -0
  54. stanwell-0.1.0/src/stanwell/ui/dashboard/helpers.py +90 -0
  55. stanwell-0.1.0/src/stanwell/ui/dashboard/sidebar.py +449 -0
  56. stanwell-0.1.0/src/stanwell/ui/dashboard/tabs/__init__.py +1 -0
  57. stanwell-0.1.0/src/stanwell/ui/dashboard/tabs/overview.py +868 -0
  58. stanwell-0.1.0/src/stanwell/ui/dashboard/tabs/projects.py +273 -0
  59. stanwell-0.1.0/src/stanwell/ui/dashboard/tabs/tag_balances.py +779 -0
  60. stanwell-0.1.0/src/stanwell/ui/dashboard/tabs/work_patterns.py +960 -0
  61. stanwell-0.1.0/src/stanwell/ui/date_periods.py +86 -0
  62. stanwell-0.1.0/tests/test_stanwell/__init__.py +0 -0
  63. stanwell-0.1.0/tests/test_stanwell/analysis/__init__.py +0 -0
  64. stanwell-0.1.0/tests/test_stanwell/analysis/test_projections.py +233 -0
  65. stanwell-0.1.0/tests/test_stanwell/analysis/test_scoring.py +101 -0
  66. stanwell-0.1.0/tests/test_stanwell/analysis/test_tag_analysis.py +184 -0
  67. stanwell-0.1.0/tests/test_stanwell/analysis/test_working_patterns.py +218 -0
  68. stanwell-0.1.0/tests/test_stanwell/analysis/test_working_time.py +689 -0
  69. stanwell-0.1.0/tests/test_stanwell/conftest.py +4 -0
  70. stanwell-0.1.0/tests/test_stanwell/data_repository/__init__.py +0 -0
  71. stanwell-0.1.0/tests/test_stanwell/data_repository/test_data_coverage.py +305 -0
  72. stanwell-0.1.0/tests/test_stanwell/data_repository/test_data_util.py +76 -0
  73. stanwell-0.1.0/tests/test_stanwell/data_repository/test_database_schema.py +138 -0
  74. stanwell-0.1.0/tests/test_stanwell/data_repository/test_db.py +145 -0
  75. stanwell-0.1.0/tests/test_stanwell/data_repository/test_projects.py +224 -0
  76. stanwell-0.1.0/tests/test_stanwell/data_repository/test_time_entries.py +310 -0
  77. stanwell-0.1.0/tests/test_stanwell/integration/__init__.py +0 -0
  78. stanwell-0.1.0/tests/test_stanwell/integration/test_toggle_api.py +129 -0
  79. stanwell-0.1.0/tests/test_stanwell/pytest_util/__init__.py +0 -0
  80. stanwell-0.1.0/tests/test_stanwell/pytest_util/fixtures.py +24 -0
  81. stanwell-0.1.0/tests/test_stanwell/test_configuration.py +153 -0
  82. stanwell-0.1.0/tests/test_stanwell/toggl/__init__.py +0 -0
  83. stanwell-0.1.0/tests/test_stanwell/toggl/test_client.py +559 -0
  84. stanwell-0.1.0/tests/test_stanwell/toggl/test_exceptions.py +84 -0
  85. stanwell-0.1.0/tests/test_stanwell/toggl/test_normalisation.py +203 -0
  86. stanwell-0.1.0/tests/test_stanwell/toggl/test_sync.py +748 -0
  87. stanwell-0.1.0/tests/test_stanwell/ui/__init__.py +0 -0
  88. stanwell-0.1.0/tests/test_stanwell/ui/cli/__init__.py +0 -0
  89. stanwell-0.1.0/tests/test_stanwell/ui/cli/test_cli.py +658 -0
  90. stanwell-0.1.0/tests/test_stanwell/ui/cli/test_cli_util.py +134 -0
  91. stanwell-0.1.0/tests/test_stanwell/ui/dashboard/__init__.py +0 -0
  92. stanwell-0.1.0/tests/test_stanwell/ui/dashboard/tabs/__init__.py +0 -0
  93. stanwell-0.1.0/tests/test_stanwell/ui/dashboard/tabs/test_overview.py +605 -0
  94. stanwell-0.1.0/tests/test_stanwell/ui/dashboard/tabs/test_projects.py +353 -0
  95. stanwell-0.1.0/tests/test_stanwell/ui/dashboard/tabs/test_tag_balances.py +510 -0
  96. stanwell-0.1.0/tests/test_stanwell/ui/dashboard/tabs/test_work_patterns.py +596 -0
  97. stanwell-0.1.0/tests/test_stanwell/ui/dashboard/test_context.py +170 -0
  98. stanwell-0.1.0/tests/test_stanwell/ui/dashboard/test_dashboard.py +158 -0
  99. stanwell-0.1.0/tests/test_stanwell/ui/dashboard/test_dashboard_app.py +322 -0
  100. stanwell-0.1.0/tests/test_stanwell/ui/dashboard/test_helpers.py +100 -0
  101. stanwell-0.1.0/tests/test_stanwell/ui/dashboard/test_sidebar.py +374 -0
  102. stanwell-0.1.0/tests/test_stanwell/ui/test_date_periods.py +67 -0
  103. stanwell-0.1.0/uv.lock +2161 -0
@@ -0,0 +1,39 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ ci:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - name: Check out repository
15
+ uses: actions/checkout@v6
16
+
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v6
19
+ with:
20
+ python-version: "3.12"
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v2
24
+ with:
25
+ version: "latest"
26
+
27
+ - name: Cache uv
28
+ uses: actions/cache@v4
29
+ with:
30
+ path: ~/.cache/uv
31
+ key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }}
32
+ restore-keys: |
33
+ ${{ runner.os }}-uv-
34
+
35
+ - name: Install dependencies
36
+ run: uv sync --dev
37
+
38
+ - name: Run CI checks
39
+ run: make ci
@@ -0,0 +1,41 @@
1
+ name: Documentation
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ branches:
9
+ - main
10
+
11
+ jobs:
12
+ build-docs:
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - name: Check out repository
17
+ uses: actions/checkout@v6
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v6
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Install uv
25
+ uses: astral-sh/setup-uv@v2
26
+ with:
27
+ version: "latest"
28
+
29
+ - name: Cache uv
30
+ uses: actions/cache@v4
31
+ with:
32
+ path: ~/.cache/uv
33
+ key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }}
34
+ restore-keys: |
35
+ ${{ runner.os }}-uv-
36
+
37
+ - name: Install dependencies
38
+ run: uv sync --all-groups
39
+
40
+ - name: Build documentation
41
+ run: make docs-check
@@ -0,0 +1,50 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - name: Check out repository
13
+ uses: actions/checkout@v6
14
+
15
+ - name: Set up Python
16
+ uses: actions/setup-python@v6
17
+ with:
18
+ python-version: "3.12"
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v2
22
+
23
+ - name: Build package
24
+ run: uv build
25
+
26
+ - name: Upload distributions
27
+ uses: actions/upload-artifact@v4
28
+ with:
29
+ name: python-package-distributions
30
+ path: dist/
31
+
32
+ publish:
33
+ needs: build
34
+ runs-on: ubuntu-latest
35
+
36
+ environment:
37
+ name: pypi
38
+
39
+ permissions:
40
+ id-token: write
41
+
42
+ steps:
43
+ - name: Download distributions
44
+ uses: actions/download-artifact@v5
45
+ with:
46
+ name: python-package-distributions
47
+ path: dist/
48
+
49
+ - name: Publish package
50
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,28 @@
1
+ # Stanwell user data
2
+ config.yml
3
+ config.yaml
4
+ *.db
5
+ *.sqlite
6
+ *.sqlite3
7
+
8
+ # Secrets
9
+ .env
10
+ .env.*
11
+
12
+ # Python
13
+ __pycache__/
14
+ .venv/
15
+
16
+ # Sphinx
17
+ docs/_build/
18
+ docs/_latex/
19
+ docs/api/generated
20
+
21
+ # Testing
22
+ .env.integration
23
+
24
+ # Pycharm
25
+ .idea/
26
+
27
+ # Emacs
28
+ *~
@@ -0,0 +1,16 @@
1
+ version: 2
2
+
3
+ build:
4
+ os: ubuntu-24.04
5
+ tools:
6
+ python: "3.12"
7
+
8
+ sphinx:
9
+ configuration: docs/conf.py
10
+
11
+ python:
12
+ install:
13
+ - method: pip
14
+ path: .
15
+ extra_requirements:
16
+ - docs
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ ## [0.1.0] - 2026-11-04
4
+ Initial public release
5
+
6
+ <!---
7
+ TEMPLATE
8
+ ## [Unreleased]
9
+
10
+ ## [0.0.0] - 20XX-XX-XX
11
+ ### Added
12
+ - AAA
13
+ ### Changed
14
+ - BBB
15
+ ### Deprecated
16
+ - CCC
17
+ ### Removed
18
+ - DDD
19
+ ### Fixed
20
+ - EEE
21
+ ### Security
22
+ - FFF
23
+ -->
stanwell-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jan Buermann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,31 @@
1
+ .PHONY: test lint format docs docs-clean docs-check tidy ci
2
+
3
+ test:
4
+ uv run pytest
5
+
6
+ lint:
7
+ uv run ruff check . --fix
8
+
9
+ format:
10
+ uv run black src tests
11
+
12
+ docs:
13
+ rm -f docs/api/generated/*.rst
14
+ uv run sphinx-build -M html docs docs/_build
15
+
16
+ docs-clean:
17
+ rm -rf docs/api/generated
18
+ rm -rf docs/_build
19
+ uv run sphinx-build -M html docs docs/_build
20
+
21
+ docs-check:
22
+ uv run sphinx-build -W --keep-going -b html docs docs/_build/html
23
+
24
+ tidy: lint format
25
+
26
+ ci:
27
+ uv run pytest
28
+ uv run ruff check .
29
+ uv run mypy -p stanwell
30
+ uv lock --locked
31
+ uv run black --check src tests
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.5
2
+ Name: stanwell
3
+ Version: 0.1.0
4
+ Summary: Application to helps understand working time and distribution based on Toggl time tracking data.
5
+ Author: Jan Buermann
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.12
9
+ Requires-Dist: loguru>=0.7.3
10
+ Requires-Dist: matplotlib>=3.11.2
11
+ Requires-Dist: numpy>=2.5.3
12
+ Requires-Dist: pandas>=3.0.6
13
+ Requires-Dist: python-dateutil>=2.9.0.post0
14
+ Requires-Dist: pyyaml>=6.0.3
15
+ Requires-Dist: seaborn>=0.13.2
16
+ Requires-Dist: streamlit>=1.64.0
17
+ Requires-Dist: typer>=0.27.2
@@ -0,0 +1,76 @@
1
+ [![CI](https://github.com/jbuerman/stanwell/actions/workflows/ci.yml/badge.svg)](https://github.com/jbuerman/stanwell/actions/workflows/ci.yml)
2
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
3
+
4
+ # Stanwell
5
+
6
+ *Have enthusiasm. Work sustainably.*
7
+
8
+ Stanwell analyses working time recorded in Toggl to help you understand how much you work and how that time is distributed across projects, activities and working patterns.
9
+
10
+ ## Quick setup
11
+
12
+ Initialise Stanwell:
13
+
14
+ ```bash
15
+ stanwell init
16
+ ```
17
+
18
+ Synchronise historical data. Repeat until all missing data has been downloaded:
19
+
20
+ ```bash
21
+ stanwell sync-missing
22
+ ```
23
+
24
+ Refresh recent entries when needed:
25
+
26
+ ```bash
27
+ stanwell refresh-recent
28
+ ```
29
+
30
+ Open the interactive dashboard:
31
+
32
+ ```bash
33
+ stanwell dashboard
34
+ ```
35
+
36
+ ## Development
37
+
38
+ ```bash
39
+ uv sync --all-groups
40
+ ```
41
+
42
+ Format and lint the project:
43
+
44
+ ```bash
45
+ uv run make tidy
46
+ ```
47
+
48
+ Run the CI checks locally:
49
+
50
+ ```bash
51
+ uv run make ci
52
+ ```
53
+
54
+ ### Documentation
55
+
56
+ Build the Sphinx documentation:
57
+
58
+ ```bash
59
+ uv run make docs
60
+ ```
61
+
62
+ Open `docs/_build/html/index.html` to view the generated documentation.
63
+
64
+ ### Integration tests
65
+
66
+ Create an environment file containing an API token and workspace ID using `.env.integration.example` as a template.
67
+
68
+ Then run:
69
+
70
+ ```bash
71
+ uv run --env-file .env.integration pytest -m integration
72
+ ```
73
+
74
+ ## Licence
75
+
76
+ Stanwell is released under the [MIT Licence](LICENSE).
@@ -0,0 +1,64 @@
1
+ """Generate CLI command documentation from the Typer application."""
2
+
3
+ from docutils import nodes
4
+ from docutils.parsers.rst import Directive
5
+
6
+ from stanwell.ui.cli.cli import app
7
+
8
+
9
+ class CliCommandsDirective(Directive):
10
+ """Render registered Typer commands as a definition list."""
11
+
12
+ has_content = False
13
+
14
+ def run(self) -> list[nodes.Node]:
15
+ """Build the definition list containing the registered CLI commands."""
16
+ definition_list = nodes.definition_list()
17
+
18
+ for command_info in app.registered_commands:
19
+ command_name = command_info.name
20
+ command_help = command_info.help
21
+ callback = command_info.callback
22
+
23
+ if command_name is None or callback is None:
24
+ continue
25
+
26
+ target = (
27
+ f"{callback.__module__}."
28
+ f"{callback.__name__}"
29
+ )
30
+
31
+ item = nodes.definition_list_item()
32
+ term = nodes.term()
33
+
34
+ reference_nodes, messages = self.state.inline_text(
35
+ f":py:func:`{command_name} <{target}>`",
36
+ self.lineno,
37
+ )
38
+ term.extend(reference_nodes)
39
+
40
+ definition = nodes.definition()
41
+ definition += nodes.paragraph(
42
+ text=command_help or "",
43
+ )
44
+
45
+ item += term
46
+ item += definition
47
+ definition_list += item
48
+
49
+ definition_list.extend(messages)
50
+
51
+ return [definition_list]
52
+
53
+
54
+ def setup(app):
55
+ """Register the CLI command directive."""
56
+ app.add_directive(
57
+ "cli-commands",
58
+ CliCommandsDirective,
59
+ )
60
+
61
+ return {
62
+ "parallel_read_safe": True,
63
+ "parallel_write_safe": True,
64
+ }
@@ -0,0 +1,11 @@
1
+ API Reference
2
+ =============
3
+
4
+ This reference documents the public packages, modules, classes and functions
5
+ provided by Stanwell.
6
+
7
+ .. autosummary::
8
+ :toctree: generated
9
+ :recursive:
10
+
11
+ stanwell
@@ -0,0 +1,2 @@
1
+ .. include:: ../CHANGELOG.md
2
+ :parser: myst_parser.sphinx_
@@ -0,0 +1,22 @@
1
+ Command-line interface
2
+ ======================
3
+
4
+ The ``stanwell`` command is used to set up Stanwell,
5
+ maintain the local copy of your Toggl data and launch the dashboard.
6
+
7
+ Commands
8
+ --------
9
+
10
+ .. cli-commands::
11
+
12
+ Use the built-in help at any time:
13
+
14
+ .. code-block:: console
15
+
16
+ stanwell --help
17
+
18
+ Help for an individual command is available in the same way:
19
+
20
+ .. code-block:: console
21
+
22
+ stanwell COMMAND --help
@@ -0,0 +1,79 @@
1
+
2
+ import os
3
+ import sys
4
+ import tomllib
5
+ from datetime import date
6
+ from pathlib import Path
7
+
8
+ DOCS_DIR = Path(__file__).parent
9
+ sys.path.insert(
10
+ 0,
11
+ str(DOCS_DIR / "_ext"),
12
+ )
13
+
14
+ PROJECT_ROOT = os.path.abspath(os.path.join(__file__, "..", ".."))
15
+ sys.path.insert(0, os.path.join(PROJECT_ROOT, "src"))
16
+
17
+ def authors_to_comma_list(pyproject_data, include_emails=False):
18
+ """Convert PEP 621 authors into a comma-separated string."""
19
+ authors = pyproject_data.get("project", {}).get("authors", []) or []
20
+ parts = []
21
+
22
+ for a in authors:
23
+ if isinstance(a, dict):
24
+ name = (a.get("name") or "").strip()
25
+ email = (a.get("email") or "").strip()
26
+ if name or email:
27
+ if include_emails and name and email:
28
+ parts.append(f"{name} <{email}>")
29
+ elif name:
30
+ parts.append(name)
31
+ elif email:
32
+ parts.append(f"<{email}>")
33
+ elif isinstance(a, str):
34
+ s = a.strip()
35
+ if s:
36
+ parts.append(s)
37
+ return ", ".join(parts)
38
+
39
+ with open(os.path.join(PROJECT_ROOT, "pyproject.toml"), "rb") as f:
40
+ pyproject_data = tomllib.load(f)
41
+ project_version = pyproject_data.get("project", {}).get("version", "-")
42
+ project_name = pyproject_data.get("project", {}).get("name", "-")
43
+
44
+ project = project_name
45
+ author = authors_to_comma_list(pyproject_data, include_emails=False)
46
+ copyright = f"{date.today().year}, {author}"
47
+ release = project_version
48
+ version = project_version
49
+
50
+ extensions = [
51
+ "sphinx.ext.autodoc",
52
+ "sphinx.ext.napoleon",
53
+ "sphinx.ext.autosummary",
54
+ "sphinx.ext.intersphinx",
55
+ "sphinx.ext.viewcode",
56
+ "sphinx_paramlinks",
57
+ "myst_parser",
58
+ "cli_commands",
59
+ ]
60
+
61
+ autosummary_generate = True
62
+
63
+ autodoc_typehints = "signature"
64
+
65
+ autodoc_default_options = {
66
+ "members": True,
67
+ "undoc-members": False,
68
+ "show-inheritance": True,
69
+ }
70
+
71
+ intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}
72
+ templates_path = ["_templates"]
73
+ exclude_patterns = []
74
+ html_static_path = ["_static"]
75
+
76
+ html_theme = 'sphinx_rtd_theme'
77
+
78
+ html_logo = "_static/stanwell_logo.png"
79
+ html_favicon = "_static/stanwell_favicon.png"
@@ -0,0 +1,78 @@
1
+ Configuration
2
+ =============
3
+
4
+ Stanwell uses a YAML configuration file to describe your
5
+ working pattern, local database and Toggl connection.
6
+
7
+ By default, the command-line interface looks for:
8
+
9
+ .. code-block:: text
10
+
11
+ ~/.config/stanwell/config.yaml
12
+
13
+ A different configuration file can be selected with the global
14
+ `--config` (or `-c`) option.
15
+
16
+ Working pattern
17
+ ---------------
18
+
19
+ The configuration describes how the application should interpret your
20
+ recorded time. Important settings include:
21
+
22
+ `workday_hours`
23
+ The number of hours in a standard working day.
24
+
25
+ `working_days`
26
+ The weekdays on which work is normally required.
27
+
28
+ `core_start` and `core_end`
29
+ The normal core-hours interval used when analysing working patterns.
30
+
31
+ `timezone`
32
+ The timezone used when interpreting recorded time.
33
+
34
+ `tracking_start_date`
35
+ The date from which working-time tracking begins.
36
+
37
+ For example:
38
+
39
+ .. code-block:: yaml
40
+
41
+ workday_hours: 7.5
42
+ working_days: [0, 1, 2, 3, 4]
43
+ timezone: Europe/London
44
+ core_start: "10:00"
45
+ core_end: "16:00"
46
+
47
+ Exception days
48
+ --------------
49
+
50
+ Exception days represent dates on which the normal working pattern does not
51
+ apply.
52
+
53
+ The standard exception types are:
54
+
55
+ `annual_leave`
56
+ Annual leave.
57
+
58
+ `sick`
59
+ Sick leave.
60
+
61
+ `public_holiday`
62
+ A public holiday.
63
+
64
+ `closure_day`
65
+ An organisation closure day.
66
+
67
+ `overtime_compensation`
68
+ Time taken off in lieu of overtime.
69
+
70
+ Annual leave, sickness, public holidays and closure days remove the normal
71
+ working-time requirement for that day.
72
+
73
+ Overtime compensation also removes the normal requirement, but differs in
74
+ one important respect: the compensated hours are deducted from the accumulated
75
+ working-time balance.
76
+
77
+ This allows a day taken in lieu to offset additional time worked previously,
78
+ rather than appearing simply as another non-working day.
@@ -0,0 +1,55 @@
1
+ Dashboard
2
+ =========
3
+
4
+ The interactive dashboard turns the locally stored time entries into a set
5
+ of views of your working time.
6
+
7
+ Open it from the command line:
8
+
9
+ .. code-block:: console
10
+
11
+ stanwell dashboard
12
+
13
+ The date controls in the dashboard determine the period used for most
14
+ analyses.
15
+
16
+ Overview
17
+ --------
18
+
19
+ The Overview brings together the main working-time measures.
20
+
21
+ It shows recorded and required working time, working-time balance and
22
+ overtime compensation. Daily and weekly views make shorter-term variation
23
+ visible, while the longer-term balance view shows how additional work,
24
+ shortfalls and overtime compensation affect the accumulated balance.
25
+
26
+ The Overview also provides a weekday view to help identify differences in
27
+ working time across the week.
28
+
29
+ Projects
30
+ --------
31
+
32
+ The Projects tab shows how recorded working time is distributed between
33
+ projects.
34
+
35
+ This is useful for understanding where working time has gone during the
36
+ selected period rather than considering total working hours alone.
37
+
38
+ Working patterns
39
+ ----------------
40
+
41
+ The Working patterns tab focuses on when work takes place.
42
+
43
+ It helps make patterns such as work outside core hours and work on
44
+ designated days off visible. These measures complement the simple
45
+ working-time balance: working the expected number of hours does not
46
+ necessarily mean those hours are distributed in a healthy way.
47
+
48
+ Tag balance
49
+ -----------
50
+
51
+ The Tag balance tab uses tags attached to Toggl entries to explore categories
52
+ of activity across the selected period.
53
+
54
+ Tags can overlap, so tagged time should be interpreted as different views of
55
+ the same recorded time rather than necessarily additive categories.