Merge pull request #449 from karthink/master

Pomodoro module - improved
This commit is contained in:
tobi-wan-kenobi 2019-10-02 21:20:27 +02:00 committed by GitHub
commit 435c2416fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 405 additions and 91 deletions

View file

@ -3,10 +3,19 @@
"""Display and run a Pomodoro timer. """Display and run a Pomodoro timer.
Left click to start timer, left click again to pause. Left click to start timer, left click again to pause.
Right click will cancel the timer. Right click will cancel the timer.
Parameters:
* pomodoro.work: The work duration of timer in minutes (defaults to 25)
* pomodoro.break: The break duration of timer in minutes (defaults to 5)
* pomodoro.format: Timer display format with "%m" and "%s" for minutes and seconds (defaults to "%m:%s")
Examples: "%m min %s sec", "%mm", "", "timer"
* pomodoro.notify: Notification command to run when timer ends/starts (defaults to nothing)
Example: 'notify-send "Time up!"'
""" """
from __future__ import absolute_import from __future__ import absolute_import
import datetime import datetime
from math import ceil
import bumblebee.input import bumblebee.input
import bumblebee.output import bumblebee.output
@ -15,18 +24,49 @@ import bumblebee.engine
class Module(bumblebee.engine.Module): class Module(bumblebee.engine.Module):
def __init__(self, engine, config): def __init__(self, engine, config):
widgets = bumblebee.output.Widget(full_text=self.text) widgets = bumblebee.output.Widget(full_text=self.text)
self.remaining_time = datetime.timedelta(minutes=25)
self.remaining_time_str = "{}min{}s ".format(int((self.remaining_time.seconds / 60)),
round((self.remaining_time.seconds/60) % 1*60))
self.time = None
self.pomodoro = { "state":"OFF", "type": "n/a"}
self._text = self.remaining_time_str + self.pomodoro["type"] + " " + self.pomodoro["state"]
super(Module, self).__init__(engine, config, widgets) super(Module, self).__init__(engine, config, widgets)
# Parameters
self._work_period = int(self.parameter("work", 25))
self._break_period = int(self.parameter("break", 5))
self._time_format = self.parameter("format", "%m:%s")
self._notify_cmd = self.parameter("notify", "")
# TODO: Handle time formats more gracefully. This is kludge.
self.display_seconds_p = False
self.display_minutes_p = False
if "%s" in self._time_format:
self.display_seconds_p = True
if "%m" in self._time_format:
self.display_minutes_p = True
self.remaining_time = datetime.timedelta(minutes=self._work_period)
self.time = None
self.pomodoro = { "state":"OFF", "type": ""}
self._text = self.remaining_time_str() + self.pomodoro["type"]
engine.input.register_callback(self, button=bumblebee.input.LEFT_MOUSE, engine.input.register_callback(self, button=bumblebee.input.LEFT_MOUSE,
cmd=self.timer_play_pause) cmd=self.timer_play_pause)
engine.input.register_callback(self, button=bumblebee.input.RIGHT_MOUSE, engine.input.register_callback(self, button=bumblebee.input.RIGHT_MOUSE,
cmd=self.timer_reset) cmd=self.timer_reset)
def remaining_time_str(self):
if self.display_seconds_p and self.display_minutes_p:
minutes, seconds = divmod(self.remaining_time.seconds, 60)
if not self.display_seconds_p:
minutes = ceil(self.remaining_time.seconds / 60)
seconds = 0
if not self.display_minutes_p:
minutes = 0
seconds = self.remaining_time.seconds
minutes = "{:2d}".format(minutes)
seconds = "{:02d}".format(seconds)
return self._time_format.replace("%m",minutes).replace("%s",seconds)+" "
def text(self, widget): def text(self, widget):
return "{}".format(self._text) return "{}".format(self._text)
@ -38,21 +78,24 @@ class Module(bumblebee.engine.Module):
self.time = datetime.datetime.now() self.time = datetime.datetime.now()
if self.remaining_time.seconds <= 0: if self.remaining_time.seconds <= 0:
if self.pomodoro["type"] == "WORK": self.notify()
self.pomodoro["type"] = "PLAY" if self.pomodoro["type"] == "Work":
self.remaining_time = datetime.timedelta(minutes=25) self.pomodoro["type"] = "Break"
elif self.pomodoro["type"] == "PLAY": self.remaining_time = datetime.timedelta(minutes=self._break_period)
self.pomodoro["type"] = "WORK" elif self.pomodoro["type"] == "Break":
self.remaining_time = datetime.timedelta(minutes=5) self.pomodoro["type"] = "Work"
self.remaining_time = datetime.timedelta(minutes=self._work_period)
self.remaining_time_str = "{}min{}s ".format(int((self.remaining_time.seconds / 60)), self._text = self.remaining_time_str() + self.pomodoro["type"]
round((self.remaining_time.seconds / 60) % 1 * 60))
self._text = self.remaining_time_str + self.pomodoro["type"] + " " + self.pomodoro["state"]
def notify(self):
if self._notify_cmd:
bumblebee.util.execute(self._notify_cmd)
def timer_play_pause(self, widget): def timer_play_pause(self, widget):
if self.pomodoro["state"] == "OFF": if self.pomodoro["state"] == "OFF":
self.pomodoro = {"state": "ON", "type": "WORK"} self.pomodoro = {"state": "ON", "type": "Work"}
self.remaining_time = datetime.timedelta(minutes=25) self.remaining_time = datetime.timedelta(minutes=self._work_period)
self.time = datetime.datetime.now() self.time = datetime.datetime.now()
elif self.pomodoro["state"] == "ON": elif self.pomodoro["state"] == "ON":
self.pomodoro["state"] = "PAUSED" self.pomodoro["state"] = "PAUSED"
@ -64,5 +107,13 @@ class Module(bumblebee.engine.Module):
def timer_reset(self, widget): def timer_reset(self, widget):
if self.pomodoro["state"] == "ON" or self.pomodoro["state"] == "PAUSED": if self.pomodoro["state"] == "ON" or self.pomodoro["state"] == "PAUSED":
self.pomodoro = {"state":"OFF", "type": "n/a" } self.pomodoro = {"state":"OFF", "type": "" }
self.remaining_time = datetime.timedelta(minutes=25) self.remaining_time = datetime.timedelta(minutes=self._work_period)
def state(self, widget):
state = [];
state.append(self.pomodoro["state"].lower())
if self.pomodoro["state"] == "ON" or self.pomodoro["state"] == "OFF":
state.append(self.pomodoro["type"].lower())
return state

