import json import socket import threading from django.conf import settings from websocket import WebSocketException, create_connection __all__ = ["EventPostingError", "EventPoster", "post", "last"] _local = threading.local() class EventPostingError(RuntimeError): pass class EventPoster(object): def __init__(self): self._connect() def _connect(self): self._conn = create_connection(settings.EVENT_DAEMON_POST) if settings.EVENT_DAEMON_KEY is not None: self._conn.send( json.dumps({"command": "auth", "key": settings.EVENT_DAEMON_KEY}) ) resp = json.loads(self._conn.recv()) if resp["status"] == "error": raise EventPostingError(resp["code"]) def post(self, channel, message, tries=0): try: self._conn.send( json.dumps({"command": "post", "channel": channel, "message": message}) ) resp = json.loads(self._conn.recv()) if resp["status"] == "error": raise EventPostingError(resp["code"]) else: return resp["id"] except WebSocketException: if tries > 10: raise self._connect() return self.post(channel, message, tries + 1) def last(self, tries=0): try: self._conn.send('{"command": "last-msg"}') resp = json.loads(self._conn.recv()) if resp["status"] == "error": raise EventPostingError(resp["code"]) else: return resp["id"] except WebSocketException: if tries > 10: raise self._connect() return self.last(tries + 1) def _get_poster(): if "poster" not in _local.__dict__: _local.poster = EventPoster() return _local.poster def post(channel, message): try: return _get_poster().post(channel, message) except (WebSocketException, socket.error): try: del _local.poster except AttributeError: pass return 0 def last(): try: return _get_poster().last() except (WebSocketException, socket.error): try: del _local.poster except AttributeError: pass return 0