Beispiel #1
0
def test_remove_listener():
    def dummy_listener():
        pass

    client = MatrixClient("http://example.com")
    handler = client.add_listener(dummy_listener)

    found_listener = False
    for listener in client.listeners:
        if listener["uid"] == handler:
            found_listener = True
            break

    assert found_listener, "listener was not added properly"

    client.remove_listener(handler)
    found_listener = False
    for listener in client.listeners:
        if listener["uid"] == handler:
            found_listener = True
            break

    assert not found_listener, "listener was not removed properly"
class matrix_utils_ext(object):

    __MODULE_NAME__ = "Matrix Bot"
    __VERSION__ = "v0.0.1a"

    __MAX_SERVICE__ = 32
    # Number of services that can be simultaneously installed.
    room_tuple = namedtuple("room_tuple", "room_addr listener")

    def __init__(self, config_path="config.json"):
        self.room_dic = {}
        self.services_sensitive_on_clock = set()
        self.is_timer_on = False
        self.is_on = False
        self.nb_current_service = 0
        self.service_list = {}
        # self.logger.setLevel(logging.DEBUG) ;
        try:
            with open(config_path) as f:
                self.config = json.loads(f.read())
        except IOError as e:
            print(e)
        self.login = self.config["login"]
        self.password = self.config["password"]
        module.config = self.config.copy()
        try:
            self.client = MatrixClient(self.config["host"])
            self.client.login(self.login, self.password)
        except MatrixRequestError as e:
            print(e)
            sys.exit()

    def add_service_to_room(self, room, service, message_on_start=None):
        ret = False
        if self.nb_current_service < matrix_utils_ext.__MAX_SERVICE__:
            if service.add_room(
                    room):  # if room has been added to the service correctly
                if service in self.service_list:
                    self.service_list[service] += 1
                else:
                    self.service_list[service] = 1
                ret = True
        else:
            #raise Exception("Maximum number of services ({}) reached".format(str(matrix_utils.__MAX_SERVICE__))) ;
            pass
        return ret

    def remove_service_from_room(self, room, service):
        ret = False
        if service.remove_room(room):
            ret = True
            # if service is not linked to any room, remove from service_list
            self.service_list[service] -= 1
            if self.service_list[service] == 0:
                del self.service_list[service]

        else:
            #raise Exception("Service {} does not exist in room {}.".format(service, room)) ;
            pass
        return ret

# TODO ; eventuellement vérifier si une room avec une même adresse n'existe pas ?

    def add_room(self, room_addr, message_on_start=""):
        room = self.client.join_room(room_addr)
        listener = room.add_listener(self.callback)
        self.room_dic[room] = matrix_utils_ext.room_tuple(
            room_addr, listener
        )  # (room object address, room_name (room address), listener object)
        if message_on_start:
            # Conversion to HTML format
            message_on_start = message_on_start.replace("\n", "<br>")
            message_on_start = message_on_start.replace("\t", "&emsp;")
            room.send_html(message_on_start, msgtype="m.notice")
        return room

    def remove_room(self, room):
        if not (room in self.room_dic):
            return False
        for service in service_list.keys():
            if (room in service.get_room_list()):
                # there are still some services linked to room.
                return False
        listener = self.room_dic[room].listener
        self.client.remove_listener(listener)
        room.leave()
        del self.room_dic[room]
        return True

    def callback(self, room, event):
        if event["type"] == "m.room.message":
            login = re.search("@[aA-zZ]+[0-9]*", event["sender"]).group(0)
            login = login[1:]
            tmp_log = "Event from " + bcolors.OKGREEN + self.room_dic[
                room].room_addr + bcolors.ENDC + " at " + str(
                    datetime.datetime.now()) + " by " + login
            print(tmp_log)
            text = str(event["content"]["body"])
            ## Stop Service Management
            if text == self.config["bot_down_cmd"]:
                self.exit()
            ## Otherwise, run services
            for service in self.service_list.keys():
                if (room in service.get_room_list()):
                    ret = service.run(text, login, room)
                    if ret:
                        for msg in ret:
                            # Conversion to HTML format
                            msg = msg.replace("\n", "<br>")
                            msg = msg.replace("\t", "&emsp;")
                            room.send_html(msg, msgtype="m.notice")

    def spawn(self):
        self.client.start_listener_thread(exception_handler=self.error_handle)
        self.is_on = True
        print(bcolors.OKGREEN +
              "\n---------------------------------------------------\n" +
              "---- Matrix Bot v0.0.1 ----------------------------\n" +
              "---------------------------------------------------\n" +
              bcolors.ENDC)
        while (self.is_on):
            time.sleep(0.5)

    def timer_callback(self, t):
        while (self.is_timer_on):
            if self.is_on:
                for service in self.service_list:
                    if service.is_clock_sensitive():
                        service.clock_update()
                        ret = service.run_on_clock()
                        if ret:
                            # Conversion to HTML format
                            ret = ret.replace("\n", "<br>")
                            ret = ret.replace("\t", "&emsp;")
                            for room in service.get_room_list():
                                room.send_html(ret, msgtype="m.notice")
            time.sleep(t)

    def start_timer(self, t=1):
        if not (self.is_timer_on):
            self.is_timer_on = True
            t1 = threading.Thread(target=self.timer_callback, args=(t, ))
            t1.start()

    def stop_timer(self):
        self.is_timer_on = False

    def exit(self):
        self.is_timer_on = False
        self.is_on = False
        for service in self.service_list:
            print("Module {} {} {} is shutting down.".format(
                bcolors.OKGREEN, service.module_name, bcolors.ENDC))
            tmp_msg = service.exit()
            if tmp_msg:
                for room in service.get_room_list():
                    room.send_text(tmp_msg)
        # for room in self.room_dic:
        # room.send_text(self.config["bot_stop_txt"]);
        sys.exit()

    def error_handle(self, err):
        print("Server is not {} responding {} ({}). Restarting ...".format(
            bcolors.FAIL, bcolors.ENDC, err))
        self.exit()
