#!/usr/bin/env python3 import sys import typing import pandas def _merge_adjacent( recordings: pandas.DataFrame, remove_tags: typing.Set[str] ) -> typing.Iterator[pandas.Series]: previous_recording: typing.Optional[pandas.Series] = None for _, next_recording in recordings.sort_values("start").iterrows(): next_recording["tags"] = set(next_recording["tags"]).difference(remove_tags) if previous_recording is not None: if next_recording["start"] <= previous_recording["end"]: previous_recording["end"] = next_recording["end"] previous_recording["tags"].update(next_recording["tags"]) else: yield previous_recording previous_recording = next_recording else: previous_recording = next_recording if previous_recording is not None: yield previous_recording def _main(): pandas.set_option("display.width", None) pandas.set_option("display.max_rows", None) # https://timewarrior.net/docs/api/ config_text, recordings_json = sys.stdin.read().split("\n\n", maxsplit=1) config = dict(o.split(": ", maxsplit=1) for o in config_text.splitlines()) selected_tags = set(config["temp.report.tags"].split(",")) print(selected_tags) recordings = pandas.DataFrame( _merge_adjacent( pandas.read_json(recordings_json, convert_dates=["start", "end"]).set_index( "id", verify_integrity=True ), remove_tags=selected_tags, ) ).assign( start=lambda df: df["start"] .dt.tz_convert("Europe/Vienna") .dt.strftime("%Y-%m-%d %H:%M"), end=lambda df: df["end"].dt.tz_convert("Europe/Vienna").dt.strftime("%H:%M"), ) print(recordings) if __name__ == "__main__": _main()