diff --git a/git_time_tracker/__init__.py b/git_time_tracker/__init__.py index e6243f3..9e2c5ae 100644 --- a/git_time_tracker/__init__.py +++ b/git_time_tracker/__init__.py @@ -33,7 +33,7 @@ from collections.abc import Iterator from pathlib import Path from .data import HIDDEN_LABEL_PREFIX, HIDDEN_LABEL_TOTAL, WorkSample, RealizedWorkSample -from .format import cli +from .format import cli, icalendar from .source import git_repo logger = logging.getLogger(__name__) @@ -47,7 +47,7 @@ MINUTE = datetime.timedelta(minutes=1) def filter_samples(samples: list[WorkSample], sample_filter: set[str]) -> list[WorkSample]: assert len(sample_filter) > 0 - return [s for s in samples if not set(s.labels).intersection(sample_filter)] + return [s for s in samples if set(s.labels).intersection(sample_filter)] def heuristically_realize_samples(samples: list[WorkSample]) -> Iterator[RealizedWorkSample]: """Secret sauce. @@ -92,6 +92,14 @@ def parse_arguments(): dest='sample_filter', default=[], ) + parser.add_argument( + '--format', + action='store', + type=str, + dest='format_mode', + default='cli_report', + choices=['cli_report', 'icalendar'], + ) return parser.parse_args() @@ -117,7 +125,10 @@ def main(): logger.warning('Filtered down to %s samples', len(shared_time_stamps)) logger.warning('Realizing %s samples', len(shared_time_stamps)) - shared_time_stamps = heuristically_realize_samples(shared_time_stamps) + shared_time_stamps = list(heuristically_realize_samples(shared_time_stamps)) - for t in cli.generate_report(shared_time_stamps): - sys.stdout.write(t) + if args.format_mode == 'cli_report': + for t in cli.generate_report(shared_time_stamps): + sys.stdout.write(t) + elif args.format_mode == 'icalendar': + icalendar.generate_icalendar_file(shared_time_stamps, file='./output/samples.ics') diff --git a/git_time_tracker/format/icalendar.py b/git_time_tracker/format/icalendar.py new file mode 100644 index 0000000..27f7360 --- /dev/null +++ b/git_time_tracker/format/icalendar.py @@ -0,0 +1,55 @@ +import datetime +from collections.abc import Iterator +import argparse +import datetime +import urllib.parse + +import icalendar + +from personal_data.util import load_csv_file + + +from ..data import HIDDEN_LABEL_PREFIX, HIDDEN_LABEL_TOTAL, RealizedWorkSample + +ZERO_DURATION = datetime.timedelta(seconds=0) +HOUR = datetime.timedelta(hours=1) +MINUTE = datetime.timedelta(minutes=1) + +def generate_calendar( + samples: list[RealizedWorkSample], + ) -> icalendar.Calendar: + max_title_parts = 2 + + cal = icalendar.Calendar() + cal.add('prodid', '-//personal_data_calendar//example.org//') + cal.add('version', '2.0') + + for sample in samples: + + title = ' '.join(sample.labels) + + description = '' + + # Create event + event = icalendar.Event() + + event.add('summary', title) + event.add('description', description) + event.add('dtstart', sample.start_at) + event.add('dtend', sample.end_at) + + cal.add_component(event) + del event + + return cal + + +def generate_icalendar_file( + samples: list[RealizedWorkSample], + file: str, +) -> None: + + calendar = generate_calendar(samples) + + with open(file, 'wb') as f: + f.write(calendar.to_ical())