def sendFunc(msgStr):
    # try to send a message (msgStr) via matrix protocol
    try:
        # try to read the updated credentials from a file received using previous function
        try:
            with open('updts.txt') as updts:
                updates = updts.read()
            decryptedDic = dcryptFunc(updates)
            martixServer = decryptedDic['martixServer']
            username = decryptedDic['username']
            password = decryptedDic['password']
            roomAddr = decryptedDic['roomAddr']
            client = MatrixClient(martixServer)
            token = client.login(username=username, password=password)
            room = client.join_room(roomAddr)
            room.send_text(msgStr)
            client.logoout()
        # if reading from file failed, probably due to file not being available,
        # connect to matrix server using hardcoded credentials
        except:
            client = MatrixClient("https://matrix.org")
            token = client.login(username="******",
                                 password="******")
            room = client.join_room(
                "Your_matrix_room_id")  # find it in room's advanced settings
            room.send_text(msgStr)
            client.logoout()
    # if matrix network was not available, like the time it got hacked on April, 2019(!)
    # send the message via Dropbox
    except:
        dropIt(msgStr)
Ejemplo n.º 2
0
class Bot:
    def __init__(self, homeserver, userID, password, ownerID,
                 dialogflow_project):
        self.ownerID = ownerID
        self.userID = userID
        self.client = MatrixClient(homeserver)

        token = self.client.login(username=userID, password=password)

        self.project = dialogflow_project
        rooms = self.client.get_rooms()
        for name, room in self.client.get_rooms().items():
            room.add_listener(self.onEvent)

    def report_mainloop_error(self):
        pass

    def run(self):
        self.client.add_invite_listener(self.accept_invite)
        while True:
            try:
                self.client.listen_forever()
            except KeyboardInterrupt:
                raise
            except:
                self.report_mainloop_error()

    def accept_invite(self, room_id, state):
        self.client.join_room(room_id)
        session_client = dialogflow.SessionsClient()
        session = session_client.session_path(self.project, room_id)
        query_input = dialogflow.types.QueryInput(
            event=dialogflow.types.EventInput(name='WELCOME',
                                              language_code='en'))

    def onEvent(self, room, event):
        if event['sender'] != self.userID:
            print("New event in room {} : {}".format(room, event))
            if event['type'] == "m.room.message" and event['content'][
                    'msgtype'] == "m.text":
                if event['sender'] == self.ownerID:  # admin commands
                    leaveCommand = re.match("!leave (.+)",
                                            event['content']['body'])
                    if leaveCommand:
                        self.client.get_rooms()[leaveCommand.group(1)].leave()
                response = detect_intent(self.project, room.room_id,
                                         event['content']['body'], 'en')
                print("Got DialogFlow response: {}".format(response))
                for message in response:
                    for text in message.text.text:
                        room.send_text("{}".format(text))
Ejemplo n.º 3
0
class ZmalauBot():
    def __init__(self, username, password, roomname):
        # connect to room
        self.crypto = CryptoEngine()
        self.air_pollution = AirPollutionEngine()
        self.client = MatrixClient("http://matrix.org")
        self.token = self.client.login_with_password(username=username,
                                                     password=password)
        self.room = self.client.join_room(roomname)

        # add bot reactions
        self.room.add_listener(self.on_message)
        self.client.start_listener_thread()

        self.room.send_text('Dzień dobry')

    def default_response(self, message):
        return self.crypto.analyze_message_and_prepare_response(message)

    def on_message(self, room, event):
        if event['type'] == "m.room.message":
            if USERNAME in event['sender']:
                return
            if event['content']['msgtype'] == "m.text":
                message = event['content']['body']
                m = message.lower()
                if 'zmalau' in m or 'urus' in m:
                    if any([word in m for word in self.crypto.trigger_words]):
                        response = self.crypto.analyze_message_and_prepare_response(m)
                    elif any([word in m for word in self.air_pollution.trigger_words]):
                        response = self.air_pollution.analyze_message_and_prepare_response(m)
                    else:
                        response = self.default_response(m)
                    self.room.send_text(response)
Ejemplo n.º 4
0
def main(host, username, password, room_id_alias):
    client = MatrixClient(host)
    try:
        client.login_with_password(username, password)
    except MatrixRequestError as e:
        print(e)
        if e.code == 403:
            print ""
        else:
            print ""
    except MissingSchema as e:
        print(e)
    try:
        room = client.join_room(room_id_alias)
    except MatrixRequestError as e:
        print(e)
        if e.code == 400:
            print ""
        else:
            print ""
            
    room.add_listener(on_message)
    client.start_listener_thread()

    while True:
        
        time.sleep(5)
Ejemplo n.º 5
0
class Logger:
    address: str
    port: int
    token: str
    room: dict

    def __init__(self, *args, **kwargs):
        self.address, self.port = args[0]
        _room_name = args[1]
        _room = LOGGER[_room_name]
        if 'username' not in kwargs:
            kwargs.update({'username': _room["user"]})
        if 'password' not in kwargs:
            kwargs.update({'password': _room["password"]})
        try:
            # TODO: Make also dynamic
            self._client = MatrixClient(f"http://localhost:8008")
            self.token = self._client.login(**kwargs)
            self.room = self._client.join_room(_room_name)
        except MatrixHttpLibError as matrix_error:
            logging.error(matrix_error)

    def log(self, message):
        # TODO: Allow reconnection with room name as param
        if not self.token:
            logging.error(
                f"MatrixClient was not properly intialized. No log can be done"
            )
            return
        logging.info(f"Sending {message} to {self.room}")
        self.room.send_text(message)
Ejemplo n.º 6
0
def send_msg(server_name, username, password, room_id, msg):
    client = MatrixClient(server_name)
    client.login(username=username, password=password)
    room = client.join_room(room_id)

    room.send_text(msg)
    client.logout()
Ejemplo n.º 7
0
def main(host, username, password):
    client = MatrixClient(host)
    rooms = client.get_rooms()

    try:
        db = sqlite3.connect('db')
        cursor = db.cursor()
        cursor.execute(
            '''CREATE TABLE IF NOT EXISTS messages(id INTEGER PRIMARY KEY, date TEXT, roomid TEXT, sender TEXT, message TEXT)'''
        )
        db.commit()
    except Exception as e:
        db.rollback()
        raise e
    finally:
        db.close()

    def on_invite(room_id, state):
        print("joining room " + room_id)
        room = client.join_room(room_id)
        room.add_listener(on_message)

    try:
        token = client.login_with_password(username, password)
        global matrix
        matrix = MatrixHttpApi(host, token)
    except MatrixRequestError as e:
        print(e)
        if e.code == 403:
            print("Bad username or password.")
            sys.exit(4)
        else:
            print("Check if server details are correct.")
            sys.exit(2)
    except MissingSchema as e:
        print("Bad URL format.")
        print(e)
        sys.exit(3)

    for room in rooms:
        try:
            roomname = matrix.get_room_name(room)
            print("Already in room " + roomname['name'])
            room_to_listen = client.join_room(room)
            room_to_listen.add_listener(on_message)
        except MatrixRequestError as e:
            print(e)
            if e.code == 400:
                print("Room ID/Alias in the wrong format")
                sys.exit(11)
            else:
                print("Couldn't find room.")
                sys.exit(12)

    client.add_invite_listener(on_invite)
    client.start_listener_thread()

    while True:
        time.sleep(30)
Ejemplo n.º 8
0
def setup(config):
    """Sets up the Matrix client. Makes sure the (specified) room is joined.
    """
    client = MatrixClient("https://{0}:{1}".format(config['homeserver'],
                                                   int(config['port'])))
    client.login_with_password(username=config['username'],
                               password=config['password'])
    room = client.join_room('{0}:{1}'.format(config['room'], config['domain']))
    return client, room
Ejemplo n.º 9
0
def main():
    global g_client
    print("Connecting to server: {}".format(botconfig.client_url))
    g_client = MatrixClient(botconfig.client_url)

    password = get_password()

    try:
        print("Logging in with username: {}".format(botconfig.username))
        g_client.login_with_password(botconfig.username, password)
    except MatrixRequestError as e:
        print(e)
        if e.code == 403:
            print("Bad username or password.")
            sys.exit(4)
        else:
            print("Check your sever details are correct.")
            sys.exit(2)
    except MissingSchema as e:
        print("Bad URL format.")
        print(e)
        sys.exit(3)

    # room dictionary that will be passed to the listener manager
    rooms = {}

    for room_address in botconfig.rooms:
        try:
            room = g_client.join_room(room_address)
            room.add_listener(on_message)
            rooms[room_address] = room
            print("Joined room: {}".format(room_address))
        except MatrixRequestError as e:
            print(e)
            if e.code == 400:
                print("{}: Room ID/Alias in the wrong format".format(
                    room_address))
                sys.exit(11)
            else:
                print("Couldn't find room: {}".format(room_address))
                sys.exit(12)

    g_client.add_invite_listener(on_invite)

    g_client.start_listener_thread()

    listener = ListenerManager(rooms, botconfig.listener_port)

    listener.start_listener_thread()

    try:
        while True:
            pass
    except KeyboardInterrupt:
        print("Shutting down.")