Beispiel #3
0
class matrix_utils(object):

    __MAX_SERVICE__ = 32
    # Number of services that can be simultaneously installed.

    def __init__(self, config_path="config.json"):
        self.rooms = {}
        self.room_name_to_room = {}
        self.services = {}
        self.services_sensitive_on_clock = set()
        self.is_timer_on = False
        self.is_on = False
        self.nb_current_service = 0
        # self.logger.setLevel(logging.DEBUG) ;
        try:
            with open(config_path) as f:
                self.config = json.loads(f.read())
        except IOError as e:
            print(e)
        self.login = self.config["login"]
        self.password = self.config["password"]
        try:
            self.client = MatrixClient(self.config["host"])
            self.client.login(self.login, self.password)
        except MatrixRequestError as e:
            print(e)
            sys.exit()

    def add_service_to_room(self, room, service, message_on_start=None):
        if self.nb_current_service < matrix_utils.__MAX_SERVICE__:
            tmp_set_service = self.rooms[room][1]
            tmp_set_service_name = self.rooms[room][2]
            service_name = service.keywords[0]
            if not (service in tmp_set_service) and not (
                    service_name in tmp_set_service_name):
                self.rooms[room][1].add(service)
                self.rooms[room][2].add(service_name)
                self.nb_current_service += 1
                if not (service in self.services):
                    self.services[service] = set()
                self.services[service].add(room)
                if message_on_start:
                    room.send_text(message_on_start)
                return True
            else:
                raise Exception("Service already does already exist.")
        else:
            # raise Exception("Maximum number of services ({}) reached".format(str(matrix_utils.__MAX_SERVICE__))) ;
            return False

    def remove_service_from_room(self, room, service):
        tmp_set_service = self.rooms[room][1]
        tmp_set_service_name = self.rooms[room][2]
        tmp_services = self.services[service]
        if service in tmp_set_service:
            tmp_set_service.remove(service)
            tmp_set_service_name.remove(service.keywords[0])
            tmp_services.remove(room)
            self.nb_current_service -= 1
            # if service is not linked to any room, remove it from the ;
            if not (tmp_services
                    ) and service in self.services_sensitive_on_clock:
                self.services_sensitive_on_clock.remove(service)
        else:
            raise Exception("Service {} does not exist.".format(service))

    def add_room(self, room_name, message_on_start=False):
        new_room = self.client.join_room(room_name)
        listener = new_room.add_listener(self.callback)
        self.rooms[new_room] = (room_name, set(), set(), listener)
        self.room_name_to_room[room_name] = new_room
        if message_on_start:
            new_room.send_text(self.config["bot_start_txt"])
        return new_room

    def remove_room(self, room):
        if room in self.room_timer and self.is_timer_on:
            raise Exception("Can not leave rooms while timer is on.")
        if room in self.rooms:
            uuid = self.rooms[room][3]
            self.client.remove_listener(uuid)
            room_name = self.rooms[room][0]
            del self.room_name_to_room[room_name]
            del self.rooms[room]
            room.leave()
        else:
            raise Exception("Room {} does not exist.".format(str(room)))

    def callback(self, room, event):
        if event["type"] == "m.room.message":
            login = re.search("@[aA-zZ]+[0-9]*", event["sender"]).group(0)
            login = login[1:]
            tmp_log = "Event from " + str(self.rooms[room][0]) + " at " + str(
                datetime.datetime.now()) + " by " + login
            print(tmp_log)
            text = str(event["content"]["body"])
            if self.rooms:
                for service in self.rooms[room][1].copy():
                    service.admin(self)
                    ret = service.run(text, login, room)
                    if ret:
                        room.send_text(ret)

    def spawn(self):
        self.client.start_listener_thread()
        self.is_on = True
        print("Ready ...")
        while (self.is_on):
            time.sleep(0.5)

    def timer_callback(self, t):
        while (self.is_timer_on):
            if self.is_on:
                for service in self.services_sensitive_on_clock.copy():
                    service.clock_update()
                    service.admin(self)
                    ret = service.run_on_clock()
                    for room in self.services.copy()[service]:
                        if ret:
                            room.send_text(ret)
            time.sleep(t)

    def start_timer(self, t=1):
        if not (self.is_timer_on):
            self.is_timer_on = True
            t1 = threading.Thread(target=self.timer_callback, args=(t, ))
            t1.start()

    def stop_timer(self):
        self.is_timer_on = False

    def exit(self):
        self.is_timer_on = False
        self.is_on = False
        for room_key, room in self.rooms.items():
            for service in room[1].copy():
                print(service)
                tmp_msg = service.exit()
                if tmp_msg:
                    room[1].send_text(tmp_msg)
                # self.remove_service_from_room(room_key, service) ;
            # room_key.leave() ;
        sys.exit()

    def add_timer_to_service(self, service):
        if not (service in self.services):
            raise BaseException(
                "Service {} should belong to (at least) one room.".format(
                    service))
        if not (service in self.services_sensitive_on_clock):
            self.services_sensitive_on_clock.add(service)

    def remove_timer_from_service(self, service):
        if service in self.services_sensitive_on_clock:
            self.services_sensitive_on_clock.remove(service)
        else:
            raise BaseException(
                "Service {} is not clock sensitive.".format(service))