Skip to content

Commit

Permalink
Merge pull request #33 from lcfd/create
Browse files Browse the repository at this point in the history
Create
  • Loading branch information
lcfd authored Dec 10, 2023
2 parents 2e4436d + 7d319f5 commit bc61030
Show file tree
Hide file tree
Showing 9 changed files with 370 additions and 119 deletions.
2 changes: 1 addition & 1 deletion cli/trakcli/config/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ class Project(NamedTuple):
categories: list[str] = []
tags: list[str] = []
customer: str = ""
hour_rate: int = 1
fare: int = 1
13 changes: 13 additions & 0 deletions cli/trakcli/create/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import typer

from trakcli.create.commands.session import create_session
from trakcli.create.commands.work import create_work
from trakcli.create.commands.project import create_project


app = typer.Typer()


app.command("session")(create_session)
app.command("work")(create_work)
app.command("project")(create_project)
Empty file.
82 changes: 82 additions & 0 deletions cli/trakcli/create/commands/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import json
import pathlib

import typer
from rich import print as rprint
from rich.panel import Panel

from trakcli.config.main import TRAK_FOLDER
from trakcli.config.models import Project
from trakcli.utils.print_with_padding import print_with_padding


def create_project(
project_id: str,
):
rprint("")
path = pathlib.Path(TRAK_FOLDER / "projects" / project_id)
files = ["details.json", "works.json", "archived_works.json"]

path.mkdir(parents=True, exist_ok=True)
details_path = path / "details.json"
details_path_exists = details_path.exists()

# Create files if not exists
for f in files:
try:
with open(path / f, "x") as file:
file.write("")
except FileExistsError:
rprint(f"The file {path / f} already exists, so it won't be created.")

if not details_path_exists:
name = typer.prompt(text="Readable name", default="")
description = typer.prompt("Description", default="")
categories = typer.prompt(
"Categories (CSV format)",
default="",
)
tags = typer.prompt("Tags (CSV format)", default="")
customer = typer.prompt("Customer", default="")
hour_rate = typer.prompt("Hour rate", default=1, show_default=True)

if project_id:
new_project = Project(
id=project_id,
name=name,
description=description,
categories=[c.strip() for c in categories.split(",")]
if categories != ""
else [],
tags=[t.strip() for t in tags.split(",")] if tags != "" else [],
customer=customer,
fare=hour_rate,
)

with open(details_path, "w") as details_file:
json.dump(
new_project._asdict(),
details_file,
indent=2,
separators=(",", ": "),
)

rprint("")
rprint(
Panel.fit(
title="[green]Success[/green]",
renderable=print_with_padding(f"Project {project_id} created."),
)
)

return
else:
rprint("")
rprint(
Panel.fit(
title="[yellow]Already exists[/yellow]",
renderable=print_with_padding(
f"Project {project_id} already has a configuration."
),
)
)
166 changes: 166 additions & 0 deletions cli/trakcli/create/commands/session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
from datetime import datetime, timedelta
from typing import Annotated, Optional

import typer
from rich import print as rprint
from rich.panel import Panel

from trakcli.config.main import get_config
from trakcli.database.database import add_session
from trakcli.database.models import Record
from trakcli.projects.database import get_projects_from_config
from trakcli.utils.print_with_padding import print_with_padding


def create_session(
project_id: str,
today: Annotated[
Optional[datetime],
typer.Option(
"--today",
help="For a task happend today, just enter a the time.",
formats=["%H:%M"],
),
] = None,
when: Annotated[
Optional[datetime],
typer.Option(
"--when",
"-w",
help="Last name of person to greet.",
formats=["%Y-%m-%dT%H:%M"],
),
] = None,
hours: Annotated[
Optional[int],
typer.Option(
"--hours",
"-h",
help="Hours spent in sessions.",
),
] = None,
minutes: Annotated[
Optional[int],
typer.Option(
"--minutes",
"-m",
help="Minutes spent in the session.",
),
] = None,
category: Annotated[
str,
typer.Option(
"--category",
"-c",
help="Add a category to the tracked time. Useful in the reporting phase.",
),
] = "",
tag: Annotated[
str,
typer.Option(
"--tag",
"-t",
help="Add a tag to the tracked time. Useful in the reporting phase.",
),
] = "",
billable: Annotated[
bool,
typer.Option(
"--billable",
"-b",
help="The project is billable.",
),
] = False,
dryrun: Annotated[
bool,
typer.Option(
"--dry-run",
help="Check the session you are about to create, without save it.",
),
] = False,
):
CONFIG = get_config()