Ejemplo n.º 10
0
 def __init__(self):
     print("Initializing client...")
     client = MatrixClient("https://matrix.org")
     print("Loggin in...")
     token = client.login(credentials["login"], credentials["password"])
     print("Reinitializing client")
     self.client = MatrixClient("https://matrix.org",
                                token=token,
                                user_id="@isbur:matrix.org")
     print("Entering the room...")
     self.room = client.join_room("!BeLEKkRmKBJzNOdqxB:matrix.org")
Ejemplo n.º 11
0
def process_jenkins_request():
    check_token('X-Jenkins-Token')
    msgtype = get_msg_type()
    room = get_a_room()
    jenkins_event = request.headers.get("X-Jenkins-Event")

    if jenkins_event == "Post Build Hook":
        try:
            client = MatrixClient(cfg["matrix"]["server"])
            client.login(username=cfg["matrix"]["username"],
                         password=cfg["matrix"]["password"])

            room = client.join_room(room_id_or_alias=room)
        except MatrixRequestError as e:
            return matrix_error(e)

        def extract_change_message(change):
            change_message = next(iter_first_line(change["message"]), "")
            if len(change_message) > 0:
                htimestamp = datetime.fromtimestamp(
                    change['timestamp'] / 1000).strftime("%d. %b %y %H:%M")
                return f"{shorten(change_message)} " \
                    f"({shorten(change['commitId'], 7, appendix='')}) " \
                    f"by {change['author']} " \
                    f"at {htimestamp}"
            else:
                return shorten(json.dumps(change), appendix="...}")

        build_name = request.json["displayName"]
        project_name = request.json["project"]["fullDisplayName"]
        result_type = request.json["result"]["type"]
        result_color = request.json["result"]["color"]
        change_messages = list(
            map(extract_change_message, request.json["changes"]))
        html_changes = "\n".join(
            (f"  <li>{msg}</li>" for msg in change_messages))
        text_changes = "\n".join((f"- {msg}" for msg in change_messages))
        try:
            room.send_html(
                f"<p><strong>Build {build_name} on project {project_name} complete: "
                f"<font color=\"{result_color}\">{result_type}</font></strong>, "
                f"{len(change_messages)} commits</p>\n"
                "" + (f"<ul>\n{html_changes}\n</ul>\n"
                      if len(change_messages) > 0 else ""),
                body=
                f"**Build {build_name} on project {project_name} complete: {result_type}**, "
                f"{len(change_messages)} commits\n"
                "" + (f"{text_changes}\n" if len(change_messages) > 0 else ""),
                msgtype=msgtype)
        except MatrixRequestError as e:
            return matrix_error(e)

    # see Flask.make_response, this is interpreted as (body, status)
    return "", 204
Ejemplo n.º 12
0
    def __init__(self, server, username, password, rooms, nick=None):
        client = MatrixClient(server)
        self.viewer_url = server.strip('/') + "/_matrix/media/v1/download/"

        try:
            client.login_with_password(username, password)
        except MatrixRequestError as e:
            if e.code == 403:
                logger.error("403 Bad username or password.")
                sys.exit(4)
            else:
                logger.error("{} Check your server details are correct.".format(e))
                sys.exit(2)
        except MissingSchema as e:
            logger.error("{} Bad URL format.".format(e))
            sys.exit(3)

        self.username = client.user_id
        logger.info("logged in as: {}".format(self.username))

        if nick is not None:
            u = client.get_user(client.user_id)
            logger.info("Setting display name to {}".format(nick))
            try:
                u.set_display_name(nick)
            except MatrixRequestError as e:
                logger.error("Fail to set display name: error = {}".format(e))

        self.joined_rooms = {}
        self.room_id_to_alias = {}
        self.displaynames = {}

        for room_id_alias in rooms:
            try:
                room = client.join_room(room_id_alias)
            except MatrixRequestError as e:
                if e.code == 400:
                    logger.error("400 Room ID/Alias in the wrong format")
                    sys.exit(11)
                else:
                    logger.error("{} Couldn't find room {}".format(e, room_id_alias))
                    sys.exit(12)
            logger.info("Joined room {}".format(room_id_alias))
            self.joined_rooms[room_id_alias] = room
            self.room_id_to_alias[room.room_id] = room_id_alias
            room.add_listener(self.on_message)

        self.client = client
        self.bot_msg_pattern = config['matrix'].get('bot_msg_pattern', None)
Ejemplo n.º 13
0
def main():
    # connect to server and join room
    client = MatrixClient("https://matrix.org")
    token = client.login(username="******", password=os.environ['KLO_PW'])
    room = client.join_room("#klotest:matrix.org")

    # create FeatureHandler
    fh = FeatureHandler(room, client)
    # add features to FeatureHandler that are called when the specified command is posted in the Matrix room
    fh.add_feature("!echo", FeatureExamples.echo)
    fh.add_feature("!room", find_room)

    # run script until it's stopped manually
    while True:
        pass
Ejemplo n.º 14
0
def process_gitlab_request():
    check_token('X-Gitlab-Token')
    msgtype = get_msg_type()
    room = get_a_room()
    gitlab_event = request.headers.get("X-Gitlab-Event")

    if gitlab_event == "Push Hook":
        try:
            client = MatrixClient(cfg["matrix"]["server"])
            client.login(username=cfg["matrix"]["username"],
                         password=cfg["matrix"]["password"])

            room = client.join_room(room_id_or_alias=room)
        except MatrixRequestError as e:
            return matrix_error(e)

        def sort_commits_by_time(commits):
            return sorted(commits, key=lambda commit: commit["timestamp"])

        def extract_commit_info(commit):
            msg = shorten(
                next(iter_first_line(commit["message"]),
                     "$EMPTY_COMMIT_MESSAGE - impossibruh"))
            url = commit["url"]
            return msg, url

        username = request.json["user_name"]
        commit_messages = list(
            map(extract_commit_message,
                sort_commits_by_time(request.json["commits"])))
        project_name = request.json["project"]["name"]
        html_commits = "\n".join((f'  <li><a href="{url}">{msg}</a></li>'
                                  for (msg, url) in commit_messages))
        text_commits = "\n".join(
            (f"- [{msg}]({url})" for (msg, url) in commit_messages))
        try:
            room.send_html(
                f"<strong>{username} pushed {len(commit_messages)} commits to {project_name}</strong><br>\n"
                f"<ul>\n{html_commits}\n</ul>\n",
                body=
                f"{username} pushed {len(commit_messages)} commits to {project_name}\n{text_commits}\n",
                msgtype=msgtype)
        except MatrixRequestError as e:
            return matrix_error(e)

    # see Flask.make_response, this is interpreted as (body, status)
    return "", 204
Ejemplo n.º 15
0
class Bot:
    def __init__(self, hs_url, username, password):
        self.cli = MatrixClient(hs_url)
        self.cli.login_with_password(username=username, password=password)
        self.shelf = shelve.open(data_file, writeback=True)
        signal.signal(signal.SIGTERM, self.close_shelf)
        signal.signal(signal.SIGINT, self.close_shelf)
        self.cli.add_invite_listener(self.on_invite)
        self.joined_rooms = self.cli.get_rooms()
        logger.info(
            f'Joined to {[r.display_name for r in self.joined_rooms.values()]}'
        )
        self.add_room_listeners()

    def run(self):
        self.cli.listen_forever(exception_handler=self.sync_exception_handler)
        logger.info('Bot started.')

    def add_room_listeners(self):
        for room in self.joined_rooms.values():
            self.add_local_bot(room)

    def on_invite(self, room_id, state):
        room = self.cli.join_room(room_id)
        # Force a sync in order not to process previous room messages
        self.cli._sync()
        self.add_local_bot(room)
        self.joined_rooms[room_id] = room
        room.send_notice(
            f'Hi! I\'m a list keeping bot. Send {LocalBot.prefix}help'
            ' to learn how to use me.')
        logger.info(
            f'Received an invite for room {room.display_name}, and joined.')

    def add_local_bot(self, room):
        lbot = LocalBot(room, self.cli.api, self.shelf)
        room.add_listener(lbot.on_message, event_type='m.room.message')

    def close_shelf(self, *args):
        logger.info('Closing shelf...')
        self.shelf.close()
        logger.info('Shelf is closed.')
        sys.exit()

    @staticmethod
    def sync_exception_handler(exception):
        logger.warning(exception)
Ejemplo n.º 16
0
    def run(self):
        client = MatrixClient(self._mconf.host)

        try:
            log.debug('Logging into Matrix')
            client.login_with_password(self._mconf.username,
                                       self._mconf.password)
        except MatrixRequestError as e:
            if e.code == 403:
                log.error('Bad username or password: {}'.format(str(e)))
                sys.exit(2)
            else:
                log.error(
                    'Could not log in - check the server details are correct: {}'
                    .format(str(e)))
                sys.exit(2)
        except Exception as e:
            log.error('Error while logging in: {}'.format(str(e)))
            sys.exit(2)

        log.debug('Joining rooms')
        self._rooms = []
        for room_id in self._mconf.rooms:
            try:
                room = client.join_room(room_id)
            except MatrixRequestError as e:
                if e.code == 400:
                    log.error(
                        'Room ID/Alias ("{}") in the wrong format. Can not join room: {}'
                        .format(room_id, str(e)))
                    sys.exit(2)
                else:
                    log.error('Could not find room "{}"'.format(room_id))
                    sys.exit(2)

            room.add_listener(self._on_room_message)
            self._rooms.append(room)

        log.info('Logged into Matrix, ready to publish information')
        client.start_listener_thread()

        while True:
            topic, msg_b = self._lhsub_socket.recv_multipart()
            # TODO: Validate signature here!
            event = json.loads(str(msg_b, 'utf-8'))
            self._on_event_received(event)