View file

@ -26,5 +26,17 @@
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
} }
} },
"pomodoro": {
"paused": {
"fg": "#002b36",
"bg": "#b58900"
},
"break": {
"fg": "#002b36",
"bg": "#859900"
}
}
} }

View file

@ -42,5 +42,20 @@
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
} }
} },
"pomodoro": {
"paused": {
"fg": "#002b36",
"bg": "#b58900"
},
"work": {
"fg": "#1d2021",
"bg": "#b8bb26"
},
"break": {
"fg": "#002b36",
"bg": "#859900"
}
}
} }

View file

@ -54,5 +54,20 @@
"modified": { "bg": "#458588" }, "modified": { "bg": "#458588" },
"deleted": { "bg": "#9d0006" }, "deleted": { "bg": "#9d0006" },
"new": { "bg": "#b16286" } "new": { "bg": "#b16286" }
} },
"pomodoro": {
"paused": {
"fg": "#1d2021",
"bg": "#d79921"
},
"work": {
"fg": "#1d2021",
"bg": "#b8bb26"
},
"break": {
"fg": "#002b36",
"bg": "#859900"
}
}
} }

View file

@ -21,38 +21,52 @@
"fg": "#282828", "fg": "#282828",
"bg": "#fbf1c7" "bg": "#fbf1c7"
} }
], ],
"dnf": { "dnf": {
"good": { "good": {
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
} }
}, },
"apt": { "apt": {
"good": { "good": {
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
} }
}, },
"battery": { "battery": {
"charged": { "charged": {
"fg": "#1d2021", "fg": "#1d2021",
"bg": "#b8bb26" "bg": "#b8bb26"
}, },
"AC": { "AC": {
"fg": "#1d2021", "fg": "#1d2021",
"bg": "#b8bb26" "bg": "#b8bb26"
} }
}, },
"bluetooth": { "bluetooth": {
"ON": { "ON": {
"fg": "#1d2021", "fg": "#1d2021",
"bg": "#b8bb26" "bg": "#b8bb26"
} }
}, },
"git": { "git": {
"modified": { "bg": "#458588" }, "modified": { "bg": "#458588" },
"deleted": { "bg": "#9d0006" }, "deleted": { "bg": "#9d0006" },
"new": { "bg": "#b16286" } "new": { "bg": "#b16286" }
} },
"pomodoro": {
"paused": {
"fg": "#1d2021",
"bg": "#d79921"
},
"work": {
"fg": "#1d2021",
"bg": "#b8bb26"
},
"break": {
"fg": "#002b36",
"bg": "#859900"
}
}
} }

