Beispiel #1
0
def test_presence_listener():
    client = MatrixClient("http://example.com")
    accumulator = []

    def dummy_callback(event):
        accumulator.append(event)

    presence_events = [
        {
            "content": {
                "avatar_url": "mxc://*****:*****@example:localhost"
            },
            "event_id": "$WLGTSEFSEF:localhost",
            "type": "m.presence"
        },
        {
            "content": {
                "avatar_url": "mxc://*****:*****@example2:localhost"
            },
            "event_id": "$CIGTXEFREF:localhost",
            "type": "m.presence"
        },
        {
            "content": {
                "avatar_url": "mxc://*****:*****@example3:localhost"
            },
            "event_id": "$ZEGASEDSEF:localhost",
            "type": "m.presence"
        },
    ]
    sync_response = deepcopy(response_examples.example_sync)
    sync_response["presence"]["events"] = presence_events
    response_body = json.dumps(sync_response)
    sync_url = HOSTNAME + MATRIX_V2_API_PATH + "/sync"

    responses.add(responses.GET, sync_url, body=response_body)
    callback_uid = client.add_presence_listener(dummy_callback)
    client._sync()
    assert accumulator == presence_events

    responses.add(responses.GET, sync_url, body=response_body)
    client.remove_presence_listener(callback_uid)
    accumulator = []
    client._sync()
    assert accumulator == []
Beispiel #2
0
class MatrixBackend(ErrBot):
    def __init__(self, config):
        super().__init__(config)
        identity = config.BOT_IDENTITY
        self.token = identity["token"]
        self.url = identity["url"]
        self.user = identity["user"]
        self._client = None

    def build_identifier(self, text_representation: str) -> None:
        """Return an object that idenfifies a matrix person or room."""
        pass

    @staticmethod
    def parse_identfier_pieces(regex: str, text_rep: str):
        m = re.match(regex, text_rep)
        if m:
            data, domain = m.group()
            return data, domain
        return None, None

    @staticmethod
    def parse_identfier(text_rep):
        """Parse matrix identifiers into usable types.
        Expected formats are as follows:
        !<room>:<domain>
        #<room>:<domain>
        @<user>:<domain>
        """

        room, domain, user = None, None, None

        room, domain = MatrixBackend.parse_identfier_pieces(
            r"[!#](.*):(.*)", text_rep)
        if not room or not domain:
            user, domain = MatrixBackend.parse_identfier_pieces(
                r"@:(.*):(.*)", text_rep)

        return room, domain, user

    def send_msg(self, room_id, msg):
        room = self._client.join_room(room_id)
        return room.send_text(msg)

    def send_file(self, room_id, file_path, filename):
        with open(file_path, "rb") as f:
            content = f.read()

        return self.send_stream_content(room_id, content, filename)

    def send_stream_content(self, room_id, content, filename):
        res = self._client.upload(content, 'application/octet-stream',
                                  filename)
        room = self._client.join_room(room_id)
        room.send_file(res, filename)
        return res

    def build_reply(self, msg, text=None, private=False, threaded=False):
        response = self.build_message(text)
        response.frm = self.bot_identifier
        self.send_msg(msg.extras['room_id'], text)
        if private:
            response.to = msg.frm
        else:
            response.to = msg.frm.room if isinstance(msg.frm,
                                                     RoomOccupant) else msg.frm
        return response

    def change_presence(self):
        pass

    def mode(self):
        pass

    def query_room(self):
        pass

    def rooms(self):
        pass

    def invite_callback(self, *args, **kwargs):
        print(args, kwargs)

    def ephemeral_callback(self, *args, **kwargs):
        print(args, kwargs)

    def leave_callback(self, *args, **kwargs):
        print(args, kwargs)

    def presence_callback(self, *args, **kwargs):
        print(args, kwargs)

    def callback(self, *events):
        for event in events:
            log.debug("Saw event %s.", event)
            if event["type"] == "m.room.message":
                content = event["content"]
                sender = event["sender"]
                if content["msgtype"] == "m.text":
                    msg = Message(content["body"],
                                  extras={'room_id': event["room_id"]})
                    msg.frm = MatrixPerson(self._client, sender)
                    msg.to = self.bot_identifier
                    self.callback_message(msg)

    def serve_once(self):
        self._client = MatrixClient(self.url,
                                    token=self.token,
                                    user_id=self.user)
        self._client.add_listener(self.callback)
        self._client.add_invite_listener(self.invite_callback)
        self._client.add_ephemeral_listener(self.ephemeral_callback)
        self._client.add_leave_listener(self.leave_callback)
        self._client.add_presence_listener(self.presence_callback)
        self.connect_callback()

        self.bot_identifier = MatrixPerson(self._client, self.user)

        self._client.listen_forever()
Beispiel #3
0
class Application(QApplication):
    loggedIn = Signal(str)

    messageReceived = Signal(object, str, object, float)

    roomSwitched = Signal(object)
    roomJoined = Signal(object)
    roomUpdated = Signal(str, str, str)
    roomLeft = Signal(object)
    roomInvited = Signal(object)

    def __init__(self, *args, **kwargs):
        super(Application, self).__init__(*args, **kwargs)

        # setup the application name and icon
        self.setApplicationName('Qui')
        self.iconPath = os.path.dirname(__file__)
        self.iconPath = os.path.join(self.iconPath, 'icons/icon.png')
        self.setWindowIcon(QIcon(self.iconPath))

        # setup the tray icon
        self.showNotifications = False
        self.tray = QSystemTrayIcon(QIcon(self.iconPath))
        self.tray.show()
        self.tray.activated.connect(self.showWindow)

        # setup the tray icon menu
        self.menu = QMenu()
        self.menu.addAction('Quit').triggered.connect(self.quit)
        self.tray.setContextMenu(self.menu)

        # setup signals
        self.messageReceived.connect(self.receiveMessage)

        # show the window
        self.window = None
        self.showWindow(None)

        # try loading the login info
        self.client = None
        self.settings = QSettings('Qui', 'Qui')
        self.url = self.settings.value("url")
        self.token = self.settings.value("token")
        self.user = self.settings.value("user")
        invalid = self.url is None or self.url == "" or self.token is None or self.token == "" or self.user is None or self.user == ""
        if not invalid:
            try:
                self.client = MatrixClient(base_url=self.url,
                                           token=self.token,
                                           user_id=self.user)
                self.postLogin()
            except:
                invalid = True
        # show the login form if we can't login
        if invalid:
            self.loginForm = LoginForm()
            self.loginForm.loggedIn.connect(self.login)
            self.loginForm.show()

    def showWindow(self, reason):
        if self.window is None:
            # make a new window if we don't have one
            self.window = MainWindow()
            # setup signals
            self.loggedIn.connect(self.window.login)
            self.messageReceived.connect(self.window.receiveMessage)
            self.roomLeft.connect(self.window.roomLeft)
            self.roomJoined.connect(self.window.roomJoined)
            self.roomUpdated.connect(self.window.roomUpdated)
            self.window.createRoom.connect(self.createRoom)
            self.window.leaveRoom.connect(self.leaveRoom)
            self.window.joinRoom.connect(self.joinRoom)
            # show it
            self.window.show()
        else:
            # show it if it's minimized or something
            self.window.showNormal()

    def quit(self):
        sys.exit(0)

    def login(self, client, url):
        self.client = client
        self.settings.setValue('url', url)
        self.url = url
        self.settings.setValue('token', client.token)
        self.token = client.token
        self.settings.setValue('user', client.user_id)
        self.user = client.user_id
        self.postLogin()

    def postLogin(self):
        self.loggedIn.emit(self.user)
        #self.messages.userId = self.user
        self.client.add_listener(self.eventCallback)
        self.client.add_presence_listener(self.presenceCallback)
        self.client.add_invite_listener(self.inviteCallback)
        self.client.add_leave_listener(self.leaveCallback)
        self.client.start_listener_thread()
        for room, obj in self.client.get_rooms().items():
            self.roomJoined.emit(obj)
            for event in obj.events:
                self.eventCallback(event)
        self.showNotifications = True

    def eventCallback(self, event):
        if 'type' in event and 'room_id' in event and 'content' in event and event[
                'type'] == 'm.room.message':
            room = Room(self.client, event['room_id'])
            self.messageReceived.emit(room, event['sender'], event['content'],
                                      time.time() - event['unsigned']['age'])
        if 'type' in event and 'room_id' in event and 'content' in event and event[
                'type'] == 'm.room.canonical_alias':
            self.roomUpdated.emit(event['room_id'], 'canonical_alias',
                                  event['content']['alias'])

    def presenceCallback(self, event):
        return
        print('presence: {}'.format(event))

    def inviteCallback(self, roomId, state):
        return
        print('invite: {} {}'.format(roomId, state))

    def leaveCallback(self, roomId, room):
        return
        print('leave: {} {}'.format(roomId, room))

    def receiveMessage(self, room, sender, content, timestamp):
        if self.showNotifications:
            if self.window is None or not self.window.isActiveWindow():
                self.tray.showMessage(sender, content['body'])

    def leaveRoom(self, room):
        self.client.api.leave_room(room.room_id)
        self.roomLeft.emit(room)

    def joinRoom(self, roomId):
        room = self.client.join_room(roomId)
        self.roomJoined.emit(room)

    def createRoom(self, roomId):
        room = self.client.create_room(roomId)
        self.roomJoined.emit(room)