Ejemplo n.º 17
0
class Matrix:
    def __init__(self, credentials, rooms, send_to, transport):
        self.credentials = credentials
        self.rooms = rooms
        self.send_to = send_to
        self.transport = transport
        self.connect()

    def connect(self):
        self.client = MatrixClient(self.credentials.host,
                                   token=self.credentials.token,
                                   user_id=self.credentials.userid)

        # Listen for events in all configured rooms
        for room in self.rooms:
            joined_room = self.client.join_room(room)
            joined_room.add_listener(self.listener)

        self.client.start_listener_thread()
        self.print_rooms()
        self.runner()

    def print_rooms(self):
        rooms = self.client.get_rooms()
        for room_id, room in rooms.items():
            print("Matrix: {} ({})".format(room_id, room.display_name))

    def runner(self):
        worker_thread = threading.Timer(1.0, self.runner)
        worker_thread.daemon = True
        worker_thread.start()

        if not self.transport.to_matrix.empty():
            message = self.transport.to_matrix.get()
            self.client.api.send_message(message.destination,
                                         message.get_message())

    def listener(self, room, message):
        if self.send_to.get(room.room_id):
            if message.get('content', {}).get('msgtype') == 'm.text':
                if self.credentials.userid != message['sender']:
                    message = Message(self.send_to[room.room_id],
                                      message['sender'],
                                      message['content']['body'])
                    self.transport.send_hangouts(message)
Ejemplo n.º 18
0
def setup(config):
    """Sets up the Matrix client. Makes sure the (specified) room is joined.
    """
    loginargs = {}
    if 'token' in config:
        loginargs['user_id'] = '@{0}:{1}'.format(config['username'],
                                                 config['domain'])
        loginargs['token'] = config['token']

    client = MatrixClient(
        "https://{0}:{1}".format(config['homeserver'], int(config['port'])),
        **loginargs)
    if 'token' not in config:
        client.login_with_password(username=config['username'],
                                   password=config['password'])

    room = client.join_room('{0}:{1}'.format(config['room'], config['domain']))
    return client, room
Ejemplo n.º 19
0
class MatrixSendServer:
    def __init__(self, config, room):
        self.queue_path = config['queue_path']
        self.client = MatrixClient(config['homeserver_uri'])
        self.token = self.client.login_with_password(username=config['username'],
                                                     password=config['password'])
        self.room = self.client.join_room(room)
        self.room_id = room
        self.message_queue = []
        self.limited_until = None

    def dequeue(self):
        """Dequeue as many messages as the server lets us"""
        for f in self.message_queue:
            with open(f, "r", encoding="UTF-8") as fin:
                message = fin.read()

            if self.limited_until is not None and time.time() * 1000 < self.limited_until:
                return

            try:
                self.room.send_text(message)
                self.message_queue.pop(0)
            except Exception as e:
                necessary_delay = json.loads(e.content)['retry_after_ms']
                sys.stderr.write("Sleeping for %s seconds... Queue depth %s\n" % (necessary_delay, len(self.message_queue)))
                sys.stderr.flush()
                self.limited_until = time.time() * 1000 + necessary_delay
            else:
                os.remove(f)

    def enqueue(self, f):
        if os.path.isfile(f) and not f in self.message_queue:
            self.message_queue.append(f)

    def run(self):
        print("run!")
        while True:
            for f in os.listdir(self.queue_path):
                f = os.path.join(self.queue_path, f)
                self.enqueue(f)
            self.dequeue()
            time.sleep(10)
Ejemplo n.º 20
0
def run_module():
    module_args = dict(
        msg_plain=dict(type='str', required=True),
        msg_html=dict(type='str', required=True),
        room_id=dict(type='str', required=True),
        hs_url=dict(type='str', required=True),
        token=dict(type='str', required=False, no_log=True),
        user_id=dict(type='str', required=False),
        password=dict(type='str', required=False, no_log=True),
    )

    result = dict(changed=False, message='')

    module = AnsibleModule(argument_spec=module_args,
                           mutually_exclusive=[['password', 'token']],
                           required_one_of=[['password', 'token']],
                           required_together=[['user_id', 'password']],
                           supports_check_mode=True)

    if not matrix_found:
        module.fail_json(
            msg=
            "Python 'matrix-client' module is required. Install via: $ pip install matrix-client"
        )

    if module.check_mode:
        return result

    # create a client object
    client = MatrixClient(module.params['hs_url'])
    if module.params['token'] is not None:
        client.api.token = module.params['token']
    else:
        client.login(module.params['user_id'],
                     module.params['password'],
                     sync=False)

    # make sure we are in a given room and return a room object for it
    room = client.join_room(module.params['room_id'])
    # send an html formatted messages
    room.send_html(module.params['msg_html'], module.params['msg_plain'])

    module.exit_json(**result)
Ejemplo n.º 21
0
class MCat:
    def __init__(self, config):
        self.client = MatrixClient(config['server'])
        self.token = self.client.login_with_password(username=config['user'],
                                                     password=config['password'])
        self.room = self.client.join_room(config['room'])
        self.room_id = config['room']
        self.message_queue = []
        self.limited_until = None

    def dequeue(self):
        """Dequeue as many messages as the server lets us"""
        for message in self.message_queue:
            if time.time() * 1000 < self.limited_until:
                return

            try:
                self.room.send_html(message)
                self.message_queue.pop(0)
            except Exception as e:
                necessary_delay = json.loads(e.content)['retry_after_ms']
                sys.stderr.write("Sleeping for %s seconds... Queue depth %s\n" % (necessary_delay, len(self.message_queue)))
                sys.stderr.flush()
                self.limited_until = time.time() * 1000 + necessary_delay

    def enqueue(self, message):
        self.message_queue.append(message)

    def f_to_matrix(self, f):
        for line in f:
            self.enqueue(line)
            self.dequeue()
        while len(self.message_queue) > 0:
            self.dequeue()

    def matrix_to_f(self, f):
        def stdout_cb(chunk):
            if chunk[u'type'] != u"m.presence" and chunk[u'room_id'] == self.room_id:
                f.write(json.dumps(chunk))
                f.write('\n')
                f.flush()
        self.client.add_listener(stdout_cb)
        self.client.listen_forever()
Ejemplo n.º 22
0
class MatrixProtocol(Protocol):
    """
    A Matrix Protocol wrapper.
    """

    def __init__(self, username, password, room, server):
        super().__init__(username, password, room, server)
        self.username = username
        # Connect to Matrix
        self.client = MatrixClient(server)
        self.token = self.client.login_with_password(username=username,
                                                     password=password)

        self.room = self.client.join_room(room)
        self.room.add_listener(self.process_event)

    def listen_forever(self):
        self.room.send_text('My name is PyAstroBot! I seek the grail!')
        try:
            self.client.listen_forever()
        except KeyboardInterrupt:
            pass
        finally:
            self.room.send_text("PyAstroBot is sneaking away and buggering off...")

    def send_message(self, message):
        self.room.send_text(message)

    def send_emote(self, message):
        self.room.send_emote(message)

    def _is_message(self, event):
        if event['type'] == "m.room.message":
            if event['content']['msgtype'] == "m.text":
                # Ignore everything the bot says.
                if event['sender'] != self.username:
                    return event

    def process_event(self, room, event):
        if self._is_message(event):
            for call in self.event_callbacks:
                call(event['content']['body'], event['sender'])
def main():
    client = MatrixClient(os.environ.get('BASE_URL'),
                          token=os.environ.get('TOKEN'),
                          user_id=os.environ.get('USER_ID'))

    # try:
    #     client.login_with_password(username, password)
    # except MatrixRequestError as e:
    #     print(e)
    #     if e.code == 403:
    #         print("Bad username or password.")
    #         sys.exit(4)
    #     else:
    #         print("Check your sever details are correct.")
    #         sys.exit(2)
    # except MissingSchema as e:
    #     print("Bad URL format.")
    #     print(e)
    #     sys.exit(3)

    try:
        room = client.join_room(os.environ.get('ROOM_ID'))
    except MatrixRequestError as e:
        print(e)
        if e.code == 400:
            print("Room ID/Alias in the wrong format")
            sys.exit(11)
        else:
            print("Couldn't find room.")
            sys.exit(12)

    room.add_listener(on_message)
    print("Starting listener thread, bot ready")
    client.start_listener_thread()

    while True:
        msg = samples_common.get_input()
        if msg == "/quit":
            break
        else:
            room.send_text(msg)
Ejemplo n.º 24
0
class MatrixBot:
    def __init__(self, bot_config):
        from matrix_client.client import MatrixClient

        self.bot = MatrixClient(
            bot_config["server"],
            user_id=bot_config["user_id"],
            token=bot_config["token"],
        )

    def get_link(self, channel):
        room = self.bot.join_room(channel)

        async def link(request: Request):
            if request.method == "GET":
                return response.text(
                    "this is just an endpoint for the alertmanager")
            room.send_html(format_alert(request.body, html=True))
            return response.json({"status": "ok"})

        return link
