annotate service/xidle/xidle.py @ 1513:c829df2b0dd5

new graph output for browsers, with autorefresh Ignore-this: e4ff4dbed311b238d90988a1891ef640 darcs-hash:ba19d0d8975104ec6a3580e50cf8b7ca7745abdc
author drewp <drewp@bigasterisk.com>
date Mon, 03 Feb 2020 23:47:23 -0800
parents 6cd9341f0a28
children 2500a3ee9102
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
858
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
1 """
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
2 X server idle time is now available over http!
1166
64e36f30f046 xidle to docker
drewp <drewp@bigasterisk.com>
parents: 1097
diff changeset
3
64e36f30f046 xidle to docker
drewp <drewp@bigasterisk.com>
parents: 1097
diff changeset
4 Note: HD-4110 webcams stop X from going idle by sending events
64e36f30f046 xidle to docker
drewp <drewp@bigasterisk.com>
parents: 1097
diff changeset
5 constantly. Run this to fix:
64e36f30f046 xidle to docker
drewp <drewp@bigasterisk.com>
parents: 1097
diff changeset
6
64e36f30f046 xidle to docker
drewp <drewp@bigasterisk.com>
parents: 1097
diff changeset
7 xinput disable "HP Webcam HD-4110"
858
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
8 """
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
9 import time
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
10 import socket, json, os
858
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
11 from rdflib import Namespace, URIRef, Literal
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
12 from influxdb import InfluxDBClient
1166
64e36f30f046 xidle to docker
drewp <drewp@bigasterisk.com>
parents: 1097
diff changeset
13 import influxdb.exceptions
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
14 import cyclone.web
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
15 from twisted.internet import reactor, task
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
16 from standardservice.logsetup import log, verboseLogging
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
17 from patchablegraph import PatchableGraph, CycloneGraphEventsHandler, CycloneGraphHandler
858
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
18
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
19 DEV = Namespace("http://projects.bigasterisk.com/device/")
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
20 ROOM = Namespace("http://projects.bigasterisk.com/room/")
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
21
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
22 host = socket.gethostname()
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
23 client = InfluxDBClient('bang6', 9060, 'root', 'root', 'main')
858
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
24
1168
808503d8c5cc xidle support graph/events streams, use actmod module for the input now
drewp <drewp@bigasterisk.com>
parents: 1166
diff changeset
25 os.environ['DISPLAY'] = ':0.0'
808503d8c5cc xidle support graph/events streams, use actmod module for the input now
drewp <drewp@bigasterisk.com>
parents: 1166
diff changeset
26
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
27 import pxss
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
28 # another option: http://thp.io/2007/09/x11-idle-time-and-focused-window-in.html
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
29
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
30 def get_idle_time():
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
31 return pxss.get_info().idle
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
32
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
33 get_idle_time() # fail if we can't get the display or something
1168
808503d8c5cc xidle support graph/events streams, use actmod module for the input now
drewp <drewp@bigasterisk.com>
parents: 1166
diff changeset
34
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
35 class Root(cyclone.web.RequestHandler):
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
36 def get(self):
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
37 get_idle_time() # fail if we can't get the display or something
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
38 self.set_header('content-type', 'text/html')
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
39 self.write('''
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
40 <!doctype html>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
41 <html>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
42 <head>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
43 <title>xidle</title>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
44 <meta charset="utf-8" />
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
45 <script src="/lib/polymer/1.0.9/webcomponentsjs/webcomponents.min.js"></script>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
46 <script src="/lib/require/require-2.3.3.js"></script>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
47 <script src="/rdf/common_paths_and_ns.js"></script>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
48
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
49 <link rel="import" href="/rdf/streamed-graph.html">
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
50 <link rel="import" href="/lib/polymer/1.0.9/polymer/polymer.html">
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
51
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
52 <meta name="mobile-web-app-capable" content="yes">
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
53 <meta name="viewport" content="width=device-width, initial-scale=1">
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
54 </head>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
55 <body>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
56 <template id="t" is="dom-bind">
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
57
858
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
58 Get the <a href="idle">X idle time</a> on %s.
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
59
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
60 <streamed-graph url="graph/xidle/events" graph="{{graph}}"></streamed-graph>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
61 <div id="out"></div>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
62 <script type="module" src="/rdf/streamed_graph_view.js"></script>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
63 </template>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
64 <style>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
65 .served-resources {
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
66 margin-top: 4em;
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
67 border-top: 1px solid gray;
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
68 padding-top: 1em;
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
69 }
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
70 .served-resources a {
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
71 padding-right: 2em;
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
72 }
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
73 </style>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
74
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
75 <div class="served-resources">
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
76 <a href="stats/">/stats/</a>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
77 <a href="graph/dpms">/graph/dpms</a>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
78 <a href="graph/dpms/events">/graph/dpms/events</a>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
79 <a href="idle">/idle</a>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
80 </div>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
81
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
82 </body>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
83 </html>
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
84 ''' % host)
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
85
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
86 class Idle(cyclone.web.RequestHandler):
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
87 def get(self):
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
88 self.set_header('Content-type', 'application/json')
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
89 self.write(json.dumps({"idleMs" : get_idle_time()}))
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
90
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
91 class Poller(object):
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
92 def __init__(self):
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
93 self.points = []
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
94 self.lastSent = None
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
95 self.lastSentTime = 0
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
96 self.lastGraphSent = None
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
97 self.lastGraphSentTime = 0
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
98 task.LoopingCall(self.poll).start(1)
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
99
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
100 def poll(self):
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
101 ms = get_idle_time()
1168
808503d8c5cc xidle support graph/events streams, use actmod module for the input now
drewp <drewp@bigasterisk.com>
parents: 1166
diff changeset
102 ctx = DEV['xidle/%s' % host]
808503d8c5cc xidle support graph/events streams, use actmod module for the input now
drewp <drewp@bigasterisk.com>
parents: 1166
diff changeset
103 subj = URIRef("http://bigasterisk.com/host/%s/xidle" % host)
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
104 lastMinActive = ms < 60 * 1000
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
105 now = int(time.time())
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
106
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
107 nextGraphUpdate = self.lastGraphSentTime + min(10, ms / 1000 / 2)
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
108 if self.lastGraphSent != lastMinActive or now > nextGraphUpdate:
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
109 masterGraph.patchObject(ctx, subj, ROOM['idleTimeMs'], Literal(ms))
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
110 masterGraph.patchObject(ctx, subj, ROOM['idleTimeMinutes'],
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
111 Literal(round(ms / 1000 / 60, 2)))
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
112 self.lastGraphSent = lastMinActive
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
113 self.lastGraphSentTime = now
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
114
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
115 if self.lastSent != lastMinActive or now > self.lastSentTime + 3600:
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
116 self.points.append({"measurement": "presence",
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
117 "tags": {"host": host, "sensor": "xidle"},
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
118 "fields": {"value": 1 if lastMinActive else 0},
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
119 "time": now})
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
120 self.lastSent = lastMinActive
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
121 self.lastSentTime = now
874
16b8c4f36f31 add idleTimeMinutes to rdf graph
drewp <drewp@bigasterisk.com>
parents: 858
diff changeset
122
1168
808503d8c5cc xidle support graph/events streams, use actmod module for the input now
drewp <drewp@bigasterisk.com>
parents: 1166
diff changeset
123 try:
808503d8c5cc xidle support graph/events streams, use actmod module for the input now
drewp <drewp@bigasterisk.com>
parents: 1166
diff changeset
124 client.write_points(self.points, time_precision='s')
808503d8c5cc xidle support graph/events streams, use actmod module for the input now
drewp <drewp@bigasterisk.com>
parents: 1166
diff changeset
125 except influxdb.exceptions.InfluxDBServerError as e:
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
126 log.error(repr(e))
1168
808503d8c5cc xidle support graph/events streams, use actmod module for the input now
drewp <drewp@bigasterisk.com>
parents: 1166
diff changeset
127 reactor.crash()
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
128 self.points = []
858
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
129
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
130 verboseLogging(False)
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
131
1168
808503d8c5cc xidle support graph/events streams, use actmod module for the input now
drewp <drewp@bigasterisk.com>
parents: 1166
diff changeset
132 masterGraph = PatchableGraph()
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
133 poller = Poller()
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
134
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
135 reactor.listenTCP(9107, cyclone.web.Application([
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
136 (r'/', Root),
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
137 (r'/idle', Idle),
1491
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
138 (r'/graph/xidle', CycloneGraphHandler, {'masterGraph': masterGraph}),
6cd9341f0a28 xidle rewrite for docker, py3
drewp <drewp@bigasterisk.com>
parents: 1168
diff changeset
139 (r'/graph/xidle/events', CycloneGraphEventsHandler, {'masterGraph': masterGraph}),
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
140 ]), interface='::')
858
8887a0778a1f new xidle service
drewp <drewp@bigasterisk.com>
parents:
diff changeset
141
1097
3aef251c7585 rewrite xidle to cyclone. add bg updating graph
drewp <drewp@bigasterisk.com>
parents: 1020
diff changeset
142 reactor.run()