Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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)