]> snippets.scripts.mit.edu Git - Scripts/git/.git/blame_incremental - barn-growl/barn-growl.py
kdo: Upstream krb5 now supports kswitch
[Scripts/git/.git] / barn-growl / barn-growl.py
... / ...
CommitLineData
1#!/usr/bin/env python
2
3"""
4Subscribes to zephyr via tzc and sends messages to notification drivers (growl or libnotify).
5"""
6
7import sexpr
8import os
9import subprocess
10import fcntl
11import select
12import sys
13from abstfilter import AbstractConsumer
14import optparse
15import time
16
17class Notifier(AbstractConsumer):
18 def __init__(self, usegrowl, usenotify, useprint):
19 self.usegrowl = usegrowl
20 self.usenotify = usenotify
21 if usenotify:
22 import pynotify
23 pynotify.init("Zephyr")
24 self.pings = {}
25 self.pynotify = pynotify
26 self.useprint = useprint
27 return
28 def feed(self, s):
29 if s is None or type(s) is type(''): return
30 d = dict([(ss[0], len(ss) > 2 and ss[2] or None) for ss in s])
31 if d['tzcspew'] == 'message':
32 zclass = d['class'].lower()
33 zinstance = d['instance'].lower()
34 zop = d['opcode'].lower()
35 zsender = d['sender'].lower()
36 zauth = d['auth'].lower() == 'yes'
37 ztime = "%02d:%02d" % time.strptime(d['time'])[3:5]
38 zmessage = d['message']
39 idtuple = (zclass, zinstance, zsender, ztime)
40 id = '%s/\n%s/\n%s\n %s' % idtuple
41 if zop == 'ping':
42 header = '%s (%s)' % (id, zsender)
43 message = '...'
44 elif zop == 'nil':
45 header = '%s (%s)' % (id, len(zmessage) > 0 and zmessage[0] or zsender)
46 message = '%s' % (len(zmessage) > 1 and zmessage[1] or '')
47 else:
48 return
49 if self.useprint:
50 print (id, header)
51 print message
52 if self.usegrowl:
53 growlnotify = ['growlnotify', '-H', 'localhost', '-a', 'MacZephyr', '-n', 'zephyr', '-d', id, '-t', header]
54 g = subprocess.Popen(growlnotify, stdin=subprocess.PIPE)
55 g.stdin.write(message)
56 g.stdin.close()
57 if self.usenotify:
58 if idtuple in self.pings:
59 self.pings[idtuple].update(header, message)
60 self.pings[idtuple].show()
61 else:
62 n = self.pynotify.Notification(header, message)
63 n.show()
64 if zop == 'ping':
65 self.pings[idtuple] = n
66 self.pings = dict(filter(lambda ((c, i, s, time), v): time == idtuple[3], self.pings.items()))
67 def close(self):
68 return
69
70def main(argv):
71 parser = optparse.OptionParser(usage = '%prog [-s "username@machine"] (--growl | --notify | --print)',
72 description = __doc__.strip())
73 parser.add_option('-s', '--ssh',
74 type = 'string',
75 default = None,
76 dest = 'ssh',
77 help = 'optional remote host to run tzc')
78 parser.add_option('-g', '--growl',
79 action = 'store_true',
80 default = False,
81 dest = 'growl',
82 help = 'use growlnotify for output')
83 parser.add_option('-n', '--notify',
84 action = 'store_true',
85 default = False,
86 dest = 'notify',
87 help = 'use notify-send for output')
88 parser.add_option('-p', '--print',
89 action = 'store_true',
90 default = False,
91 dest = 'useprint',
92 help = 'use stdout for output')
93 opts, args = parser.parse_args()
94
95 usegrowl = opts.growl
96 usenotify = opts.notify
97 useprint = opts.useprint
98 if not usegrowl and not usenotify and not useprint:
99 parser.print_help(sys.stderr)
100 return 1
101 ssh = opts.ssh
102
103 if ssh is None:
104 retval = subprocess.call(['which', 'tzc'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
105 if retval:
106 print 'tzc not in path. Please add -s username@machine to specify remote host.'
107 return 1
108
109 if ssh is not None:
110 command = "ssh -o GSSAPIAuthentication=yes -o GSSAPIDelegateCredentials=yes -o GSSAPIKeyExchange=yes %s 'tzc -si'" % ssh
111 else:
112 command = "tzc -si"
113 p = os.popen(command)
114 r = sexpr.SExprReader(Notifier(usegrowl, usenotify, useprint))
115
116 flags = fcntl.fcntl(p, fcntl.F_GETFL)
117 fcntl.fcntl(p, fcntl.F_SETFL, flags | os.O_NONBLOCK)
118
119 try:
120 while 1:
121 [i,o,e] = select.select([p], [], [], 5)
122 if i: s = p.read(1024)
123 else: s = ''
124
125 if s != '':
126 r.feed(s)
127 except KeyboardInterrupt:
128 pass
129 return 0
130
131if __name__ == "__main__":
132 sys.exit(main(sys.argv))