From 4a3744192ae9e6c4d9745ff692979996a04bdc0e Mon Sep 17 00:00:00 2001 From: Jindrich Pilar Date: Sat, 8 Oct 2016 15:43:24 +0200 Subject: [PATCH 1/4] Timewarrior module Module for heads up information for taskwarrior.org/docs/timewarrior/ --- i3pystatus/timewarrior.py | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 i3pystatus/timewarrior.py diff --git a/i3pystatus/timewarrior.py b/i3pystatus/timewarrior.py new file mode 100644 index 0000000..ca387a6 --- /dev/null +++ b/i3pystatus/timewarrior.py @@ -0,0 +1,77 @@ +from i3pystatus import IntervalModule +from json import loads +from dateutil.parser import parse +from dateutil.relativedelta import relativedelta +from datetime import datetime, timezone +import subprocess + + +class TImewarrior(IntervalModule): + """ + Show current Timewarrior tracking + Requires `json` `dateutil` + + Formaters: + + * `{tags}` — contains tags of current track + * `{start}` - contains start of track + * `{duration}` — contains time of current track + """ + + format = '{duration}' + duration_format = '{years}y{months}m{days}d{hours}h{minutes}m{seconds}s' + enable_stop = True + enable_continue = True + color_running = '#00FF00' + color_stopped = '#F00000' + on_rightclick = 'stop_or_continue' + track = None + + settings = ( + ('format', 'format string'), + ('enable_stop', 'Allow right click to stop tracking'), + ('enable_continue', 'ALlow right click to continue tracking'), + ('color_running', '#00FF00'), + ('color_stopped', '#F00000'), + ) + + def loadTrack(self): + try: + tracks_json = subprocess.check_output(['timew', 'export']) + tracks = loads(tracks_json.decode("utf-8")) + self.track = tracks[-1] + + except ValueError: + print('Decoding JSON has failed') + + def stop_or_continue(self): + self.loadTrack() + + if 'end' in self.track and self.enable_continue: + subprocess.check_output(['timew', 'continue']) + elif self.enable_stop: + subprocess.check_output(['timew', 'stop']) + + def run(self): + self.loadTrack() + start = parse(self.track['start']) + end = parse(self.track['end']) if 'end' in self.track else datetime.now(timezone.utc) + duration = relativedelta(end, start) + + format_values = dict( + tags=", ".join(self.track['tags'] if 'tags' in self.track else []), + start=start, + duration=self.duration_format.format( + years=duration.years, + months=duration.months, + days=duration.days, + hours=duration.hours, + minutes=duration.minutes, + seconds=duration.seconds, + ) + ) + + self.output = { + 'full_text': self.format.format(**format_values), + 'color': self.color_stopped if 'end' in self.track else self.color_running + } From 4692e0f9143dc12835a22730a8dc3ebe1342af1f Mon Sep 17 00:00:00 2001 From: Jindrich Pilar Date: Sun, 9 Oct 2016 10:09:54 +0200 Subject: [PATCH 2/4] Timewarrior re-raise error --- i3pystatus/timewarrior.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/i3pystatus/timewarrior.py b/i3pystatus/timewarrior.py index ca387a6..a80a46c 100644 --- a/i3pystatus/timewarrior.py +++ b/i3pystatus/timewarrior.py @@ -41,8 +41,9 @@ class TImewarrior(IntervalModule): tracks = loads(tracks_json.decode("utf-8")) self.track = tracks[-1] - except ValueError: + except ValueError as error: print('Decoding JSON has failed') + raise error def stop_or_continue(self): self.loadTrack() From 6016c52a8711a59a2108ea69b4abd93da1f56943 Mon Sep 17 00:00:00 2001 From: Jindrich Pilar Date: Sun, 9 Oct 2016 10:53:01 +0200 Subject: [PATCH 3/4] Timewarrior use Logger instead of print --- i3pystatus/timewarrior.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i3pystatus/timewarrior.py b/i3pystatus/timewarrior.py index a80a46c..979cb17 100644 --- a/i3pystatus/timewarrior.py +++ b/i3pystatus/timewarrior.py @@ -6,7 +6,7 @@ from datetime import datetime, timezone import subprocess -class TImewarrior(IntervalModule): +class Timewarrior(IntervalModule): """ Show current Timewarrior tracking Requires `json` `dateutil` @@ -42,7 +42,7 @@ class TImewarrior(IntervalModule): self.track = tracks[-1] except ValueError as error: - print('Decoding JSON has failed') + self.logger.exception('Decoding JSON has failed') raise error def stop_or_continue(self): From 4c9e84968d2c5e7304ef90ee41e75db5d39e33d2 Mon Sep 17 00:00:00 2001 From: Jindrich Pilar Date: Tue, 18 Oct 2016 09:28:38 +0200 Subject: [PATCH 4/4] Dependencies dateutil.parser and dateutil.relativedelta added to docs/config.py --- docs/conf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index bc11038..d1948e0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -44,6 +44,8 @@ MOCK_MODULES = [ "vlc", "dateutil.tz", "i3ipc", + "dateutil.parser", + "dateutil.relativedelta", ] for mod_name in MOCK_MODULES: