comparison service/xidle/xidle.py @ 292:105969d248d6

rewrite xidle to cyclone. add bg updating graph Ignore-this: 5e02bc3572723517fb5ed3aa6971805a
author drewp@bigasterisk.com
date Mon, 01 Aug 2016 02:24:50 -0700
parents 1e94d074f642
children 01817264cc3d
comparison
equal deleted inserted replaced
291:299ddd7e2070 292:105969d248d6
2 from __future__ import division 2 from __future__ import division
3 """ 3 """
4 X server idle time is now available over http! 4 X server idle time is now available over http!
5 """ 5 """
6 6
7 from bottle import run, get, put, request, response 7 import time
8 import subprocess, sys, socket 8 import sys, socket, json
9 from rdflib import Namespace, URIRef, Literal 9 from rdflib import Namespace, URIRef, Literal
10 from influxdb import InfluxDBClient
11 import cyclone.web
12 from twisted.internet import reactor, task
10 13
11 # from http://bebop.bigasterisk.com/python/ 14 # from http://bebop.bigasterisk.com/python/
12 import xss 15 import xss
13 # another option: http://thp.io/2007/09/x11-idle-time-and-focused-window-in.html 16 # another option: http://thp.io/2007/09/x11-idle-time-and-focused-window-in.html
14 17
17 20
18 sys.path.append("/my/site/magma") 21 sys.path.append("/my/site/magma")
19 from stategraph import StateGraph 22 from stategraph import StateGraph
20 23
21 host = socket.gethostname() 24 host = socket.gethostname()
25 client = InfluxDBClient('bang6', 9060, 'root', 'root', 'main')
22 26
23 @get("/") 27 class Root(cyclone.web.RequestHandler):
24 def index(): 28 def get(self):
25 xss.get_info() # fail if we can't get the display or something 29 xss.get_info() # fail if we can't get the display or something
26 return ''' 30 self.write('''
27 Get the <a href="idle">X idle time</a> on %s. 31 Get the <a href="idle">X idle time</a> on %s.
28 <a href="graph">rdf graph</a> available.''' % host 32 <a href="graph">rdf graph</a> available.''' % host)
33
34 class Idle(cyclone.web.RequestHandler):
35 def get(self):
36 self.set_header('Content-type', 'application/json')
37 self.write(json.dumps({"idleMs" : xss.get_info().idle}))
38
39 class Graph(cyclone.web.RequestHandler):
40 def get(self):
41 self.set_header('Content-type', 'application/x-trig')
29 42
30 @get("/idle") 43 g = StateGraph(ctx=DEV['xidle/%s' % host])
31 def monitor():
32 return {"idleMs" : xss.get_info().idle}
33 44
34 @get("/graph") 45 ms = xss.get_info().idle
35 def graph(): 46 subj = URIRef("http://bigasterisk.com/host/%s/xidle" % host)
36 g = StateGraph(ctx=DEV['xidle/%s' % host]) 47 g.add((subj, ROOM['idleTimeMs'], Literal(ms)))
48 g.add((subj, ROOM['idleTimeMinutes'], Literal(ms / 1000 / 60)))
37 49
38 ms = xss.get_info().idle 50 self.write(g.asTrig())
39 subj = URIRef("http://bigasterisk.com/host/%s/xidle" % host)
40 g.add((subj, ROOM['idleTimeMs'], Literal(ms)))
41 g.add((subj, ROOM['idleTimeMinutes'], Literal(ms / 1000 / 60)))
42 51
43 response.set_header('Content-type', 'application/x-trig') 52 class Poller(object):
44 return g.asTrig() 53 def __init__(self):
54 self.points = []
55 self.lastSent = None
56 self.lastSentTime = 0
57 task.LoopingCall(self.poll).start(5)
58
59 def poll(self):
60 ms = xss.get_info().idle
61 lastMinActive = ms < 60 * 1000
62 now = int(time.time())
63 if self.lastSent != lastMinActive or now > self.lastSentTime + 3600:
64 self.points.append({"measurement": "presence",
65 "tags": {"host": host, "sensor": "xidle"},
66 "fields": {"value": 1 if lastMinActive else 0},
67 "time": now})
68 self.lastSent = lastMinActive
69 self.lastSentTime = now
45 70
46 run(host="[::]", server='gunicorn', port=9107, quiet=True) 71 client.write_points(self.points, time_precision='s')
72 self.points = []
47 73
74 poller = Poller()
75
76 reactor.listenTCP(9107, cyclone.web.Application([
77 (r'/', Root),
78 (r'/idle', Idle),
79 (r'/graph', Graph),
80 ]), interface='::')
81
82 reactor.run()