From 477fce869d31b3e671ec8aa0544d0ddc7741b880 Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Sun, 13 Oct 2024 15:20:18 +0200 Subject: [PATCH] Moved ActivitySample into personal_data --- git_time_tracker/__init__.py | 4 +--- git_time_tracker/format/cli.py | 23 +++++++++---------- git_time_tracker/format/icalendar.py | 18 +++++++-------- git_time_tracker/source/csv_file.py | 6 ++--- git_time_tracker/source/git_repo.py | 8 +++---- .../data.py => personal_data/activity.py | 14 ++++++++--- 6 files changed, 37 insertions(+), 36 deletions(-) rename git_time_tracker/data.py => personal_data/activity.py (55%) diff --git a/git_time_tracker/__init__.py b/git_time_tracker/__init__.py index b3532f6..0af98e8 100644 --- a/git_time_tracker/__init__.py +++ b/git_time_tracker/__init__.py @@ -32,9 +32,7 @@ import sys from collections.abc import Iterator from pathlib import Path -from .data import ( - HIDDEN_LABEL_PREFIX, - HIDDEN_LABEL_TOTAL, +from personal_data.activity import ( RealizedActivitySample, ActivitySample, ) diff --git a/git_time_tracker/format/cli.py b/git_time_tracker/format/cli.py index d715a9d..461a26e 100644 --- a/git_time_tracker/format/cli.py +++ b/git_time_tracker/format/cli.py @@ -1,7 +1,7 @@ import datetime from collections.abc import Iterator -from ..data import HIDDEN_LABEL_PREFIX, HIDDEN_LABEL_TOTAL, RealizedActivitySample +from personal_data.activity import HIDDEN_LABEL_CATEGORY, RealizedActivitySample, Label ZERO_DURATION = datetime.timedelta(seconds=0) HOUR = datetime.timedelta(hours=1) @@ -29,18 +29,18 @@ def fmt_year_ranges(years: list[int]) -> str: return ''.join(list(fmt_year_ranges_internal(years))) -def fmt_line(label_type: str, label: str, total_time: datetime.timedelta) -> str: +def fmt_line(label: Label, total_time: datetime.timedelta) -> str: hours = int(total_time / HOUR) minutes = int((total_time - hours * HOUR) / MINUTE) - return f' {label_type:10} {label:40} {hours:-4d}h {minutes:-2d}m' + return f' {label.category:10} {label.label:40} {hours:-4d}h {minutes:-2d}m' def generate_report( samples: list[RealizedActivitySample], ) -> Iterator[str]: # Time spent per label - time_per_label: dict[str, datetime.timedelta] = {} - years_per_label: dict[str, set[int]] = {} + time_per_label: dict[Label, datetime.timedelta] = {} + years_per_label: dict[Label, set[int]] = {} for sample in samples: duration = sample.end_at - sample.start_at @@ -57,15 +57,13 @@ def generate_report( # yield '-' * 66 yield '\n' - for total_time, label_and_type in time_and_label: - if label_and_type.startswith(HIDDEN_LABEL_PREFIX): + for total_time, label in time_and_label: + if label.category == HIDDEN_LABEL_CATEGORY: continue - label_type, label = label_and_type.split(':', 1) - - yield fmt_line(label_type, label, total_time) + yield fmt_line(label, total_time) yield ' (' - yield fmt_year_ranges(years_per_label.get(label_and_type, [])) + yield fmt_year_ranges(years_per_label.get(label, [])) yield ')' yield '\n' del label, total_time @@ -73,5 +71,6 @@ def generate_report( yield '-' * 66 yield '\n' - yield fmt_line('', 'TOTAL', time_per_label.get(HIDDEN_LABEL_TOTAL, ZERO_DURATION)) + label_total = Label(HIDDEN_LABEL_CATEGORY, 'total') + yield fmt_line(label_total, time_per_label.get(label_total, ZERO_DURATION)) yield '\n' diff --git a/git_time_tracker/format/icalendar.py b/git_time_tracker/format/icalendar.py index 5c4725a..522be9f 100644 --- a/git_time_tracker/format/icalendar.py +++ b/git_time_tracker/format/icalendar.py @@ -2,7 +2,7 @@ import datetime import icalendar -from ..data import HIDDEN_LABEL_PREFIX, RealizedActivitySample +from personal_data.activity import HIDDEN_LABEL_CATEGORY, RealizedActivitySample, Label ZERO_DURATION = datetime.timedelta(seconds=0) HOUR = datetime.timedelta(hours=1) @@ -12,15 +12,13 @@ MINUTE = datetime.timedelta(minutes=1) def create_title(sample: RealizedActivitySample) -> tuple[str, str]: ls = [] desc = [] - for label_and_type in sample.labels: - if label_and_type.startswith(HIDDEN_LABEL_PREFIX): - continue - if label_and_type.startswith('author:'): + for label in sample.labels: + if label.category in {HIDDEN_LABEL_CATEGORY, 'author'}: continue if len(ls) == 0: - ls.append(label_and_type.split(':')[1]) + ls.append(label.label) else: - desc.append(label_and_type) + desc.append(label.label) return ' '.join(ls), '\n'.join(desc) @@ -44,11 +42,11 @@ def generate_calendar( event.add('dtstart', sample.start_at) event.add('dtend', sample.end_at) - for label_and_type in sample.labels: - if label_and_type.startswith('author:'): + for label in sample.labels: + if label.category == 'author': event.add( 'organizer', - 'mailto:' + label_and_type.removeprefix('author:'), + 'mailto:' + label.label, ) cal.add_component(event) diff --git a/git_time_tracker/source/csv_file.py b/git_time_tracker/source/csv_file.py index 627cffd..a739cd5 100644 --- a/git_time_tracker/source/csv_file.py +++ b/git_time_tracker/source/csv_file.py @@ -8,7 +8,7 @@ import dataclasses from personal_data.csv_import import load_csv_file, start_end, determine_possible_keys -from ..data import ActivitySample +from personal_data.activity import ActivitySample, Label def iterate_samples_from_dicts(rows: list[dict[str,Any]]) -> Iterator[ActivitySample]: assert len(rows) > 0 @@ -17,11 +17,9 @@ def iterate_samples_from_dicts(rows: list[dict[str,Any]]) -> Iterator[ActivitySa if True: event_data = rows[len(rows)//2] # Hopefully select a useful representative. - print(event_data) possible_keys = determine_possible_keys(event_data) del event_data - print(possible_keys) assert len(possible_keys.time_start) + len(possible_keys.time_end) >= 1 assert len(possible_keys.image) >= 0 @@ -35,7 +33,7 @@ def iterate_samples_from_dicts(rows: list[dict[str,Any]]) -> Iterator[ActivitySa ''' (start_at, end_at) = start_end(event_data, possible_keys) - labels = [f'{k}:{event_data[k]}' for k in possible_keys.misc] + labels = [Label(k, event_data[k]) for k in possible_keys.misc] # Create event yield ActivitySample( diff --git a/git_time_tracker/source/git_repo.py b/git_time_tracker/source/git_repo.py index a85b589..9d7710e 100644 --- a/git_time_tracker/source/git_repo.py +++ b/git_time_tracker/source/git_repo.py @@ -5,7 +5,7 @@ from pathlib import Path import git -from ..data import HIDDEN_LABEL_TOTAL, ActivitySample +from personal_data.activity import ActivitySample, Label, HIDDEN_LABEL_CATEGORY logger = logging.getLogger(__name__) @@ -34,9 +34,9 @@ def get_samples_from_project(repo: git.Repo) -> Iterator[ActivitySample]: repo.commit() for commit in repo.iter_commits(determine_default_branch(repo)): - labels = [HIDDEN_LABEL_TOTAL] - labels.append('project:' + project_name) - labels.append('author:' + commit.author.email) + labels = [Label(HIDDEN_LABEL_CATEGORY, 'total')] + labels.append(Label('project', project_name)) + labels.append(Label('author', commit.author.email)) authored_date = datetime.datetime.fromtimestamp( commit.authored_date, diff --git a/git_time_tracker/data.py b/personal_data/activity.py similarity index 55% rename from git_time_tracker/data.py rename to personal_data/activity.py index 2a152aa..e6c6280 100644 --- a/git_time_tracker/data.py +++ b/personal_data/activity.py @@ -2,13 +2,21 @@ import dataclasses import datetime from collections.abc import Sequence -HIDDEN_LABEL_PREFIX = '__' -HIDDEN_LABEL_TOTAL = HIDDEN_LABEL_PREFIX + 'TOTAL' +HIDDEN_LABEL_CATEGORY = '__' +@dataclasses.dataclass(frozen=True, order=True) +class Label: + category: str + label: str + + def __post_init__(self): + assert self.category is not None + assert ':' not in self.category + assert self.label is not None @dataclasses.dataclass(frozen=True, order=True) class ActivitySample: - labels: Sequence[str] + labels: Sequence[Label] start_at: datetime.datetime | None end_at: datetime.datetime | None