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..42e7f6112 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 " # @@ -29,6 +29,12 @@ _hamster() _hamster_helper "assist" "$prev" "$cur" return 0 ;; + resume) + if [[ ${#COMP_WORDS[@]} -ge 2 ]]; then + COMPREPLY=($(compgen -W "--no-gap" -- ${cur})) + fi + return 0 + ;; esac diff --git a/src/hamster/client.py b/src/hamster/client.py index ab3d3ba04..aef354316 100644 --- a/src/hamster/client.py +++ b/src/hamster/client.py @@ -210,6 +210,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/db.py b/src/hamster/storage/db.py index 49edd2fc2..9216d58d7 100644 --- a/src/hamster/storage/db.py +++ b/src/hamster/storage/db.py @@ -457,6 +457,16 @@ def __touch_fact(self, fact, end_time = None): """ self.execute(query, (end_time, fact.id)) + + def __continue_fact(self, fact): + update = """ + UPDATE facts + SET end_time = null + WHERE id = ? + """ + self.execute(update, (fact.id,)) + + def __squeeze_in(self, start_time): """ tries to put task in the given date if there are conflicts, we will only truncate the ongoing task diff --git a/src/hamster/storage/storage.py b/src/hamster/storage/storage.py index 82e551917..5e4d8a0da 100644 --- a/src/hamster/storage/storage.py +++ b/src/hamster/storage/storage.py @@ -145,6 +145,28 @@ 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.__continue_fact(facts[-1]) + self.facts_changed() + else: + logger.warning("No activity to continue") + + 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"""