View file

@ -54,5 +54,19 @@
"modified": { "bg": "#458588" }, "modified": { "bg": "#458588" },
"deleted": { "bg": "#9d0006" }, "deleted": { "bg": "#9d0006" },
"new": { "bg": "#b16286" } "new": { "bg": "#b16286" }
} },
"pomodoro": {
"paused": {
"fg": "#1d2021",
"bg": "#d79921"
},
"work": {
"fg": "#1d2021",
"bg": "#b8bb26"
},
"break": {
"fg": "#002b36",
"bg": "#859900"
}
}
} }

View file

@ -54,5 +54,20 @@
"modified": { "bg": "#458588" }, "modified": { "bg": "#458588" },
"deleted": { "bg": "#9d0006" }, "deleted": { "bg": "#9d0006" },
"new": { "bg": "#b16286" } "new": { "bg": "#b16286" }
} },
"pomodoro": {
"paused": {
"fg": "#1d2021",
"bg": "#d79921"
},
"work": {
"fg": "#1d2021",
"bg": "#b8bb26"
},
"break": {
"fg": "#002b36",
"bg": "#859900"
}
}
} }

View file

@ -47,5 +47,20 @@
"fg": "#0f1117", "fg": "#0f1117",
"bg": "#84a0c6" "bg": "#84a0c6"
} }
},
"pomodoro": {
"paused": {
"fg": "#0f1117",
"bg": "#e2a478"
},
"work": {
"fg": "#1d2021",
"bg": "#b8bb26"
},
"break": {
"fg": "#b4be82",
"bg": "#161821"
}
} }
} }

View file

@ -46,5 +46,19 @@
"fg": "#0f1117", "fg": "#0f1117",
"bg": "#84a0c6" "bg": "#84a0c6"
} }
},
"pomodoro": {
"paused": {
"fg": "#0f1117",
"bg": "#e2a478"
},
"work": {
"fg": "#1d2021",
"bg": "#b8bb26"
},
"break": {
"fg": "#89b8c2",
"bg": "#161821"
}
} }
} }

View file

@ -46,5 +46,20 @@
"fg": "#89b8c2", "fg": "#89b8c2",
"bg": "#161821" "bg": "#161821"
} }
},
"pomodoro": {
"paused": {
"fg": "#e2a478",
"bg": "#c6c8d1"
},
"work": {
"fg": "#89b8c2",
"bg": "#161821"
},
"break": {
"fg": "#b4be82",
"bg": "#161821"
}
} }
} }

View file

@ -40,5 +40,20 @@
"fg": "#89b8c2", "fg": "#89b8c2",
"bg": "#161821" "bg": "#161821"
} }
},
"pomodoro": {
"paused": {
"fg": "#0f1117",
"bg": "#e2a478"
},
"work": {
"fg": "#1d2021",
"bg": "#b8bb26"
},
"break": {
"fg": "#89b8c2",
"bg": "#161821"
}
} }
} }

View file

@ -302,6 +302,10 @@
}, },
"system": { "system": {
"prefix": "system" "prefix": "system"
} },
"pomodoro": {
"off": { "prefix": "pom" },
"paused": { "prefix": "||" },
"on": { "prefix": " >" }
}
} }

View file

