Skip to content

Commit

Permalink
feat: add commands resume and continue
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
xai committed Mar 20, 2024
1 parent 81be67e commit e00b308
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 2 deletions.
28 changes: 27 additions & 1 deletion src/hamster-cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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":
Expand Down
13 changes: 13 additions & 0 deletions src/hamster-service.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
8 changes: 7 additions & 1 deletion src/hamster.bash
Original file line number Diff line number Diff line change
Expand Up @@ -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 "


#
Expand All @@ -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

Expand Down
12 changes: 12 additions & 0 deletions src/hamster/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"""
Expand Down
10 changes: 10 additions & 0 deletions src/hamster/storage/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions src/hamster/storage/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"""
Expand Down

0 comments on commit e00b308

Please sign in to comment.