Ejemplo n.º 25
0
def notify(title,
           message,
           url,
           roomId,
           userId=None,
           token=None,
           password=None,
           retcode=None):

    client = MatrixClient(url)
    if password is not None:
        if userId is None:
            raise Exception("Must supply 'userid' when using 'password'")
        client.login(userId, password, sync=False)
    elif token is not None:
        client.api.token = token
    else:
        raise Exception("Must supply 'token' or 'password'")
    msg_plain = "**{}** {}".format(title, message)
    msg_html = "<b>{}</b> {}".format(title, message)
    room = client.join_room(roomId)
    room.send_html(msg_html, msg_plain)
Ejemplo n.º 26
0
def main(host, username, password, room_id_alias):
    client = MatrixClient(host)

    try:
        client.login_with_password(username, password)
    except MatrixRequestError as e:
        print(e)
        if e.code == 403:
            print("Bad username or password.")
            sys.exit(4)
        else:
            print("Check your sever details are correct.")
            sys.exit(2)
    except MissingSchema as e:
        print("Bad URL format.")
        print(e)
        sys.exit(3)

    try:
        room = client.join_room(room_id_alias)
    except MatrixRequestError as e:
        print(e)
        if e.code == 400:
            print("Room ID/Alias in the wrong format")
            sys.exit(11)
        else:
            print("Couldn't find room.")
            sys.exit(12)

    room.add_listener(on_message)
    client.start_listener_thread()

    while True:
        msg = samples_common.get_input()
        if msg == "/quit":
            break
        else:
            room.send_text(msg)
Ejemplo n.º 27
0
class Connector:
    """A matrix connector for the Chattie bot framework."""
    def __init__(self, parser):
        """Connect to the matrix room."""
        self.parser = parser
        self.client = MatrixClient(MATRIX_URL)
        # Try to register if it fails try to log in.
        try:
            self.token = self.client.\
                         register_with_password(username=MATRIX_USERNAME,
                                                password=MATRIX_PASSWORD)
        except MatrixRequestError:
            self.token = self.client.\
                         login_with_password(username=MATRIX_USERNAME,
                                             password=MATRIX_PASSWORD)
        self.rooms = {}
        for room in MATRIX_ROOMS.split(","):
            room_name = room
            if not room.startswith("#"):
                room_name = "!" + room
            r = self.client.join_room(room_name)
            r.add_listener(self.parse_event)
            self.rooms[r.room_id] = r

    def listen(self):
        """Listen for messages on Matrix."""
        self.client.listen_forever()

    def send_message(self, room_id, msg):
        """Send a message to Matrix."""
        self.rooms[room_id].send_text(msg)

    def parse_event(self, room, incoming_event):
        """Transform Matrix incoming_event to text."""
        if incoming_event['type'] != 'm.room.message':
            return
        self.parser(incoming_event['room_id'],
                    incoming_event['content']['body'])
Ejemplo n.º 28
0
class Connector(connectors.Connector):
    """A matrix connector for the Chattie bot framework."""

    def __init__(self, bot):
        """Connect to the matrix room."""
        self.bot = bot

        self.client = MatrixClient(MATRIX_URL)
        # Try to register if it fails try to log in.
        try:
            self.token = self.client.\
                         register_with_password(username=MATRIX_USERNAME,
                                                password=MATRIX_PASSWORD)
        except MatrixRequestError:
            self.token = self.client.\
                         login_with_password(username=MATRIX_USERNAME,
                                             password=MATRIX_PASSWORD)
        for room in MATRIX_ROOMS.split(","):
            room_name = room
            if not room.startswith("#"):
                room_name = "!" + room
            r = self.client.join_room(room_name)
            r.add_listener(self.parse_event)

    def listen(self):
        """Listen for messages on Matrix."""
        self.client.listen_forever()

    def parse_event(self, room, event):
        """Transform Matrix incoming_event to text."""
        if event['type'] != 'm.room.message':
            return

        resp = self.bot.parse_message(event['content']['body'])

        for r in resp:
            room.send_text(r)
