From 43f03c19a5e63a8f541cc5d772f2b6c4fb8550bc Mon Sep 17 00:00:00 2001 From: Olaf Lessenich Date: Wed, 29 Nov 2023 00:00:59 +0100 Subject: [PATCH] feat: add commands resume and continue Support resuming/continuing the last tracked activity. When `hamster resume` is called, the last tracked activity is started, i.e., the same activity is started again with the current start_time. If the `resume` command is called with the option `--no-gap`, the activity is started again with its previous end_time. If `hamster continue` is called, the last tracked activity continues to be tracked, i.e., its end_time is removed and there is no gap in the time tracking. Signed-off-by: Olaf Lessenich --- src/hamster-cli.py | 28 +++++++++++++++++++++++++++- src/hamster-service.py | 13 +++++++++++++ src/hamster.bash | 2 +- src/hamster/client.py | 12 ++++++++++++ src/hamster/storage/storage.py | 19 +++++++++++++++++++ 5 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/hamster-cli.py b/src/hamster-cli.py index 9c6786787..1ee6147fc 100755 --- a/src/hamster-cli.py +++ b/src/hamster-cli.py @@ -261,6 +261,24 @@ def start(self, *args): return id_ + def resume(self, *args, no_gap=False): + '''Resume the last activity.''' + facts = self.storage.get_todays_facts() + if facts and facts[-1].end_time: + no_gap = no_gap or "--no-gap" in args + self.storage.resume_tracking(no_gap) + else: + print((_("No activity to resume"))) + + def continue_(self, *args): + '''Continue the last activity.''' + facts = self.storage.get_todays_facts() + if facts and facts[-1].end_time: + self.storage.continue_tracking() + else: + print((_("No activity to continue"))) + + def stop(self, *args): '''Stop tracking the current activity.''' self.storage.stop_tracking() @@ -419,6 +437,10 @@ def version(self): Actions: * add [activity [start-time [end-time]]]: Add an activity * stop: Stop tracking current activity. + * resume: The last tracked activity is tracked again from now. + If --no-gap is specified, the activity is restarted without a gap + since its last end time + * continue: The last tracked activity is continued from its last end time. * list [start-date [end-date]]: List activities * search [terms] [start-date [end-date]]: List activities matching a search term @@ -488,13 +510,17 @@ def version(self): else: action = args.action - if action in ("about", "add", "edit", "overview", "preferences"): + if action in ("about", "add", "edit", "overview", "preferences", "continue"): if action == "add" and args.action_args: assert not unknown_args, "unknown options: {}".format(unknown_args) # directly add fact from arguments id_ = hamster_client.start(*args.action_args) assert id_ > 0, "failed to add fact" sys.exit(0) + elif action == "continue": + assert not unknown_args, "unknown options: {}".format(unknown_args) + hamster_client.continue_() + sys.exit(0) else: app.register() if action == "edit": diff --git a/src/hamster-service.py b/src/hamster-service.py index 29e7c1e06..238745595 100755 --- a/src/hamster-service.py +++ b/src/hamster-service.py @@ -281,6 +281,19 @@ def StopTracking(self, end_time): end_time = dt.datetime.utcfromtimestamp(end_time) return self.stop_tracking(end_time) + @dbus.service.method("org.gnome.Hamster") + def ResumeTracking(self, no_gap = False): + """Resumes tracking the last activity. + Parameters: + b no_gap: Use the previous end time as start time to fill the untracked gap. + Default is False. + """ + return self.resume_tracking(no_gap) + + @dbus.service.method("org.gnome.Hamster") + def ContinueTracking(self): + """Continue tracking the last activity""" + return self.continue_tracking() @dbus.service.method("org.gnome.Hamster") def StopOrRestartTracking(self): diff --git a/src/hamster.bash b/src/hamster.bash index 293abcd6d..c1bb384e2 100644 --- a/src/hamster.bash +++ b/src/hamster.bash @@ -17,7 +17,7 @@ _hamster() # # The basic options we'll complete. # - opts="activities categories current export list search start stop " + opts="activities categories current export list search start stop resume continue " # diff --git a/src/hamster/client.py b/src/hamster/client.py index 8a0c297c3..e48882762 100644 --- a/src/hamster/client.py +++ b/src/hamster/client.py @@ -221,6 +221,18 @@ def add_fact(self, fact, temporary_activity = False): return new_id + def resume_tracking(self, no_gap = False): + """Resume tracking last activity. + Parameters: + b no_gap: Use the previous end time as start time to fill the untracked gap. + Default is False. + """ + return self.conn.ResumeTracking(no_gap) + + def continue_tracking(self): + """Continue tracking last activity.""" + return self.conn.ContinueTracking() + def stop_tracking(self, end_time = None): """Stop tracking current activity. end_time can be passed in if the activity should have other end time than the current moment""" diff --git a/src/hamster/storage/storage.py b/src/hamster/storage/storage.py index 82e551917..4734967fb 100644 --- a/src/hamster/storage/storage.py +++ b/src/hamster/storage/storage.py @@ -145,6 +145,25 @@ def stop_tracking(self, end_time): self.__touch_fact(facts[-1], end_time) self.facts_changed() + def continue_tracking(self): + """Continue tracking the last activity""" + facts = self.__get_todays_facts() + if facts and facts[-1].end_time: + self.__touch_fact(facts[-1], None) + + def resume_tracking(self, no_gap=False): + """Resume tracking the last activity""" + facts = self.__get_todays_facts() + if facts and facts[-1].end_time: + if no_gap: + self.add_fact(facts[-1].copy(start_time=facts[-1].end_time, + end_time=None)) + else: + start_time = dt.datetime.now() + self.add_fact(facts[-1].copy(start_time=start_time, + end_time=None)) + else: + logger.warning("No activity to resume") def stop_or_restart_tracking(self): """Stops or restarts tracking the last activity"""