@ -222,5 +222,11 @@
}, },
"rss": { "rss": {
"prefix": "" "prefix": ""
},
"pomodoro": {
"off": { "prefix": "" },
"paused": { "prefix": "" },
"work": { "prefix": "" },
"break": { "prefix": "" }
} }
} }

View file

@ -185,5 +185,11 @@
}, },
"rss": { "rss": {
"prefix": "\uf1ea" "prefix": "\uf1ea"
},
"pomodoro": {
"off": { "prefix": "\uf24f" },
"paused": { "prefix": "\uf210" },
"on": { "prefix": "\uf488" }
} }
} }

View file

@ -36,5 +36,20 @@
"fg": "#282C34", "fg": "#282C34",
"bg": "#98C379" "bg": "#98C379"
} }
} },
"pomodoro": {
"paused": {
"fg": "#282C34",
"bg": "#E5C07B"
},
"work": {
"fg": "#98C379",
"bg": "#282C34"
},
"break": {
"fg": "#282C34",
"bg": "#98C379"
}
}
} }

View file

@ -43,5 +43,20 @@
"fg": "#494949", "fg": "#494949",
"bg": "#41db00" "bg": "#41db00"
} }
} },
"pomodoro": {
"paused": {
"fg": "#d75f00",
"bg": "#ffd700"
},
"work": {
"fg": "#ffd700",
"bg": "#d75f00"
},
"break": {
"fg": "#494949",
"bg": "#41db00"
}
}
} }

View file

@ -40,5 +40,20 @@
}, },
"cmus": { "cmus": {
"bg": "#C42021" "bg": "#C42021"
} },
"pomodoro": {
"paused": {
"fg": "#FDFFFC",
"bg": "#B91372"
},
"work": {
"fg": "#FDFFFC",
"bg": "#41EAD4"
},
"break": {
"fg": "#FDFFFC",
"bg": "#011627"
}
}
} }

View file

@ -21,29 +21,43 @@
}, },
"apt": { "apt": {
"good": { "good": {
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
} }
}, },
"pacman": { "pacman": {
"good": { "good": {
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
} }
}, },
"battery": { "battery": {
"charged": { "charged": {
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
}, },
"AC": { "AC": {
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
} }
}, },
"git": { "git": {
"modified": { "bg": "#2aa198" }, "modified": { "bg": "#2aa198" },
"deleted": { "bg": "#d33682" }, "deleted": { "bg": "#d33682" },
"new": { "bg": "#859900" } "new": { "bg": "#859900" }
} },
"pomodoro": {
"paused": {
"fg": "#002b36",
"bg": "#b58900"
},
"work": {
"fg": "#eee8d5",
"bg": "#586e75"
},
"break": {
"fg": "#002b36",
"bg": "#859900"
}
}
} }

View file

@ -47,5 +47,19 @@
"modified": { "bg": "#2aa198" }, "modified": { "bg": "#2aa198" },
"deleted": { "bg": "#d33682" }, "deleted": { "bg": "#d33682" },
"new": { "bg": "#859900" } "new": { "bg": "#859900" }
} },
"pomodoro": {
"paused": {
"fg": "#002b36",
"bg": "#b58900"
},
"work": {
"fg": "#eee8d5",
"bg": "#586e75"
},
"break": {
"fg": "#002b36",
"bg": "#859900"
}
}
} }

View file

@ -49,5 +49,20 @@
"modified": { "bg": "#2aa198" }, "modified": { "bg": "#2aa198" },
"deleted": { "bg": "#d33682" }, "deleted": { "bg": "#d33682" },
"new": { "bg": "#859900" } "new": { "bg": "#859900" }
} },
"pomodoro": {
"paused": {
"fg": "#002b36",
"bg": "#b58900"
},
"work": {
"fg": "#eee8d5",
"bg": "#586e75"
},
"break": {
"fg": "#002b36",
"bg": "#859900"
}
}
} }

View file

@ -44,5 +44,20 @@
"fg": "background", "fg": "background",
"bg": "color3" "bg": "color3"
} }
} },
"pomodoro": {
"paused": {
"fg": "cursor",
"bg": "color6"
},
"work": {
"fg": "background",
"bg": "foreground"
},
"break": {
"fg": "background",
"bg": "color3"
}
}
} }