summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2013-10-11 02:34:00 +0200
committerDavid Lamparter <equinox@diac24.net>2013-10-11 02:34:00 +0200
commit2c29a04e745eba7c03d7251c697bfc519e0c0f9d (patch)
tree685716724f2e581f73b03685d219a7f3efa87860
parente74527f80308ba20d2c3b4d21e4dd9c767ec6906 (diff)
general: add longpoll.py (glib/libsoup longpoll)
-rw-r--r--longpoll.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/longpoll.py b/longpoll.py
new file mode 100644
index 0000000..a771e32
--- /dev/null
+++ b/longpoll.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# vim: set expandtab ts=4:
+
+from gi.repository import GLib, Soup
+import json
+
+ml = GLib.MainLoop()
+
+def callback(new, old):
+ try:
+ import datadiff
+ if old is None:
+ return
+ print datadiff.diff(old, new)
+ except ImportError:
+ print 'received longpoll update, datadiff not available'
+
+prevjson = None
+
+LPURL = 'http://beaglebone.local.sublab.org/longpoll'
+uri = Soup.URI.new(LPURL)
+
+#
+# TODO: add timer that aborts/kills previous requests after a timeout
+# for proper error recovery
+#
+# Note: message.status_code contains HTTP codes _or_ libsoup specific errors
+# (status_code < 100 => libsoup)
+#
+
+def cb(session, message, cbarg):
+ global prevjson
+
+ def request_next():
+ uri.set_query(prevjson['ref'])
+ get = Soup.Message.new_from_uri("GET", uri)
+ ss.queue_message(get, cb, None)
+
+ if message.status_code != 200:
+ print 'cb error:', message.status_code
+ if prevjson is None:
+ print 'first request failed'
+ ml.quit()
+ request_next()
+ return
+
+ try:
+ rdata = message.response_body.flatten().get_data()
+ if rdata == '':
+ request_next()
+ return
+
+ njson = json.loads(rdata)
+ print 'CB OK', njson['ref']
+
+ if prevjson is None or njson['ref'] != prevjson['ref']:
+ callback(njson['data'],
+ prevjson['data'] if prevjson is not None else None)
+ prevjson = njson
+
+ finally:
+ request_next()
+
+ss = Soup.SessionAsync.new()
+get = Soup.Message.new_from_uri("GET", uri)
+ss.queue_message(get, cb, None)
+del get
+
+ml.run()
+