def setup(self): self.webhook = NebHookServer(8500) self.webhook.daemon = True self.webhook.start() # init the plugins for cls_name in self.plugin_cls: self.plugins[cls_name] = self.plugin_cls[cls_name](self.matrix, self.config, self.webhook) while True: try: sync = self.matrix.initial_sync() break except ConnectionError: pass log.debug("Notifying plugins of initial sync results") for plugin_name in self.plugins: plugin = self.plugins[plugin_name] plugin.on_sync(sync) # see if this plugin needs a webhook if plugin.get_webhook_key(): self.webhook.set_plugin(plugin.get_webhook_key(), plugin)
def setup(self): self.webhook = NebHookServer(8500) self.webhook.daemon = True self.webhook.start() # init the plugins for cls_name in self.plugin_cls: self.plugins[cls_name] = self.plugin_cls[cls_name]( self.matrix, self.config, self.webhook ) while True: try: sync = self.matrix.initial_sync() break except ConnectionError: pass log.debug("Notifying plugins of initial sync results") for plugin_name in self.plugins: plugin = self.plugins[plugin_name] plugin.on_sync(sync) # see if this plugin needs a webhook if plugin.get_webhook_key(): self.webhook.set_plugin(plugin.get_webhook_key(), plugin)
def setup(self): self.webhook = NebHookServer(8500) self.webhook.daemon = True self.webhook.start() # init the plugins for cls_name in self.plugin_cls: self.plugins[cls_name] = self.plugin_cls[cls_name](self.matrix, self.config, self.webhook) sync = self.matrix.sync(timeout_ms=30000, since=self.sync_token) self.parse_sync(sync, initial_sync=True) log.debug("Notifying plugins of initial sync results") for plugin_name in self.plugins: plugin = self.plugins[plugin_name] plugin.on_sync(sync) # see if this plugin needs a webhook if plugin.get_webhook_key(): self.webhook.set_plugin(plugin.get_webhook_key(), plugin)
def setup(self): self.webhook = NebHookServer(8500) self.webhook.daemon = True self.webhook.start() # init the plugins for cls_name in self.plugin_cls: self.plugins[cls_name] = self.plugin_cls[cls_name]( self.matrix, self.config, self.webhook ) sync = self.matrix.sync(timeout_ms=30000, since=self.sync_token) self.parse_sync(sync, initial_sync=True) log.debug("Notifying plugins of initial sync results") for plugin_name in self.plugins: plugin = self.plugins[plugin_name] plugin.on_sync(sync) # see if this plugin needs a webhook if plugin.get_webhook_key(): self.webhook.set_plugin(plugin.get_webhook_key(), plugin)
class Engine(object): """Orchestrates plugins and the matrix API/endpoints.""" PREFIX = "!" def __init__(self, matrix_api, config): self.plugin_cls = {} self.plugins = {} self.config = config self.matrix = matrix_api def setup(self): self.webhook = NebHookServer(8500) self.webhook.daemon = True self.webhook.start() # init the plugins for cls_name in self.plugin_cls: self.plugins[cls_name] = self.plugin_cls[cls_name]( self.matrix, self.config, self.webhook ) while True: try: sync = self.matrix.initial_sync() break except ConnectionError: pass log.debug("Notifying plugins of initial sync results") for plugin_name in self.plugins: plugin = self.plugins[plugin_name] plugin.on_sync(sync) # see if this plugin needs a webhook if plugin.get_webhook_key(): self.webhook.set_plugin(plugin.get_webhook_key(), plugin) def _help(self): return ( "Installed plugins: %s - Type '%shelp <plugin_name>' for more." % (self.plugins.keys(), Engine.PREFIX) ) def add_plugin(self, plugin): log.debug("add_plugin %s", plugin) if not plugin.name: raise NebError("No name for plugin %s" % plugin) self.plugin_cls[plugin.name] = plugin def parse_membership(self, event): log.info("Parsing membership: %s", event) if (event["state_key"] == self.config.user_id and event["content"]["membership"] == "invite"): user_id = event["user_id"] if user_id in self.config.admins: self.matrix.join_room(event["room_id"]) else: log.info( "Refusing invite, %s not in admin list. Event: %s", user_id, event ) def parse_msg(self, event): body = event["content"]["body"] if (event["user_id"] == self.config.user_id or event["content"]["msgtype"] == "m.notice"): return if body.startswith(Engine.PREFIX): room = event["room_id"] try: segments = body.split() cmd = segments[0][1:] if cmd == "help": if len(segments) == 2 and segments[1] in self.plugins: # return help on a plugin self.matrix.send_message( room, self.plugins[segments[1]].__doc__ ) else: # return generic help self.matrix.send_message(room, self._help()) elif cmd in self.plugins: plugin = self.plugins[cmd] responses = None try: responses = plugin.run( event, unicode(" ".join(body.split()[1:]).encode("utf8")) ) except CommandNotFoundError as e: self.matrix.send_message( room, str(e) ) except MatrixRequestError as ex: self.matrix.send_message( room, "Problem making request: (%s) %s" % (ex.code, ex.content) ) if responses: log.debug("[Plugin-%s] Response => %s", cmd, responses) if type(responses) == list: for res in responses: if type(res) in [str, unicode]: self.matrix.send_message( room, res ) else: self.matrix.send_message_event( room, "m.room.message", res ) elif type(responses) in [str, unicode]: self.matrix.send_message( room, responses ) else: self.matrix.send_message_event( room, "m.room.message", responses ) except NebError as ne: self.matrix.send_message(room, ne.as_str()) except Exception as e: log.exception(e) self.matrix.send_message( room, "Fatal error when processing command." ) else: try: for p in self.plugins: self.plugins[p].on_msg(event, body) except Exception as e: log.exception(e) def event_proc(self, event): etype = event["type"] switch = { "m.room.member": self.parse_membership, "m.room.message": self.parse_msg } try: switch[etype](event) except KeyError: try: for p in self.plugins: self.plugins[p].on_event(event, etype) except Exception as e: log.exception(e) except Exception as e: log.error("Couldn't process event: %s", e) def event_loop(self): end = "END" while True: j = self.matrix.event_stream(timeout=30000, from_token=end) end = j["end"] events = j["chunk"] log.debug("Received: %s", events) for event in events: self.event_proc(event)
class Engine(object): """Orchestrates plugins and the matrix API/endpoints.""" PREFIX = "!" def __init__(self, matrix_api, config): self.plugin_cls = {} self.plugins = {} self.config = config self.matrix = matrix_api def setup(self): self.webhook = NebHookServer(8500) self.webhook.daemon = True self.webhook.start() # init the plugins for cls_name in self.plugin_cls: self.plugins[cls_name] = self.plugin_cls[cls_name](self.matrix, self.config, self.webhook) sync = self.matrix.initial_sync() log.debug("Notifying plugins of initial sync results") for plugin_name in self.plugins: plugin = self.plugins[plugin_name] plugin.on_sync(sync) # see if this plugin needs a webhook if plugin.get_webhook_key(): self.webhook.set_plugin(plugin.get_webhook_key(), plugin) def _help(self): return ( "Installed plugins: %s - Type '%shelp <plugin_name>' for more." % (self.plugins.keys(), Engine.PREFIX)) def add_plugin(self, plugin): log.debug("add_plugin %s", plugin) if not plugin.name: raise NebError("No name for plugin %s" % plugin) self.plugin_cls[plugin.name] = plugin def parse_membership(self, event): log.info("Parsing membership: %s", event) if (event["state_key"] == self.config.user_id and event["content"]["membership"] == "invite"): user_id = event["user_id"] if user_id in self.config.admins: self.matrix.join_room(event["room_id"]) else: log.info("Refusing invite, %s not in admin list. Event: %s", user_id, event) def parse_msg(self, event): body = event["content"]["body"] if (event["user_id"] == self.config.user_id or event["content"]["msgtype"] == "m.notice"): return if body.startswith(Engine.PREFIX): room = event["room_id"] try: segments = body.split() cmd = segments[0][1:] if self.config.case_insensitive: cmd = cmd.lower() if cmd == "help": if len(segments) == 2 and segments[1] in self.plugins: # return help on a plugin self.matrix.send_message( room, self.plugins[segments[1]].__doc__, msgtype="m.notice") else: # return generic help self.matrix.send_message(room, self._help(), msgtype="m.notice") elif cmd in self.plugins: plugin = self.plugins[cmd] responses = None try: responses = plugin.run( event, unicode(" ".join(body.split()[1:]).encode("utf8"))) except CommandNotFoundError as e: self.matrix.send_message(room, str(e), msgtype="m.notice") except MatrixRequestError as ex: self.matrix.send_message( room, "Problem making request: (%s) %s" % (ex.code, ex.content), msgtype="m.notice") if responses: log.debug("[Plugin-%s] Response => %s", cmd, responses) if type(responses) == list: for res in responses: if type(res) in [str, unicode]: self.matrix.send_message( room, res, msgtype="m.notice") else: self.matrix.send_message_event( room, "m.room.message", res) elif type(responses) in [str, unicode]: self.matrix.send_message(room, responses, msgtype="m.notice") else: self.matrix.send_message_event( room, "m.room.message", responses) except NebError as ne: self.matrix.send_message(room, ne.as_str(), msgtype="m.notice") except Exception as e: log.exception(e) self.matrix.send_message( room, "Fatal error when processing command.", msgtype="m.notice") else: try: for p in self.plugins: self.plugins[p].on_msg(event, body) except Exception as e: log.exception(e) def event_proc(self, event): etype = event["type"] switch = { "m.room.member": self.parse_membership, "m.room.message": self.parse_msg } try: switch[etype](event) except KeyError: try: for p in self.plugins: self.plugins[p].on_event(event, etype) except Exception as e: log.exception(e) except Exception as e: log.error("Couldn't process event: %s", e) def event_loop(self): end = "END" while True: j = self.matrix.event_stream(timeout=30000, from_token=end) end = j["end"] events = j["chunk"] log.debug("Received: %s", events) for event in events: self.event_proc(event)
class Engine(object): """Orchestrates plugins and the matrix API/endpoints.""" PREFIX = "!" def __init__(self, matrix_api, config): self.plugin_cls = {} self.plugins = {} self.config = config self.matrix = matrix_api self.sync_token = None # set later by initial sync def setup(self): self.webhook = NebHookServer(8500) self.webhook.daemon = True self.webhook.start() # init the plugins for cls_name in self.plugin_cls: self.plugins[cls_name] = self.plugin_cls[cls_name]( self.matrix, self.config, self.webhook ) sync = self.matrix.sync(timeout_ms=30000, since=self.sync_token) self.parse_sync(sync, initial_sync=True) log.debug("Notifying plugins of initial sync results") for plugin_name in self.plugins: plugin = self.plugins[plugin_name] plugin.on_sync(sync) # see if this plugin needs a webhook if plugin.get_webhook_key(): self.webhook.set_plugin(plugin.get_webhook_key(), plugin) def _help(self): return ( "Installed plugins: %s - Type '%shelp <plugin_name>' for more." % (self.plugins.keys(), Engine.PREFIX) ) def add_plugin(self, plugin): log.debug("add_plugin %s", plugin) if not plugin.name: raise NebError("No name for plugin %s" % plugin) self.plugin_cls[plugin.name] = plugin def parse_membership(self, event): log.info("Parsing membership: %s", event) if (event["state_key"] == self.config.user_id and event["content"]["membership"] == "invite"): user_id = event["sender"] if user_id in self.config.admins: self.matrix.join_room(event["room_id"]) else: log.info( "Refusing invite, %s not in admin list. Event: %s", user_id, event ) def parse_msg(self, event): body = event["content"]["body"] if (event["sender"] == self.config.user_id or event["content"]["msgtype"] == "m.notice"): return if body.startswith(Engine.PREFIX): room = event["room_id"] # room_id added by us try: segments = body.split() cmd = segments[0][1:] if self.config.case_insensitive: cmd = cmd.lower() if cmd == "help": if len(segments) == 2 and segments[1] in self.plugins: # return help on a plugin self.matrix.send_message( room, self.plugins[segments[1]].__doc__, msgtype="m.notice" ) else: # return generic help self.matrix.send_message(room, self._help(), msgtype="m.notice") elif cmd in self.plugins: plugin = self.plugins[cmd] responses = None try: responses = plugin.run( event, unicode(" ".join(body.split()[1:]).encode("utf8")) ) except CommandNotFoundError as e: self.matrix.send_message( room, str(e), msgtype="m.notice" ) except MatrixRequestError as ex: self.matrix.send_message( room, "Problem making request: (%s) %s" % (ex.code, ex.content), msgtype="m.notice" ) if responses: log.debug("[Plugin-%s] Response => %s", cmd, responses) if type(responses) == list: for res in responses: if type(res) in [str, unicode]: self.matrix.send_message( room, res, msgtype="m.notice" ) else: self.matrix.send_message_event( room, "m.room.message", res ) elif type(responses) in [str, unicode]: self.matrix.send_message( room, responses, msgtype="m.notice" ) else: self.matrix.send_message_event( room, "m.room.message", responses ) except NebError as ne: self.matrix.send_message(room, ne.as_str(), msgtype="m.notice") except Exception as e: log.exception(e) self.matrix.send_message( room, "Fatal error when processing command.", msgtype="m.notice" ) else: try: for p in self.plugins: self.plugins[p].on_msg(event, body) except Exception as e: log.exception(e) def event_proc(self, event): etype = event["type"] switch = { "m.room.member": self.parse_membership, "m.room.message": self.parse_msg } try: switch[etype](event) except KeyError: try: for p in self.plugins: self.plugins[p].on_event(event, etype) except Exception as e: log.exception(e) except Exception as e: log.error("Couldn't process event: %s", e) def event_loop(self): while True: j = self.matrix.sync(timeout_ms=30000, since=self.sync_token) self.parse_sync(j) def parse_sync(self, sync_result, initial_sync=False): self.sync_token = sync_result["next_batch"] # for when we start syncing # check invited rooms rooms = sync_result["rooms"]["invite"] for room_id in rooms: events = rooms[room_id]["invite_state"]["events"] self.process_events(events, room_id) # return early if we're performing an initial sync (ie: don't parse joined rooms, just drop the state) if initial_sync: return # check joined rooms rooms = sync_result["rooms"]["join"] for room_id in rooms: events = rooms[room_id]["timeline"]["events"] self.process_events(events, room_id) def process_events(self, events, room_id): for event in events: event["room_id"] = room_id self.event_proc(event)