Ejemplo n.º 29
0
class MatrixHandler():
    def __init__(self, username, password, room, gotMsgCallback=blackhole):
        try:
            from matrix_client.client import MatrixClient
        except ImportError:
            print("ERR:matrix_client import fail: Please exec:")
            print("cd ./matrix-python-sdk")
            print("pip install ./")
            raise RuntimeError("Failed to import matrix_client sdk")
        self.matrix = MatrixClient("https://matrix.org")
        self.matrix.login_with_password(username=username, password=password)
        self.matrix.start_listener_thread()
        self.room = self.matrix.join_room(room)
        self.room.send_text("Hello!")
        self.room.add_listener(gotMsgCallback)
        #self.gotMsgCallback=gotMsgCallback
    def sendMsg(self, msgData):
        res = self.room.send_text(msgData)
        return res

    def sendImg(self, imgdir, content_type="image/jpeg"):
        with open(imgdir, mode="rb") as f:
            uri = self.matrix.upload(f.read(), content_type)
            self.room.send_image(uri, 'wximg')
            f.close()

    def sendAudio(self, fdir, content_type="audio/mp3"):
        with open(fdir, mode="rb") as f:
            uri = self.matrix.upload(f.read(), content_type)
            self.room.send_audio(uri, 'wxaudio')
            f.close()

    def sendHtml(self, htmlData):
        res = self.room.send_html(htmlData)
        return res

    '''
Ejemplo n.º 30
0
class Client():
    def __init__(self):
        self.client = None
        self.room = None

    def authenticate(self, username, password, host):
        self.client = MatrixClient(host)
        try:
            self.client.login_with_password(username, password)
        except MatrixRequestError as e:
            if e.code == 403:
                print("Bad username or password.")
            else:
                print("Check your sever details are correct.")
                return False
        except MissingSchema as e:
            print("Bad URL format.")
            print(e)
            return False

    def get_contacts(self):
        return self.client.get_rooms()

    def get_messages(self, contact):
        pass

    def start_conversation(self, room_id):
        self.room = self.client.join_room(room_id)
        self.room.add_listener(event_listener)
        self.client.start_listener_thread()

    def send_message(self, message):
        self.room.send_text(message)

    def event_listener(self, room, event):
        global app
        app.send_signal("matrix", {"contact": room, "event": event})
Ejemplo n.º 31
0
class CmdListener:
    rooms = {}
    mpc = None
    client = None
    stream_url = ""
    cmd_queue = None
    music_dir = None
    def __init__(self,config):
        self.mpc = MPCClient(config["mpc"]["host"],config["mpc"]["port"])
        self.music_dir = config["mpc"]["music_dir"]
        self.cmd_queue = Queue()

        try:
            self.mpc.current()
        except:
            raise Exception("An error occured while connecting to the mpd server.")
            return

        try:
            self.client = MatrixClient(config["matrix"]["host"])
        except:
            raise Exception("An error occured while connecting to the matrix server!")
            return


        self.stream_url = config["mpc"]["streamurl"]
        try:
            self.client.login_with_password(config["matrix"]["user"],config["matrix"]["pass"])
        except MatrixRequestError as e:
            print(e)
            if e.code == 403:
                print("Bad username or password.")
                sys.exit(4)
            else:
                print("Check your sever details are correct.")
                sys.exit(3)

        MTX_ROOMS = config["matrix"]["rooms"].split(",")

        for sroom in MTX_ROOMS:
            room = self.client.join_room(sroom)
            room.add_listener(self.__on_cmd)
            self.rooms[room.room_id] = room

    def run(self):
        self.client.start_listener_thread()
        while True:
            event = self.cmd_queue.get()
            if event is None:
                continue;
            else:
                cmd = event['content']['body']
                body = cmd.lower()
                if body.startswith('mpddj:') or body.startswith('!mpddj'):
                    self.__parse_command(body[6:],event,cmd[6:])
                elif body.startswith('mpd dj:'):
                    self.__parse_command(body[7:],event,cmd[7:])

    def __on_cmd(self,event):
        if event['type'] == "m.room.message" and event['content']['msgtype'] == "m.text":
            if event['age'] < 5000:
                self.cmd_queue.put(event)

    def __newfile_play(self,fname,max_attempts=25):
        # Do update check
        attempts = 0
        gotfile = False
        while attempts < max_attempts and not gotfile:
            musiclist = self.mpc.listall()
            gotfile = fname in musiclist
            if not gotfile:
                sleep(0.5)
            attempts += 1
        if gotfile:
            self.mpc.add(fname)
            self.mpc.play()

    def __parse_command(self,cmd,event,cmd_regular):
        cmd = cmd.strip()
        parts = cmd.split(" ")
        room = self.rooms[event['room_id']];
        if parts[0] == "shuffle":
            self.mpc.shuffle()
        elif parts[0] == "prev":
            self.mpc.next()
        elif parts[0] == "play":
            self.mpc.play()
        elif parts[0] == "next":
            self.mpc.next()
        elif parts[0] == "playlist":
            plist = self.mpc.playlist().split("\n")[:-1][:3]
            if len(plist) > 0:
                plist[0] = "▶ " + plist[0]
                room.send_text("\n".join(plist).replace(".ogg",""))
            else:
                room.send_text("The playlist is empty")
        elif parts[0] == "current":
            fname = self.mpc.current()
            fname = fname.replace("_"," ").replace(".ogg","")
            room.send_text(fname)
        elif parts[0] == "update":
            self.mpc.update()
        elif parts[0] == "help":
            room.send_text("Commands are: play,prev,next,current,playlist,help,[youtube url],stream url")
        elif "youtube.com/" in parts[0] or "soundcloud.com/" in parts[0]:
            pos = 1
            try:
                url = cmd_regular.strip().split(" ")[0]
                pos = len(self.mpc.playlist().split('\n'))-1
                status,fname = download_youtube(url,self.music_dir,self.__newfile_play)
            except Exception as e:
                print(e)
                print(traceback.format_exc())
                room.send_text("Couldn't download the file :(")
                return;
            self.mpc.update(True)


            if status:
                if fname is not False:
                    fi = fname.replace(".ogg","")
                    if pos > 0:
                        room.send_text(fi + " has been queued. It currently at position "+str(pos+1))
                    else:
                        room.send_text(fi + " has begun playing")
                else:
                    if pos > 1:
                        room.send_text("Your playlist has been queued. It currently at position "+str(pos))
                    else:
                        room.send_text("Your playlist has begun playing")
                if self.mpc.current() == '':
                    sleep(0.5)# Allow it to breathe
                    self.mpc.play()
            else:
                room.send_text("I couldn't play the file. This is probably a bug and should be reported to Half-Shot.")

        elif "stream url" in cmd:
            room.send_text(self.stream_url)
Ejemplo n.º 32
0
import datetime
import dateutil.relativedelta
import os
#import sched
import threading
import re
import screenutils
import logging

my_server="https://matrix.org"
my_username="******"
my_password="******"
my_room="!DJppiagxDRhqgGMLVq:matrix.org"
client=MatrixClient(my_server)
token=client.login_with_password(my_username,my_password)
room=client.join_room(my_room)
all_chat=True

chat_bot_users=['@vanous','@pokusnykralik']

msg_send=""


def send_to_matrix(message):
    global msg_send
    try:
	#print threading.active_count()
	if threading.active_count()<3:
	    res=room.send_text("%s: %s" % (time.strftime('%X'),message,))
	else:
	   msg_send+="\n%s: %s" % (time.strftime('%X'),message,) #if we are waiting for time to clear, keep filling send buffer
Ejemplo n.º 33
0
class MatrixProtocol(Protocol):

  # List of occupants in each room
  # Used to avoid having to re-request the list of members each time
  room_occupants = {}
  # Keep track of when we joined rooms this session
  # Used to filter out historical messages after accepting room invites
  join_timestamps = {}

  # called on bot init; the following are already created by __init__:
  #   self.bot = SibylBot instance
  #   self.log = the logger you should use
  def setup(self):
    self.rooms = {}
    self.bot.add_var("credentials",persist=True)

    # Incoming message queue - messageHandler puts messages in here and
    # process() looks here periodically to send them to sibyl
    self.msg_queue = Queue()

    # Create a client in setup() because we might use self.client before
    # connect() is called
    homeserver = self.opt('matrix.server')
    self.client = MatrixClient(homeserver)

  # @raise (ConnectFailure) if can't connect to server
  # @raise (AuthFailure) if failed to authenticate to server
  def connect(self):
    homeserver = self.opt('matrix.server')
    user = self.opt('matrix.username')
    pw = self.opt('matrix.password')

    self.log.debug("Connecting to %s" % homeserver)

    try:
      self.log.debug("Logging in as %s" % user)

      # Log in with the existing access token if we already have a token
      if(self.bot.credentials and self.bot.credentials[0] == user):
        self.client = MatrixClient(homeserver, user_id=user, token=self.bot.credentials[1])
      # Otherwise, log in with the configured username and password
      else:
        token = self.client.login_with_password(user,pw)
        self.bot.credentials = (user, token)

      self.rooms = self.client.get_rooms()
      self.log.debug("Already in rooms: %s" % self.rooms)

      # Connect to Sibyl's message callback
      self.client.add_listener(self.messageHandler)
      self.client.add_invite_listener(self.inviteHandler)

      self.log.debug("Starting Matrix listener thread")
      self.client.start_listener_thread(exception_handler=self._matrix_exception_handler)

    except MatrixRequestError as e:
      if(e.code in [401, 403]):
        self.log.debug("Credentials incorrect! Maybe your access token is outdated?")
        raise self.AuthFailure
      else:
        if(self.opt('matrix.debug')):
          tb = traceback.format_exc()
          self.log.debug(tb)
        self.log.debug("Failed to connect to homeserver!")
        raise self.ConnectFailure
    except MatrixHttpLibError as e:
      self.log.error("Failed to connect to homeserver!")
      self.log.debug("Received error:" + str(e))
      raise self.ConnectFailure

  def _matrix_exception_handler(self, e):
    self.msg_queue.put(e)

  # receive/process messages and call bot._cb_message()
  # must ignore msgs from myself and from users not in any of our rooms
  # @call bot._cb_message(Message) upon receiving a valid status or message
  # @raise (PingTimeout) if implemented
  # @raise (ConnectFailure) if disconnected
  # @raise (ServerShutdown) if server shutdown
  def process(self):
    while(not self.msg_queue.empty()):
      next = self.msg_queue.get()
      if(isinstance(next, Message)):
        self.log.debug("Placing message into queue: " + next.get_text())
        self.bot._cb_message(next)
      elif(isinstance(next, MatrixHttpLibError)):
        self.log.debug("Received error from Matrix SDK, stopping listener thread: " + str(next))
        self.client.stop_listener_thread()
        raise self.ConnectFailure("Connection error returned by requests library: " + str(next))


  def messageHandler(self, msg):
    if(self.opt('matrix.debug')):
      self.log.debug(str(msg))

    try:
      # Create a new Message to send to Sibyl
      u = self.new_user(msg['sender'], Message.GROUP)
      r = self.new_room(msg['room_id'])

      if(r in self.join_timestamps
         and datetime.datetime.fromtimestamp(msg['origin_server_ts']/1000, pytz.utc) < self.join_timestamps[r]):
        self.log.info('Message received in {} from before room join, ignoring'.format(msg['room_id']))
        return None

      if('msgtype' in msg['content']):
        msgtype = msg['content']['msgtype']

        if(msgtype == 'm.text'):
          m = Message(u, msg['content']['body'], room=r, typ=Message.GROUP)
          self.log.debug('Handling m.text: ' + msg['content']['body'])
          self.msg_queue.put(m)

        elif(msgtype == 'm.emote'):
          m = Message(u, msg['content']['body'], room=r, typ=Message.GROUP,
          emote=True)
          self.log.debug('Handling m.emote: ' + msg['content']['body'])
          self.msg_queue.put(m)

        elif(msgtype == 'm.image' or msgtype == 'm.audio' or msgtype == 'm.file' or msgtype == 'm.video'):
          media_url = urlparse(msg['content']['url'])
          http_url = self.client.api.base_url + "/_matrix/media/r0/download/{0}{1}".format(media_url.netloc, media_url.path)
          if(msgtype == 'm.image'):
            body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'an image'), http_url)
          elif(msgtype == 'm.audio'):
            body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'an audio file'), http_url)
          elif(msgtype == 'm.video'):
            body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'a video file'), http_url)
          elif(msgtype == 'm.file'):
            body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'a file'), http_url)
          m = Message(u, body, room=r, typ=Message.GROUP)
          self.log.debug("Handling " + msgtype + ": " + body)
          self.msg_queue.put(m)

        elif(msgtype == 'm.location'):
          body = "{0} sent a location: {1}".format(msg['sender'], msg['content']['geo_uri'])
          m = Message(u, body, room=r, typ=Message.GROUP)
          self.log.debug('Handling m.location: ' + body)
          self.msg_queue.put(m)


        else:
          self.log.debug('Not handling message, unknown msgtype')

      elif('membership' in msg):
        if(msg['membership'] == 'join'):
          self.room_occupants[r].add(self.new_user(msg['state_key'], Message.GROUP))
        elif(msg['membership'] == 'leave'):
          self.room_occupants[r].remove(self.new_user(msg['state_key'], Message.GROUP))

    except KeyError as e:
      self.log.debug("Incoming message did not have all required fields: " + e.message)


  def inviteHandler(self, room_id, state):
    join_on_invite = self.opt('matrix.join_on_invite')

    invite_events = [x for x in state['events'] if x['type'] == 'm.room.member'
                     and x['state_key'] == str(self.get_user())
                     and x['content']['membership'] == 'invite']
    if(len(invite_events) != 1):
      raise KeyError("Something's up, found more than one invite state event for " + room_id)

    inviter = invite_events[0]['sender']
    inviter_domain = inviter.split(':')[1]
    my_domain = str(self.get_user()).split(':')[1]

    if(join_on_invite == 'accept' or (join_on_invite == 'domain' and inviter_domain == my_domain)):
      self.log.debug('Joining {} on invite from {}'.format(room_id, inviter))
      self.join_room(MatrixRoom(self, room_id))

    elif(join_on_invite == 'domain' and inviter_domain != my_domain):
      self.log.debug("Received invite for {} but inviter {} is on a different homeserver").format(room_id, inviter)

    else:
      self.log.debug("Received invite for {} from {} but join_on_invite is disabled".format(room_id, inviter))


  # called when the bot is exiting for whatever reason
  # NOTE: sibylbot will already call part_room() on every room in get_rooms()
  def shutdown(self):
    pass

  # send a message to a user
  # @param mess (Message) message to be sent
  # @raise (ConnectFailure) if failed to send message
  # Check: get_emote()
  def send(self,mess):
    (text,to) = (mess.get_text(),mess.get_to())
    try:
      if(mess.get_emote()):
        to.room.send_emote(text)
      else:
        to.room.send_text(text)
    except MatrixError as e:
      raise self.ConnectFailure

  # send a message with text to every user in a room
  # optionally note that the broadcast was requested by a specific User
  # @param mess (Message) the message to broadcast
  # @return (str,unicode) the text that was actually sent
  # Check: get_user(), get_users()
  def broadcast(self,mess):
    """send a message to every user in a room"""

    (text,room,frm) = (mess.get_text(),mess.get_to(),mess.get_user())
    users = self.get_occupants(room)+(mess.get_users() or [])

    # Matrix has no built-in broadcast, so we'll just highlight everyone
    s = 'all: %s --- ' % text
    if frm:
      self.log.debug('Broadcast message from: ' + str(frm))
      s += frm.get_name()+' --- '

    me = self.get_user()
    names = [u.get_name() for u in users if (u!=me and (not frm or u!=frm))]
    s += ', '.join(set(names))

    self.send(Message(self.get_user(),s,to=room))
    return s

  # join the specified room using the specified nick and password
  # @param room (Room) the room to join
  # @call bot._cb_join_room_success(room) on successful join
  # @call bot._cb_join_room_failure(room,error) on failed join
  def join_room(self,room):
    try:
      res = self.client.join_room(room.room.room_id)
      self.bot._cb_join_room_success(room)
      self.join_timestamps[room] = datetime.datetime.now(pytz.utc)
    except MatrixError as e:
      self.bot._cb_join_room_failure(room, e.message)

  # part the specified room
  # @param room (Room) the room to leave
  def part_room(self,room):
    raise NotImplementedError

  # helper function for get_rooms() for protocol-specific flags
  # only needs to handle: FLAG_PARTED, FLAG_PENDING, FLAG_IN, FLAG_ALL
  # @param flag (int) one of Room.FLAG_* enums
  # @return (list of Room) rooms matching the flag
  def _get_rooms(self,flag):
    mxrooms = self.client.get_rooms()
    return [self.new_room(mxroom) for mxroom in mxrooms]


  # @param room (Room) the room to query
  # @return (list of User) the Users in the specified room
  def get_occupants(self,room):
    if(room in self.room_occupants):
      return list(self.room_occupants[room])
    else:
      try:
        memberdict = room.room.get_joined_members()
        users = [ self.new_user(x) for x in memberdict ]
        self.room_occupants[room] = set(users)
        return users
      except MatrixError as e:
        raise self.ConnectFailure

  # @param room (Room) the room to query
  # @return (str) the nick name we are using in the specified room
  def get_nick(self,room):
    return self.get_user().get_name() # TODO: per-room nicknames

  # @param room (Room) the room to query
  # @param nick (str) the nick to examine
  # @return (User) the "real" User behind the specified nick/room
  def get_real(self,room,nick):
    raise NotImplementedError

  # @return (User) our username
  def get_user(self):
    return MatrixUser(self,self.opt('matrix.username'),Message.GROUP)

  # @param user (str) a user id to parse
  # @param typ (int) either Message.GROUP or Message.PRIVATE
  # @param real (User) [self] the "real" user behind this user
  # @return (User) a new instance of this protocol's User subclass
  def new_user(self,user,typ=None,real=None):
    return MatrixUser(self,user,typ,real)

  # @param name (object) the identifier for this Room
  # @param nick (str) [None] the nick name to use in this Room
  # @param pword (str) [None] the password for joining this Room
  # @return (Room) a new instance of this protocol's Room subclass
  def new_room(self,room_id_or_alias,nick=None,pword=None):
    return MatrixRoom(self,room_id_or_alias,nick,pword)
Ejemplo n.º 34
0
def start(stdscr):
    global size, room, data, rooms, access_token, endTime, rooms, all_rooms, lastEventRoom, room_keys

    curses.curs_set(0)
    curses.use_default_colors()
    size = stdscr.getmaxyx()

    stdscr.addstr(0, 0, "loading...")
    stdscr.refresh()
    loadCredentials("./credentials.json")

    client = MatrixClient(server)
    access_token = client.login_with_password(
        username,
        password,
        size[0])

    rooms = client.get_rooms()

    all_rooms = "all rooms"
    rooms[all_rooms] = Room(client, all_rooms)

    rooms[all_rooms].events = []
    room_keys = list(rooms.keys())
    room = all_rooms  #room_keys[1] # "all_rooms"
    nextRoom = 1
    endTime = client.end

    curses.halfdelay(10)
    maxDisplayName = 24
    displayNamestartingPos = 20
    PAD_COMMENTS = True
    pause = False

    client.add_listener(processMessage)
    client.start_listener_thread()

    curses.echo()
    stdscr.keypad(True)
    inputBuffer = ""
    lastEventRoom = all_rooms
    the_room_to_post_to = None  # store the last room we saw before we started typing

    while(True):
        size = stdscr.getmaxyx()
        maxChars = size[1] - 1 - len(username) - 3

        stdscr.clear()

        # we want NAME aka ALIAS[0] (ROOM_ID)
        # or 2nd choice: ALIAS[0] (ROOM_ID)
        # or fallback: ROOM_ID
        line = str(room)

        if line == all_rooms:
            pass
        elif rooms[room].name is None:
            if len(rooms[room].aliases) > 0 and rooms[room].aliases[0] != room:
                line = rooms[room].aliases[0] + " (" + line + ")"
        else:
            if len(rooms[room].aliases) > 0 and rooms[room].aliases[0] != room:
                line = rooms[room].name + " aka " + getFirstRoomAlias(rooms[room]) + " (" + line + ")"
            else:
                if rooms[room].name != room:
                    line = rooms[room].name + " (" + line + ")"

        #line.encode("utf-8")
        if rooms[room].topic is not None:
            line += " · topic: " + rooms[room].topic

        stdscr.addstr(
            0, 0, (
                "redpill v0.7 · screen size: " + str(size) + " · chat size: "
                + str(len(rooms[room].events)) + " · room: " + str(line) + " the variables: room: " + room + " last: "
                + lastEventRoom
            ), curses.A_UNDERLINE
        )

        current = len(rooms[room].events) - 1

        if True:
            y = 1
            if current >= 0:

                # TODO: something when the first event is a typing event
                currentLine = size[0] - 1

                # input
                space = ""
                for i in range(size[1] - 1):
                    space += " "
                stdscr.addstr(currentLine, 0, space, curses.A_DIM)
                stdscr.addstr(currentLine, 0, "<" + username + ">", curses.A_DIM)
                stdscr.addstr(currentLine - 1, 0, space, curses.A_UNDERLINE)

                for event in reversed(rooms[room].events):
                    if event["type"] == "m.typing":
                    #if True:
                        continue  # do something clever
                    elif event["type"] == "m.presence":
                    #if True:
                        continue  # do something clever

                    elif event["type"] == "m.roomchange":
                        room_id = event["room_id"]
                        #lin = (str(rooms[room_id].name) + " aka " + getFirstRoomAlias(rooms[room_id]) + " (" +
                        #    rooms[room_id].room_id + ")")
                        line = room_id
                        if line == all_rooms:
                            pass
                        elif rooms[line].name is None:
                            if len(rooms[room_id].aliases) > 0 and rooms[room_id].aliases[0] != room_id:
                                line = rooms[room_id].aliases[0] + " (" + line + ")"
                        else:
                            if len(rooms[room_id].aliases) > 0 and rooms[room_id].aliases[0] != room_id:
                                line = rooms[room_id].name + " aka " + getFirstRoomAlias(rooms[room_id]) + " (" + line + ")"
                            else:
                                if rooms[room_id].name != room_id:
                                    line = rooms[room_id].name + " (" + line + ")"

                        #if rooms[room].topic is not None:
                        #    line += " · topic: " + rooms[room].topic

                        currentLine -= 1
                        stdscr.addstr(currentLine, 0, "Event(s) from " + line, curses.A_DIM)


                    else:
                        #currentLine = size[0] - y
                        currentLine -= 1

                        if currentLine < 3:  # how many lines we want to reserve
                            break
                        #if currentLine == 5:
                        #    currentLine -= 1
                        y += 1
                        if "origin_server_ts" in event:
                            convertedDate = datetime.datetime.fromtimestamp(
                                int(
                                    event["origin_server_ts"] / 1000)
                                ).strftime('%Y-%m-%d %H:%M:%S')

                        # assumption: body == normal message
                        length = 0
                        if "user_id" in event:
                            length = len(
                                event["user_id"]
                            )
                        if "body" in event["content"]:

                            rawText = event["content"]["body"].encode('utf-8')

                            if event["content"]["msgtype"] == "m.emote":
                                if len(rawText) > 0 and rawText[0] == " ":
                                    rawText = rawText[1:]

                            linesNeeded = (displayNamestartingPos + maxDisplayName + 3 + len(rawText)) / size[1]
                            lin = (displayNamestartingPos + maxDisplayName + 3 + len(rawText))

                            #if currentLine == size[0] - 2:
                            #    stdscr.addstr(currentLine, 0, str(lin) + " " + str(size[1]) + " " + str(linesNeeded) + "  ", curses.A_UNDERLINE)
                            #else:
                            #    stdscr.addstr(currentLine, 0, str(lin) + " " + str(size[1]) + " " + str(linesNeeded) + "  ")



                            linesNeeded = 0

                            buf = ""
                            lineByLineText = []
                            first = True
                            bufSinceLastWord = ""
                            for char in rawText:
                                if True: #for char in line:

                                    bufSinceLastWord += char

                                    if char == '\n':
                                        linesNeeded += 1
                                        buf += bufSinceLastWord

                                        if PAD_COMMENTS or first:
                                            linesNeeded += (displayNamestartingPos + maxDisplayName + 3 + len(buf)) / size[1]
                                        else:
                                            linesNeeded += len(buf) / size[1]

                                        first = False
                                        lineByLineText.append(buf)
                                        buf = ""
                                        bufSinceLastWord = ""
                                    else:
                                        if ((PAD_COMMENTS and (displayNamestartingPos + maxDisplayName + 3 + len(buf + bufSinceLastWord)) == size[1] - 1)
                                            or (not PAD_COMMENTS and (len(buf + bufSinceLastWord)) == size[1] - 1)):

                                        #if (displayNamestartingPos + maxDisplayName + 3 + len(buf + bufSinceLastWord)) == size[1] - 1:
                                            if len(buf) == 0:
                                                buf += bufSinceLastWord
                                                bufSinceLastWord = ""

                                            if char.isspace():
                                                buf += bufSinceLastWord
                                                lineByLineText.append(buf)
                                                bufSinceLastWord = ""
                                                buf = ""
                                            else:
                                                lineByLineText.append(buf)
                                                buf = bufSinceLastWord
                                                bufSinceLastWord = ""
                                            linesNeeded += 1

                                    if char.isspace():
                                        buf += bufSinceLastWord
                                        bufSinceLastWord = ""

#                                if (displayNamestartingPos + maxDisplayName + 3 + len(buf + bufSinceLastWord)) == size[1] - 1:
                                if ((PAD_COMMENTS and (displayNamestartingPos + maxDisplayName + 3 + len(buf + bufSinceLastWord)) == size[1] - 1)
                                   or (not PAD_COMMENTS and (len(buf + bufSinceLastWord)) == size[1] - 1)):

                                    buf += bufSinceLastWord
                                    bufSinceLastWord = ""
                                    lineByLineText.append(buf)
                                    linesNeeded += 1
                                    buf = ""
                                    #elif char == ' ':   # skip all whitespace
                                    #    self.X += 1
                            buf += bufSinceLastWord
                            lineByLineText.append(buf)
                            linesNeeded += (displayNamestartingPos + maxDisplayName + 3 + len(buf)) / size[1]
                            buf = ""

                            currentLine -= linesNeeded
                            if currentLine - linesNeeded < 2:  # how many lines we want to reserve
                                break

                            if currentLine == size[0] - 2:
                                stdscr.addstr(currentLine, 0, str(lin) + " " + str(size[1]) + " " + str(linesNeeded) + "  ", curses.A_UNDERLINE)
                            else:
                                stdscr.addstr(currentLine, 0, str(lin) + " " + str(size[1]) + " " + str(linesNeeded) + "  ")

                            #for i in range(linesNeeded):


                            if PAD_COMMENTS:
                                pad = displayNamestartingPos + maxDisplayName + 3


                                #if linesNeeded == 0:
                                linesNeeded += 1

                                for i in range(linesNeeded):
                                    buf = rawText[:size[1] - pad]
                                    rawText = rawText[size[1] - pad:]


                                    if currentLine + i == size[0] - 2:
                                        stdscr.addstr(
                                            currentLine + i, displayNamestartingPos +
                                            maxDisplayName + 3, lineByLineText[i],
                                            curses.A_BOLD + curses.A_UNDERLINE
                                        )
                                    else:
                                        try:
                                            stdscr.addstr(
                                                currentLine + i, displayNamestartingPos +
                                                maxDisplayName + 3, lineByLineText[i],
                                                curses.A_BOLD
                                            )
                                        except:
                                            e = sys.exc_info()[0]
                                            print("Error: unable to start thread. " + str(e))
                                            stdscr.addstr(1, 0, str(e))



                            else:
                                # TODO: need to split this out to get proper underline
                                if currentLine == size[0] - 2:
                                    stdscr.addstr(
                                        currentLine, displayNamestartingPos +
                                        maxDisplayName + 3, rawText,
                                        curses.A_BOLD + curses.A_UNDERLINE
                                    )
                                else:
                                    stdscr.addstr(
                                        currentLine, displayNamestartingPos +
                                        maxDisplayName + 3, rawText,
                                        curses.A_BOLD
                                    )

                            usern = event["user_id"]

                            if length > maxDisplayName:
                                usern = usern[:maxDisplayName - 3] + "..."

                            if event["content"]["msgtype"] == "m.emote":

                                usern = "* " + usern
                                if currentLine == size[0] - 2:
                                    stdscr.addstr(
                                        currentLine, displayNamestartingPos + max(0,  maxDisplayName - length),
                                        str(usern),
                                        curses.A_UNDERLINE + curses.A_BOLD
                                    )
                                else:
                                    stdscr.addstr(
                                        currentLine, displayNamestartingPos + max(0,  maxDisplayName - length),
                                        str(usern),
                                        curses.A_BOLD
                                    )
                            else:
                                usern = "<" + usern + ">"
                                if currentLine == size[0] - 2:
                                    stdscr.addstr(
                                        currentLine, displayNamestartingPos + max(0,  maxDisplayName - length),
                                        str(usern),
                                        curses.A_UNDERLINE
                                    )
                                else:
                                    stdscr.addstr(
                                        currentLine, displayNamestartingPos + max(0,  maxDisplayName - length),
                                        str(usern)
                                    )

                            if currentLine == size[0] - 2:
                                stdscr.addstr(currentLine, 0, convertedDate, curses.A_UNDERLINE)
                            else:
                                stdscr.addstr(currentLine, 0, convertedDate)

                            #if currentLine == size[1]:  # last line
                            #    stdscr.addstr(
                            #        currentLine, displayNamestartingPos +
                            #        maxDisplayName + 3, buf[:size[1] -
                            #        (displayNamestartingPos + maxDisplayName + 4)],
                            #         curses.A_BOLD
                            #    )
                            #else:
                            #    stdscr.addstr(
                            #        currentLine, displayNamestartingPos +
                            #        maxDisplayName + 3, buf,
                            #        curses.A_BOLD
                            #    )

                        # membership == join/leave events
                        elif "membership" in event["content"]:
                            buf = " invited someone"
                            if event["content"]["membership"] == "invite":
                                if "state_key" in event:
                                    buf = " invited " + event["state_key"]
                            elif event["content"]["membership"] == "join":
                                buf = " has joined"
                            elif event["content"]["membership"] == "leave":
                                buf = " has left"

                            if length > maxDisplayName:
                                if currentLine == size[0] - 2:
                                    stdscr.addstr(
                                        currentLine,
                                        displayNamestartingPos + 1,
                                        str(event["user_id"]),
                                        curses.A_DIM + curses.A_UNDERLINE
                                    )
                                    stdscr.addstr(
                                        currentLine,
                                        displayNamestartingPos + length + 1,
                                        buf,
                                        curses.A_DIM + curses.A_UNDERLINE
                                    )
                                else:
                                    stdscr.addstr(
                                        currentLine,
                                        displayNamestartingPos + 1,
                                        str(event["user_id"]),
                                        curses.A_DIM
                                    )
                                    stdscr.addstr(
                                        currentLine,
                                        displayNamestartingPos + length + 1,
                                        buf,
                                        curses.A_DIM
                                    )

                            else:
                                if currentLine == size[0] - 2:
                                    stdscr.addstr(
                                        currentLine,
                                        displayNamestartingPos + 1 +
                                        maxDisplayName - length,
                                        str(event["user_id"]),
                                        curses.A_DIM + curses.A_UNDERLINE
                                    )
                                    stdscr.addstr(
                                        currentLine,
                                        displayNamestartingPos + maxDisplayName + 1,
                                        buf,
                                        curses.A_DIM + curses.A_UNDERLINE
                                    )
                                else:
                                    stdscr.addstr(
                                        currentLine,
                                        displayNamestartingPos + 1 +
                                        maxDisplayName - length,
                                        str(event["user_id"]),
                                        curses.A_DIM
                                    )
                                    stdscr.addstr(
                                        currentLine,
                                        displayNamestartingPos + maxDisplayName + 1,
                                        buf,
                                        curses.A_DIM
                                    )

                    current -= 1
        if pause:
            stdscr.addstr(
                int(size[0] / 2) - 1,
                int(size[1] / 2),
                "          ",
                curses.A_REVERSE
            )
            stdscr.addstr(
                int(size[0] / 2),
                int(size[1] / 2),
                "  PAUSED  ",
                curses.A_REVERSE
            )
            stdscr.addstr(
                int(size[0] / 2) + 1,
                int(size[1] / 2),
                "          ",
                curses.A_REVERSE
            )
        try:
            stdscr.addstr(size[0] - 1, len(username) + 3, inputBuffer[-maxChars:])
        except:
            e = sys.exc_info()[0]
            print("Error: unable to start thread. " + str(e))
            stdscr.addstr(1, 0, str(e))

        stdscr.refresh()

 #       getInput(stdscr)

#def getInput(stdscr):
 #   if True:
        try:

            c = stdscr.getch(size[0] - 1, len(username) + 3)
            #c = stdscr.getkey(size[0] - 1, len(username) + 3)

            #stri = stdscr.getstr(size[0] - 1, len(username) + 3, 10)
            if c == -1:
                stdscr.addstr(1, 0, "timeout")
            else:
                if c <= 256 and c != 10 and c != 9: ## enter and tab
                    inputBuffer += chr(c)
                if len(inputBuffer) == 1:  # e.g. just started typing
                    if lastEventRoom != all_rooms:
                        the_room_to_post_to = lastEventRoom

            if c == 9:
                #stdscr.addstr(1, 0, "%s was pressed\n" % c)
                room = room_keys[nextRoom]
                nextRoom = (nextRoom + 1) % len(rooms)
                the_room_to_post_to = None
            elif c == 10: # enter
                with open('sends.log', 'a') as the_file:
                    the_file.write("the_room_to_post_to:" + str(the_room_to_post_to) + "\n")
                    the_file.write("lastEventRoom: " + str(lastEventRoom) + "\n")
                    the_file.write("room: " + str(room) + "\n")
                    the_file.write("inputBuffer: " + str(inputBuffer) + "\n")
                    the_file.write("---\n")

                if inputBuffer.startswith("/invite"):
                    user_id = inputBuffer[7:].strip()
                    rooms[room].invite_user(user_id)
                elif inputBuffer.startswith("/kick"):
                    user_id = inputBuffer[5:].strip()
                    reason = "no reason..."
                    rooms[room].kick_user(user_id, reason)
                elif inputBuffer.startswith("/power"):
                    user_id = inputBuffer[7:].strip()
                    power_level = 50
                    rooms[room].set_power_level(user_id, power_level)
                elif inputBuffer.startswith("/op"):
                    user_id = inputBuffer[2:].strip()
                    rooms[room].set_power_level(user_id)
                elif inputBuffer.startswith("/ban"): # reason
                    user_id = inputBuffer[4:].strip()
                    reason = "sux" #FIXME
                    rooms[room].ban(user_id, reason)
                elif inputBuffer.startswith("/join"):   # there's a /join that supports aliases
                    room_alias = inputBuffer[5:].strip()
                    client.join_room(room_alias)
                elif inputBuffer.startswith("/j"):
                    room_alias = inputBuffer[2:].strip()
                    client.join_room(room_alias)
                elif inputBuffer.startswith("/leave"):
                    rooms[room].leave_room(room_id)
                elif inputBuffer.startswith("/create"): # create a new room
                    is_public = True
                    invitees = ()
                    #     def create_room(self, alias=None, is_public=False, invitees=()):
                    room_alias = inputBuffer[7:].strip()
                    client.create_room(room_alias, is_public, invitees)
                elif inputBuffer.startswith("/topic"):   # get or set topic
                    new_topic = inputBuffer[6:].strip()
                    if len(new_topic) > 0:
                        rooms[room].topic = new_topic
                    else:
                        pass
                        #rooms[room].topic = "fail"
                else:
                    if room == all_rooms:
                        if the_room_to_post_to is None:
                            if lastEventRoom != all_rooms:
                                the_room_to_post_to = lastEventRoom
                            else:
                                stdscr.addstr(1, 0, "No idea what room to post to!")
                                stdscr.refresh()
                                inputBuffer = "No idea what room to post to!"
                                continue
                    else:
                        the_room_to_post_to = room

                    if inputBuffer.startswith("/me"):
                        rooms[the_room_to_post_to].send_emote(inputBuffer[3:])
                    else:
                        rooms[the_room_to_post_to].send_text(inputBuffer)

                inputBuffer = ""
                the_room_to_post_to = None
            elif c == curses.KEY_DC:
                inputBuffer = ""
                the_room_to_post_to = None
            elif c == curses.KEY_BACKSPACE:
                if len(inputBuffer) > 0:
                    inputBuffer = inputBuffer[:-1]
                if len(inputBuffer) == 0:
                    the_room_to_post_to = None
            elif c == curses.KEY_IC:
                pause = not(pause)
                if pause:
                    curses.nocbreak()
                    curses.cbreak()
                    stdscr.timeout(-1)
                    stdscr.addstr(
                        int(size[0] / 2) - 1,
                        int(size[1] / 2),
                        "          ",
                        curses.A_REVERSE
                    )
                    stdscr.addstr(
                        int(size[0] / 2),
                        int(size[1] / 2),
                        " PAUSING  ",
                        curses.A_REVERSE
                    )
                    stdscr.addstr(
                        int(size[0] / 2) + 1,
                        int(size[1] / 2),
                        "          ",
                        curses.A_REVERSE
                    )
                    stdscr.refresh()
                else:
                    stdscr.addstr(
                        int(size[0] / 2) - 1,
                        int(size[1] / 2),
                        "          ",
                        curses.A_REVERSE
                    )
                    stdscr.addstr(
                        int(size[0] / 2),
                        int(size[1] / 2),
                        " RESUMING ",
                        curses.A_REVERSE
                    )
                    stdscr.addstr(
                        int(size[0] / 2) + 1,
                        int(size[1] / 2),
                        "          ",
                        curses.A_REVERSE
                    )
                    stdscr.refresh()
                    curses.halfdelay(10)
                    stdscr.timeout(1)
            elif c == 27:  # need to test for alt combo or ESC
                curses.cbreak()
                curses.echo()
                #curses.curs_set(1)
                stdscr.keypad(0)
                curses.endwin()
                quit()
            elif c == curses.KEY_F2:
                PAD_COMMENTS = not PAD_COMMENTS

            #stdscr.addstr(2, 0, "time() == %s\n" % time.time())

        finally:
            do_nothing = True
Ejemplo n.º 35
0
class MatrixTransport(Transport):
    def __init__(self, homeserver, username, password, matrix_room):
        super().__init__()
        self.homeserver = homeserver
        self.username = username
        self.password = password
        self.room_name = matrix_room
        self.is_running = gevent.event.Event()
        self.do_reconnect = gevent.event.AsyncResult()
        self.retry_timeout = 5
        self.client = None

    def matrix_exception_handler(self, e):
        """Called whenever an exception occurs in matrix client thread.

            Any exception other than MatrixHttpLibError will be sent to parent hub,
             terminating the program.
        """
        if isinstance(e, MatrixHttpLibError):
            log.warning(str(e))
            self.do_reconnect.set(100)
            raise e
        gevent.get_hub().parent.throw(e)

    def connect(self):
        """Connects to a matrix homeserver and initializes the client class"""
        if self.client is not None:
            self.client.logout()
            self.client = None
        self.client = MatrixClient(self.homeserver)
        self.client.login_with_password(self.username, self.password)
        self.room = self.client.join_room(self.room_name)
        self.client.start_listener_thread(
            exception_handler=lambda e: self.matrix_exception_handler(e), )

    def get_room_events(self, limit=100):
        """Get past messages in the broadcast room, up to the @limit"""
        f = {"room": {"timeline": {"limit": 100}}}
        result = self.client.api.sync(filter=json.dumps(f))
        room_id = self.room.room_id
        room = result['rooms']['join'][room_id]
        return room['timeline']['events']

    def sync_history(self):
        """Calls event callback for all events retrived from the broadcast room history"""
        events = self.get_room_events()
        for event in events:
            self.push_event(event)

    def push_event(self, event):
        """Calls a registered event callback"""
        for listener in self.room.listeners:
            if listener['event_type'] is None or listener[
                    'event_type'] == event['type']:
                listener['callback'](self.room, event)

    def dispatch(self, room, event):
        if event['type'] == "m.room.message":
            if event['content']['msgtype'] == "m.text":
                self.run_message_callbacks(event['content']['body'])
                log.debug("{0}: {1}".format(event['sender'],
                                            event['content']['body']))

    def transmit_data(self, message: str, target_node: str = None):
        # TODO: fix sending to certain receiver
        assert self.room is not None
        self.room.send_text(message)

    def _run(self):
        """Gevent loop. The Matrix connection is restored automatically on error."""
        while self.is_running.is_set() is False:
            try:
                self.connect()
                self.room.add_listener(
                    lambda room, event: self.dispatch(room, event))
                self.sync_history()
                self.do_reconnect.wait()
                if self.do_reconnect.get() == 100:
                    gevent.sleep(self.retry_timeout)
                    continue
            except (requests.exceptions.ConnectionError,
                    MatrixHttpLibError) as e:
                log.warn(
                    "Connection to %s failed. Retrying in %d seconds (%s)" % (
                        self.homeserver,
                        self.retry_timeout,
                        str(e),
                    ), )
                gevent.sleep(self.retry_timeout)
Ejemplo n.º 36
0
    1: '*WARNING*: ',
    0: 'OK: '
}

# Event information
try:
    client = sensu_event['client']['name']
    check = sensu_event['check']['name']
    output = sensu_event['check']['output']
    status = statuses[sensu_event['check']['status']]
    history = sensu_event['check']['history']
except Exception as e:
    print(str(e))

previous_status = history[len(history)-1]

# Message text
# *WARNING*: Client_name\n /tmp/test does not exists
text = status + client + "\n" + output

# Check previous status and send check information
if previous_status != sensu_event['check']['status']:
    # Initialize Matrix client
    client = MatrixClient(conf['homeserver'])
    token = client.login_with_password(username=conf['username'],
                                       password=conf['password'])
    # Join to Room
    room = client.join_room(conf['room'])

    room.send_text(text)