Skip to content

Commit

Permalink
Reports for all projects (trak report all)
Browse files Browse the repository at this point in the history
  • Loading branch information
lcfd committed Oct 29, 2023
1 parent df49798 commit c5364a2
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 36 deletions.
38 changes: 2 additions & 36 deletions cli/trakcli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
)
from trakcli.database.models import Record
from trakcli.dev.commands import app as dev_app
from trakcli.report.commands import app as report_app
from trakcli.initialize import initialize_trak
from trakcli.utils.print_with_padding import print_with_padding

Expand All @@ -44,6 +45,7 @@
)
app.add_typer(config_app, name="config", help="Interact with your configuration.")
app.add_typer(projects_app, name="projects", help="Interact with your projects.")
app.add_typer(report_app, name="report", help="See reports for your projects.")


@app.callback()
Expand Down Expand Up @@ -257,39 +259,3 @@ def status(
),
)
)


@app.command()
def report(
project: str,
when: Annotated[
str,
typer.Option(
"--when",
"-w",
help="Look for records in a specific date or range by keyword. \
Values may be: \
- today \
- yesterday \
- month: the current month \
- yyyy-mm-dd: like 2023-10-08",
),
] = "",
category: Annotated[str, typer.Option("--category", "-c")] = "",
tag: Annotated[str, typer.Option("--tag", "-t")] = "",
billable: Annotated[
bool,
typer.Option(
"--billable",
"-b",
help="Consider only the billable records.",
),
] = False,
):
"""
Report stats for projects.
"""

get_record_collection(
project=project, billable=billable, category=category, tag=tag, when=when
)
Empty file added cli/trakcli/report/__init__.py
Empty file.
198 changes: 198 additions & 0 deletions cli/trakcli/report/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# import json
# from rich.panel import Panel
# from rich.table import Table
from datetime import datetime, timedelta
import json
from typing import Annotated
from rich.panel import Panel

import typer
from trakcli.config.main import get_db_file_path

from trakcli.database.database import get_record_collection

from rich import print as rprint

from trakcli.utils.print_with_padding import print_with_padding
from trakcli.utils.same_week import same_week

# from trakcli.config.main import CONFIG_FILE_PATH, get_config, get_db_file_path
# from trakcli.config.models import Project
# from trakcli.utils.print_with_padding import print_with_padding
#
# from trakcli.projects.database import (
# get_projects_from_config,
# get_projects_from_db,
# )

app = typer.Typer()


@app.command()
def all(
billable: Annotated[
bool,
typer.Option(
"--billable",
"-b",
help="Consider only the billable records.",
),
] = False,
when: Annotated[
str,
typer.Option(
"--when",
"-w",
help="Look for records in a specific date or range by keyword. \
Values may be: \
- today \
- yesterday \
- month: the current month \
- yyyy-mm-dd: like 2023-10-08",
),
] = "",
):
"""
Report stats for all projects.
"""

db_path = get_db_file_path()

with open(db_path, "r") as db:
db_content = db.read()

parsed_json = json.loads(db_content)

grouped = {}

for record in parsed_json:
project = record.get("project", False)
if project:
del record["project"]
if isinstance(grouped.get(project, False), list):
grouped[project].append(record)
else:
grouped[project] = [record]

for g in grouped:
records = grouped[g]

if billable:
records = [
record for record in grouped[g] if record["billable"] == billable
]

if when:
if when == "yesterday":
records = [
record
for record in records
if datetime.fromisoformat(record["end"]).date()
== datetime.today().date() - timedelta(1)
]
elif when == "today":
records = [
record
for record in records
if datetime.fromisoformat(record["end"]).date()
== datetime.today().date()
]
elif when == "week":
records = [
record
for record in records
if same_week(
datetime.fromisoformat(record["end"]).date().strftime("%Y%m%d"),
)
]
elif when == "month":

def trunc_datetime(someDate):
return someDate.replace(
day=1, hour=0, minute=0, second=0, microsecond=0
)

records = [
record
for record in records
if trunc_datetime(datetime.today())
== trunc_datetime(datetime.fromisoformat(record["end"]))
]
else:
try:
records = [
record
for record in records
if datetime.fromisoformat(record["end"]).date()
== datetime.fromisoformat(when).date()
]
except Exception:
rprint(
Panel(
title="🔴 Invalid date",
renderable=print_with_padding(
"""The provided date it's invalid.
Try with a date like 2023-10-08, or the strings today, yesterday."""
),
)
)

acc_seconds = 0

for record in records:
start_datetime = datetime.fromisoformat(record["start"])
end_datetime = datetime.fromisoformat(record["end"])

diff = end_datetime - start_datetime

acc_seconds = acc_seconds + diff.seconds

m, _ = divmod(diff.seconds, 60)
h, m = divmod(m, 60)

m, _ = divmod(acc_seconds, 60)
h, m = divmod(m, 60)

sum_panel = Panel(
print_with_padding(f"[bold]{h}h {m}m[/bold]"),
title=f"🧮 Total spent time on {g}",
)

rprint(sum_panel)


@app.command()
def single(
project: str,
when: Annotated[
str,
typer.Option(
"--when",
"-w",
help="Look for records in a specific date or range by keyword. \
Values may be: \
- today \
- yesterday \
- month: the current month \
- yyyy-mm-dd: like 2023-10-08",
),
] = "",
category: Annotated[str, typer.Option("--category", "-c")] = "",
tag: Annotated[str, typer.Option("--tag", "-t")] = "",
billable: Annotated[
bool,
typer.Option(
"--billable",
"-b",
help="Consider only the billable records.",
),
] = False,
):
"""
Report stats for single projects.
"""

get_record_collection(
project=project, billable=billable, category=category, tag=tag, when=when
)

0 comments on commit c5364a2

Please sign in to comment.