├── README.md
├── .gitignore
├── tomatych.py
├── tomatych_habitica.py
└── tomatych_slack.py
/README.md:
--------------------------------------------------------------------------------
1 | # Simple Hackable Pomodoro Timer
2 |
3 |
4 |
5 | Decription
6 | -----------
7 |
8 | Intended to be hacked and modified to fit your specific vision of how Pomodoro timers should work. Some assembly be required :)
9 |
10 | See recipes:
11 |
12 | * [Score Habitica habits on completed or canceled Pomodoros](http://developer.run/18#habitica)
13 | * [Set Slack to do not disturb mode while Pomodoro is running](http://developer.run/18#dnd)
14 | * [Set Tomato Emoji as Slack status while Pomodoro is running](http://developer.run/18#slack)
15 | * [More...](http://developer.run/18)
16 |
17 | Requirements
18 | ------------
19 |
20 | 1. On Linux install package `python-tk`, Windows should have it installed with Python
21 | 2. `pip install requests`
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 |
27 | # PyInstaller
28 | # Usually these files are written by a python script from a template
29 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
30 | *.manifest
31 | *.spec
32 |
33 | # Installer logs
34 | pip-log.txt
35 | pip-delete-this-directory.txt
36 |
37 | # Unit test / coverage reports
38 | htmlcov/
39 | .tox/
40 | .coverage
41 | .coverage.*
42 | .cache
43 | nosetests.xml
44 | coverage.xml
45 | *,cover
46 | .hypothesis/
47 |
48 | # Translations
49 | *.mo
50 | *.pot
51 |
52 | # Django stuff:
53 | *.log
54 | local_settings.py
55 |
56 | # Flask stuff:
57 | instance/
58 | .webassets-cache
59 |
60 | # Scrapy stuff:
61 | .scrapy
62 |
63 | # Sphinx documentation
64 | docs/_build/
65 |
66 | # PyBuilder
67 | target/
68 |
69 | # IPython Notebook
70 | .ipynb_checkpoints
71 |
72 | # pyenv
73 | .python-version
74 |
75 | # celery beat schedule file
76 | celerybeat-schedule
77 |
78 | # dotenv
79 | .env
80 |
81 | # virtualenv
82 | venv/
83 | ENV/
84 |
85 | # Spyder project settings
86 | .spyderproject
87 |
88 | # Rope project settings
89 | .ropeproject
90 |
--------------------------------------------------------------------------------
/tomatych.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | # Simple Hackable Pomodoro Timer
4 | # ===============================
5 |
6 | #
7 | #
8 | # Decription
9 | # -----------
10 | #
11 | # Intended to be hacked and modified to fit your specific vision of how Pomodoro timers should work. Some assembly may be required :)
12 | #
13 | # See recipes:
14 | #
15 | # * [Score Habitica habits on completed or canceled Pomodoros](http://developer.run/18#habitica)
16 | # * [Set Slack to do not disturb mode while Pomodoro is running](http://developer.run/18#dnd)
17 | # * [Set Tomato Emoji as Slack status while Pomodoro is running](http://developer.run/18#slack)
18 | # * [More...](http://developer.run/18)
19 |
20 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin)
21 |
22 | # Requirements
23 | # ------------
24 | # 1. On Linux install package `python-tk`, Windows should have it installed with Python
25 | # 2. `pip install requests`
26 |
27 | try:
28 | import Tkinter as tk
29 | except ImportError:
30 | import tkinter as tk
31 | import time
32 | import datetime
33 | import requests
34 |
35 | class App():
36 | def __init__(self):
37 | self.root = tk.Tk()
38 | self.root.wm_attributes("-topmost", 1) # always on top
39 | self.label = tk.Label(font=("Helvetica Neue", 44))
40 | self.label.pack()
41 |
42 | self.buttons = tk.Frame(self.root)
43 | self.buttons.pack()
44 | tk.Button(self.buttons, text ="Start", command=lambda: self.start()).pack(side=tk.LEFT)
45 | tk.Button(self.buttons, text ="Cancel", command=lambda: self.cancel()).pack(side=tk.LEFT)
46 |
47 | self.end = time.time()
48 | self.started = False
49 |
50 | self.update_clock()
51 | self.root.mainloop()
52 |
53 | def start(self):
54 | self.started = True
55 | self.end = time.time() + datetime.timedelta(minutes=25).total_seconds()
56 |
57 | print("start")
58 |
59 | def cancel(self):
60 | self.started = False
61 | self.end = time.time()
62 |
63 | print("canceled")
64 |
65 | def complete(self):
66 | self.started = False
67 |
68 | print("completed")
69 |
70 | def update_clock(self):
71 | delta = self.end - time.time()
72 | if delta<0:
73 | self.label.configure(text="00:00", bg="#d9d9d9")
74 | self.root.wm_title("Pomodoro")
75 | if self.started:
76 | self.complete()
77 | else:
78 | time_left = datetime.datetime.fromtimestamp(delta).strftime("%M:%S")
79 | self.root.wm_title("(%s) Pomodoro" % time_left)
80 | self.label.configure(text=time_left, bg="#ca1616")
81 | self.root.after(1000, self.update_clock)
82 |
83 | app=App()
84 |
--------------------------------------------------------------------------------
/tomatych_habitica.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | # Simple Hackable Pomodoro Timer
4 | # ===============================
5 |
6 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin)
7 |
8 | # Requirements
9 | # ------------
10 | # 1. On Linux and Mac install package `python-tk`
11 | # 2. pip install requests
12 |
13 | try:
14 | import Tkinter as tk
15 | except ImportError:
16 | import tkinter as tk
17 | import time
18 | import datetime
19 | import os
20 | import requests
21 |
22 | API_TOKEN = '' # https://habitica.com/#/options/settings/api
23 | USER_ID = '' # https://habitica.com/#/options/settings/api
24 | TASK_ID = ''
25 |
26 |
27 | class App():
28 | def __init__(self):
29 | self.root = tk.Tk()
30 | self.root.wm_attributes("-topmost", 1) # always on top
31 | self.root.tk.call('wm', 'iconphoto', self.root._w, tk.PhotoImage(data="R0lGODlhIAAgAOMIAAAAAHkAAJcDALUhBgBlANM/JAChAPFdQv///////////////////////////////yH+EUNyZWF0ZWQgd2l0aCBHSU1QACH5BAEKAAgALAAAAAAgACAAAASwEMlJq704622BB0ZofKDIUaQ4fuo5pSIcupK8eu1GkkM/EEDC7oMZeny/oBFQNCKDQmNz+FRKX5+D9lDoFlRIsG+55XrFPfSAvPV+RWH42Fh2q9VLN3LPHwj+AnlefYR+gIJdhX2AgUZ6inuMS5CGjH8BmAGTkJaAmZpOnJ0Cn5uKo6SZJCgfSKilRBc8Pq+qsR2ttKOwHlMArru2vTpLVy7FxifIQzQIyzvN0dLTEhEAOw=="))
32 | self.label = tk.Label(font=("Helvetica Neue", 44))
33 | self.label.pack()
34 |
35 | self.buttons = tk.Frame(self.root)
36 | self.buttons.pack()
37 | tk.Button(self.buttons, text ="Start", command=lambda: self.start()).pack(side=tk.LEFT)
38 | tk.Button(self.buttons, text ="Cancel", command=lambda: self.cancel()).pack(side=tk.LEFT)
39 |
40 | self.end = time.time()
41 | self.started = False
42 |
43 | self.update_clock()
44 | self.root.mainloop()
45 |
46 | def start(self):
47 | self.started = True
48 | self.end = time.time() + datetime.timedelta(minutes=25).total_seconds()
49 |
50 | print("start")
51 |
52 | def cancel(self):
53 | self.started = False
54 | self.end = time.time()
55 |
56 | print("canceled")
57 | requests.post('https://habitica.com/api/v3/tasks/'+TASK_ID+'/score/down', headers={'x-api-key': API_TOKEN, 'x-api-user': USER_ID})
58 |
59 | def complete(self):
60 | self.started = False
61 |
62 | print("completed")
63 | requests.post('https://habitica.com/api/v3/tasks/'+TASK_ID+'/score/up', headers={'x-api-key': API_TOKEN, 'x-api-user': USER_ID})
64 |
65 | def update_clock(self):
66 | delta = self.end - time.time()
67 | if delta<0:
68 | self.label.configure(text="00:00", bg="#d9d9d9")
69 | self.root.wm_title("Pomodoro")
70 | if self.started:
71 | self.complete()
72 | else:
73 | time_left = datetime.datetime.fromtimestamp(delta).strftime("%M:%S")
74 | self.root.wm_title("(%s) Pomodoro" % time_left)
75 | self.label.configure(text=time_left, bg="#ca1616")
76 | self.root.after(1000, self.update_clock)
77 |
78 | app=App()
79 |
--------------------------------------------------------------------------------
/tomatych_slack.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | # Simple Hackable Pomodoro Timer
4 | # ===============================
5 |
6 | # Some assembly may be required :)
7 | # [Read More](http://developer.run/18)
8 |
9 | # Author: [Dmitry](http://dmi3.net) [Source](https://github.com/dmi3/bin)
10 |
11 | # Requirements
12 | # ------------
13 | # 1. On Linux and Mac install package `python-tk`
14 | # 2. pip install requests
15 |
16 | try:
17 | import Tkinter as tk
18 | except ImportError:
19 | import tkinter as tk
20 | import time
21 | import datetime
22 | import os
23 | import requests
24 |
25 | xoxp_TOKEN = '' # get one at https://api.slack.com/custom-integrations/legacy-tokens
26 |
27 | class App():
28 | def __init__(self):
29 | self.root = tk.Tk()
30 | self.root.wm_attributes("-topmost", 1) # always on top
31 | self.root.tk.call('wm', 'iconphoto', self.root._w, tk.PhotoImage(data="R0lGODlhIAAgAOMIAAAAAHkAAJcDALUhBgBlANM/JAChAPFdQv///////////////////////////////yH+EUNyZWF0ZWQgd2l0aCBHSU1QACH5BAEKAAgALAAAAAAgACAAAASwEMlJq704622BB0ZofKDIUaQ4fuo5pSIcupK8eu1GkkM/EEDC7oMZeny/oBFQNCKDQmNz+FRKX5+D9lDoFlRIsG+55XrFPfSAvPV+RWH42Fh2q9VLN3LPHwj+AnlefYR+gIJdhX2AgUZ6inuMS5CGjH8BmAGTkJaAmZpOnJ0Cn5uKo6SZJCgfSKilRBc8Pq+qsR2ttKOwHlMArru2vTpLVy7FxifIQzQIyzvN0dLTEhEAOw=="))
32 | self.label = tk.Label(font=("Helvetica Neue", 44))
33 | self.label.pack()
34 |
35 | self.buttons = tk.Frame(self.root)
36 | self.buttons.pack()
37 | tk.Button(self.buttons, text ="Start", command=lambda: self.start()).pack(side=tk.LEFT)
38 | tk.Button(self.buttons, text ="Cancel", command=lambda: self.cancel()).pack(side=tk.LEFT)
39 |
40 | self.end = time.time()
41 | self.started = False
42 |
43 | self.update_clock()
44 | self.root.mainloop()
45 |
46 | def start(self):
47 | self.started = True
48 | self.end = time.time() + datetime.timedelta(minutes=25).total_seconds()
49 |
50 | print("start")
51 |
52 | requests.get('https://slack.com/api/dnd.setSnooze', params=(('token', xoxp_TOKEN), ('num_minutes', '25')))
53 | requests.post('https://slack.com/api/users.profile.set', params=(('token', xoxp_TOKEN), ('name','status_emoji'), ('value', ':tomato:')))
54 |
55 | def cancel(self):
56 | self.started = False
57 | self.end = time.time()
58 |
59 | print("canceled")
60 |
61 | requests.get('https://slack.com/api/dnd.endSnooze', params=(('token', xoxp_TOKEN),))
62 | requests.post('https://slack.com/api/users.profile.set', params=(('token', xoxp_TOKEN), ('name','status_emoji')))
63 |
64 | def complete(self):
65 | self.started = False
66 |
67 | print("completed")
68 |
69 | requests.get('https://slack.com/api/dnd.endSnooze', params=(('token', xoxp_TOKEN),))
70 | requests.post('https://slack.com/api/users.profile.set', params=(('token', xoxp_TOKEN), ('name','status_emoji')))
71 |
72 | def update_clock(self):
73 | delta = self.end - time.time()
74 | if delta<0:
75 | self.label.configure(text="00:00", bg="#d9d9d9")
76 | self.root.wm_title("Pomodoro")
77 | if self.started:
78 | self.complete()
79 | else:
80 | time_left = datetime.datetime.fromtimestamp(delta).strftime("%M:%S")
81 | self.root.wm_title("(%s) Pomodoro" % time_left)
82 | self.label.configure(text=time_left, bg="#ca1616")
83 | self.root.after(1000, self.update_clock)
84 |
85 | app=App()
86 |
--------------------------------------------------------------------------------