I've been using i3 and I wanted a notification thing for
it, so I made one. It's not very beautiful, but it does the job: you run a
shell command
$ scripts/notify.py -c red -l 15 this is a notification
and something like this appears in i3bar:
External dependencies are py3status,
clize and
webcolors.
py3status plugin:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 | import json
import os
import os.path as path
from time import time
plugin = None
class Plugin:
NOTIFY_PATH = "~/.i3/notify/notify"
buf = ""
def __init__(self, config):
self.config = config
self.NOTIFY_PATH = path.expanduser(self.NOTIFY_PATH)
if not path.exists(path.dirname(self.NOTIFY_PATH)):
os.makedirs(path.dirname(self.NOTIFY_PATH))
if not path.exists(self.NOTIFY_PATH):
os.mkfifo(self.NOTIFY_PATH)
fifofd = os.open(self.NOTIFY_PATH, os.O_ASYNC | os.O_NONBLOCK | os.O_RDONLY)
self.fifo = os.fdopen(fifofd)
self.notification = {'deathtime': 0}
def kill(self):
self.fifo.close()
def props(self, d, *a):
return (str(d[k]) if isinstance(d[k], unicode) else d[k] for k in a)
def get_notification(self):
self.buf += self.fifo.read()
if '\n' in self.buf:
notif, self.buf = self.buf.split('\n', 1)
notif = json.loads(notif)
notif['deathtime'] = time() + notif.get('lifetime', 20)
self.notification = notif
return self.props(self.notification, 'text', 'color')
elif time() <= self.notification['deathtime']:
return self.props(self.notification, 'text', 'color')
else:
return '', None
def get_text(self):
text, color = self.get_notification()
return {
'cached_until': time(), # never cache.
'full_text': text,
'color': color,
'name': 'notify'
}
class Py3status:
def notify(self, json, i3status_config):
global plugin
if plugin is None:
plugin = Plugin(i3status_config)
response = plugin.get_text()
return (0, response)
|
executable script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | #!/usr/bin/python
from clize import run, clize
import json
import os.path as path
import sys
import webcolors
NOTIFY_PATH = "~/.i3/notify/notify"
@clize(alias={'color': ('c',), 'ttl': ('l',)})
def main(color='FFFFFF', ttl=20, *text):
try:
color = webcolors.name_to_hex(color)
except:
color = '#' + color.strip('#')
obj = {
'color': color.upper(),
'lifetime': ttl
}
inp = '' if sys.stdin.isatty() else sys.stdin.read()
if not text:
notify = inp
else:
notify = ' '.join(text)
if '{}' in notify:
notify = notify.format(inp)
obj['text'] = notify
with open(path.expanduser(NOTIFY_PATH), 'a') as f:
f.write("{}\n".format(json.dumps(obj)))
sys.stdout.write(inp)
if __name__ == '__main__':
run(main)
|