define("xmpp_jid", help="XMPP JID. e.g.: [email protected]", type=str) define("xmpp_password", help="XMPP Password.", type=str) define("xmpp_host", help="XMPP Host", type=str) define("xmpp_port", help="XMPP Port", type=int) define("callback_port", help="HTTP callback port.", type=int) parse_config_file("relay-config.py") start = "http://127.0.0.1:%d/start/" % options['callback_port'].value() message = "http://127.0.0.1:%d/message/" % options['callback_port'].value() xmpp = XMPPProxyBot(options['xmpp_jid'].value(), options['xmpp_password'].value(), start, message) manager = XMPPSessionManager(xmpp) app = tornado.web.Application([ (r'/start/', XMPPProxyCallback, {"callback": manager.on_start}), (r'/message/', XMPPProxyCallback, {"callback": manager.on_message}), ]) if xmpp.connect((options['xmpp_host'].value(), options['xmpp_port'].value())): xmpp.process(block=False) try: app.listen(options['callback_port'].value()) ioloop = tornado.ioloop.IOLoop.instance() ioloop.start() except KeyboardInterrupt: ioloop.stop() xmpp.disconnect(wait=False)
class XMPPManager(LoggingEnabledObject): def __init__(self): define("xmpp_jid", help="XMPP JID. e.g.: [email protected]", type=str) define("xmpp_password", help="XMPP Password.", type=str) define("xmpp_host", help="XMPP Host", type=str) define("xmpp_port", help="XMPP Port", type=int) define("xmpp_relay_user", help="XMPP relay user", type=str) define("callback_port", help="HTTP callback port.", default=15827, type=int) config_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "upstream-config.py") parse_config_file(config_path) self.relay_user = options["xmpp_relay_user"].value() super(XMPPManager, self).__init__("XMPPManager(%s)", options["xmpp_jid"].value()) start = "http://127.0.0.1:%d/start/" % options["callback_port"].value() message = "http://127.0.0.1:%d/message/" % options["callback_port"].value() self.xmpp = XMPPProxyBot(options["xmpp_jid"].value(), options["xmpp_password"].value(), start, message) self.app = tornado.web.Application( [ (r"/start/", XMPPProxyCallback, {"callback": self.on_start}), (r"/message/", XMPPProxyCallback, {"callback": self.on_message}), ] ) if self.xmpp.connect((options["xmpp_host"].value(), options["xmpp_port"].value())): self.xmpp.process(block=False) self.streams = {} self.app.listen(options["callback_port"].value()) def cleanup(self): self.xmpp.disconnect(wait=False) def on_start(self, jid): self.from_user = jid self.info("my JID: " + jid) def on_message(self, data): try: msg = json.loads(data) except Exception as e: self.warning( "cannot parse message from xmpp \ callback: %s, error: %s" % (data, str(e)) ) return try: reply = json.loads(msg["body"]) except Exception as e: self.warning( "cannot parse request: %s, error: %s\ " % (msg["body"], str(e)) ) return self.on_reply(reply, msg) def on_reply(self, reply, msg): if reply["event"] == "pong": pass else: stream_id = reply["id"] stream = self.streams.get(stream_id, None) if stream: if reply["event"] == "establishing": pass elif reply["event"] == "error": stream.on_error(reply["errno"]) self.delete_stream_id(stream_id) elif reply["event"] == "closed": stream.on_close() self.delete_stream_id(stream_id) elif reply["event"] == "data": stream.on_streaming_data(bytes(reply["data"].decode("base64"))) elif reply["event"] == "connected": stream.local_addr = tuple(reply["address"]) stream.on_connect() else: self.warning("unknown event: %s" % reply["event"]) def send_request(self, req): serialized = json.dumps(req) self.xmpp.send_message(mbody=serialized, mto=self.relay_user, mtype="chat", mfrom=self.from_user) def add_stream(self, stream): self.streams[stream.stream_id] = stream def delete_stream_id(self, stream_id): try: del self.streams[stream_id] except KeyError: pass