# Check if the project exists
projects_in_config = get_projects_from_config(CONFIG)
if len(projects_in_config):
if project_id in projects_in_config:
# Check if today or when is passed
start_timedate = datetime.today()
if today or when:
# Create the start date for the session
if today:
now = datetime.today()
today_time = today.time()
start_timedate = now.replace(
hour=today_time.hour, minute=today_time.minute
)
if when:
start_timedate = when

end_timedate = start_timedate
if hours or minutes:
if hours:
end_timedate = end_timedate + timedelta(hours=hours)
if minutes:
end_timedate = end_timedate + timedelta(minutes=minutes)

new_session = Record(
project=project_id,
start=start_timedate.isoformat(),
end=end_timedate.isoformat(),
billable=billable,
category=category,
tag=tag,
)

if not dryrun:
add_session(new_session)
rprint("")
rprint("✅ Session created.")

rprint("")
rprint(
Panel.fit(
title=project_id,
renderable=print_with_padding(
(
f"start: {new_session.start}\n"
f"end: {new_session.end}\n"
f"billable: {new_session.billable}\n"
f"category: {new_session.category}\n"
f"tag: {new_session.tag}"
)
),
)
)

return
else:
rprint(
Panel(
title="[red]Missing start time[/red]",
renderable=print_with_padding(
"Use the `--today` or `--when` flag."
),
)
)
else:
renderable_projects_list = "\n • ".join(projects_in_config)
rprint(
Panel(
title="[red]Missing project[/red]",
renderable=print_with_padding(
"This project doesn't exists.\n\n"
f"Awailable projects: \n{renderable_projects_list}\n\n\n\n"
"Try to run the `trak create project <project name>` command if you want to create a new project."
),
)
)
return
else:
rprint(projects_in_config)

# Check if hours or minutes is passed
# Get category
# Get tag
5 changes: 5 additions & 0 deletions cli/trakcli/create/commands/work.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from rich import print as rprint


def create_work():
rprint("Create a work")
51 changes: 35 additions & 16 deletions cli/trakcli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
from trakcli.dev.commands import app as dev_app
from trakcli.initialize import initialize_trak
from trakcli.projects.commands import app as projects_app
from trakcli.projects.database import get_projects_from_config
from trakcli.report.commands.main import report
from trakcli.utils.print_with_padding import print_with_padding
from trakcli.create import app as create_app

console = Console()

Expand All @@ -43,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(create_app, name="create", help="Create something in trak.")


@app.callback()
Expand Down Expand Up @@ -131,27 +134,43 @@ def start_tracker(
project = typer.prompt("Which project do you want to track?")

record = tracking_already_started()
projects_in_config = get_projects_from_config()

if not record:
add_session(
Record(
project=project,
start=datetime.now().isoformat(),
billable=billable,
category=category,
tag=tag,
if project in projects_in_config:
add_session(
Record(
project=project,
start=datetime.now().isoformat(),
billable=billable,
category=category,
tag=tag,
)
)
)
rprint(
Panel.fit(
title="▶️ Start",
renderable=print_with_padding(
f"""[bold green]{project}[/bold green] started.
rprint(
Panel.fit(
title="▶️ Start",
renderable=print_with_padding(
f"""[bold green]{project}[/bold green] started.
Have a good session!"""
),
Have a good session!"""
),
)
)
)
else:
renderable_projects_list = "\n • ".join(projects_in_config)
rprint("")
rprint(
Panel(
title="[red]Missing project[/red]",
renderable=print_with_padding(
"This project doesn't exists.\n\n"
f"Awailable projects: \n{renderable_projects_list}\n\n\n\n"
"Try to run the `trak create project <project name>` command if you want to create a new project."
),
)
)
return
else:
formatted_start_time = datetime.fromisoformat(record["start"]).strftime(
"%m/%d/%Y, %H:%M"
Expand Down
Loading

0 comments on commit bc61030

Please sign in to comment.