コード例 #1
0
def server_from_buffer(buffer):
    for server in SERVERS.values():
        if buffer in server.buffers.values():
            return server
        if buffer == server.server_buffer:
            return server
    return None
コード例 #2
0
def matrix_unload_cb():
    for server in SERVERS.values():
        server.config.free()

    G.CONFIG.free()

    return W.WEECHAT_RC_OK
コード例 #3
0
def matrix_me_command_cb(data, buffer, args):
    for server in SERVERS.values():
        if buffer in server.buffers.values():

            if not server.connected:
                message = ("{prefix}matrix: you are not connected to "
                           "the server").format(prefix=W.prefix("error"))
                W.prnt(server.server_buffer, message)
                return W.WEECHAT_RC_ERROR

            room_id = key_from_value(server.buffers, buffer)

            if not args:
                return W.WEECHAT_RC_OK

            formatted_data = Formatted.from_input_line(args)
            message = MatrixEmoteMessage(server.client,
                                         room_id=room_id,
                                         formatted_message=formatted_data)

            server.send_or_queue(message)

            return W.WEECHAT_RC_OK

        elif buffer == server.server_buffer:
            message = ("{prefix}matrix: command \"me\" must be "
                       "executed on a Matrix channel buffer").format(
                           prefix=W.prefix("error"))
            W.prnt("", message)
            return W.WEECHAT_RC_OK
コード例 #4
0
def matrix_command_part_cb(data, buffer, command):
    def part(server, buffer, args):
        rooms = []

        split_args = args.split(" ", 1)

        if len(split_args) == 1:
            if buffer == server.server_buffer:
                message = ("{prefix}Error with command \"/part\" (help on "
                           "command: /help part)").format(
                               prefix=W.prefix("error"))
                W.prnt("", message)
                return

            rooms = [key_from_value(server.buffers, buffer)]

        else:
            _, rooms = split_args
            rooms = rooms.split(" ")

        for room_id in rooms:
            message = MatrixPartMessage(server.client, room_id=room_id)
            server.send_or_queue(message)

    for server in SERVERS.values():
        if buffer in server.buffers.values():
            part(server, buffer, command)
            return W.WEECHAT_RC_OK_EAT
        elif buffer == server.server_buffer:
            part(server, buffer, command)
            return W.WEECHAT_RC_OK_EAT

    return W.WEECHAT_RC_OK
コード例 #5
0
ファイル: config.py プロジェクト: tylerjw/weechat-matrix
def matrix_config_change_cb(data, option):
    option_name = key_from_value(OPTIONS.options, option)

    if option_name == "redactions":
        OPTIONS.redaction_type = RedactType(W.config_integer(option))

    elif option_name == "server_buffer":
        OPTIONS.look_server_buf = ServerBufferType(W.config_integer(option))
        for server in SERVERS.values():
            if server.server_buffer:
                server_buffer_merge(server.server_buffer)

    elif option_name == "max_initial_sync_events":
        OPTIONS.sync_limit = W.config_integer(option)

    elif option_name == "max_backlog_sync_events":
        OPTIONS.backlog_limit = W.config_integer(option)

    elif option_name == "fetch_backlog_on_pgup":
        OPTIONS.enable_backlog = W.config_boolean(option)

        if OPTIONS.enable_backlog:
            if not OPTIONS.page_up_hook:
                hook_page_up(matrix.globals.CONFIG)
        else:
            if OPTIONS.page_up_hook:
                W.unhook(OPTIONS.page_up_hook)
                OPTIONS.page_up_hook = None

    return 1
コード例 #6
0
def matrix_command_invite_cb(data, buffer, command):
    def invite(server, buf, args):
        split_args = args.split(" ", 1)

        # TODO handle join for non public rooms
        if len(split_args) != 2:
            message = ("{prefix}Error with command \"/invite\" (help on "
                       "command: /help invite)").format(
                           prefix=W.prefix("error"))
            W.prnt("", message)
            return

        _, invitee = split_args
        room_id = key_from_value(server.buffers, buf)

        message = MatrixInviteMessage(server.client,
                                      room_id=room_id,
                                      user_id=invitee)
        server.send_or_queue(message)

    for server in SERVERS.values():
        if buffer in server.buffers.values():
            invite(server, buffer, command)
            return W.WEECHAT_RC_OK_EAT

    return W.WEECHAT_RC_OK
コード例 #7
0
def matrix_command_kick_cb(data, buffer, command):
    def kick(server, buf, args):
        split_args = args.split(" ", 1)[1:]

        if (len(split_args) < 1
                or split_args[0].startswith("#") and len(split_args) < 2):
            error_msg = ('{prefix}Error with command "/kick" (help on '
                         'command: /help kick)').format(
                             prefix=W.prefix("error"))
            W.prnt("", error_msg)
            return

        if split_args[0].startswith("#"):
            assert len(split_args) >= 2
            room_id = split_args[0]
            kicked_user = split_args[1]
            reason = split_args[2:] or None
        else:
            room_id = key_from_value(server.buffers, buf)
            kicked_user = split_args[0]
            reason = split_args[1:] or None

        message = MatrixKickMessage(server.client,
                                    room_id=room_id,
                                    user_id=kicked_user,
                                    reason=reason)
        server.send_or_queue(message)

    for server in SERVERS.values():
        if buffer in server.buffers.values():
            kick(server, buffer, command)
            return W.WEECHAT_RC_OK_EAT

    return W.WEECHAT_RC_OK
コード例 #8
0
def matrix_bar_item_name(data, item, window, buffer, extra_info):
    # pylint: disable=unused-argument
    for server in SERVERS.values():
        if buffer in server.buffers.values():
            color = ("status_name_ssl"
                     if server.ssl_context.check_hostname else "status_name")

            room_id = key_from_value(server.buffers, buffer)

            room = server.rooms[room_id]

            return "{color}{name}".format(
                color=W.color(color),
                name=room.display_name(server.user_id))

        elif buffer == server.server_buffer:
            color = ("status_name_ssl"
                     if server.ssl_context.check_hostname else "status_name")

            return "{color}server{del_color}[{color}{name}{del_color}]".format(
                color=W.color(color),
                del_color=W.color("bar_delim"),
                name=server.name)

    return ""
コード例 #9
0
def matrix_message_completion_cb(data, completion_item, buffer, completion):
    max_events = 500

    def redacted_or_not_message(tags):
        # type: (List[str]) -> bool
        if SCRIPT_NAME + "_redacted" in tags:
            return True
        if SCRIPT_NAME + "_message" not in tags:
            return True

        return False

    def event_id_from_tags(tags):
        # type: (List[str]) -> Optional[str]
        for tag in tags:
            if tag.startswith("matrix_id"):
                event_id = tag[10:]
                return event_id

        return None

    for server in SERVERS.values():
        if buffer in server.buffers.values():
            room_buffer = server.find_room_from_ptr(buffer)
            lines = room_buffer.weechat_buffer.lines

            added = 0

            for line in lines:
                tags = line.tags
                if redacted_or_not_message(tags):
                    continue

                event_id = event_id_from_tags(tags)

                if not event_id:
                    continue

                # Make sure we'll be able to reliably detect the end of the
                # quoted snippet
                message_fmt = line.message.replace("\\", "\\\\") \
                                          .replace('"', '\\"')

                if len(message_fmt) > REDACTION_COMP_LEN + 2:
                    message_fmt = message_fmt[:REDACTION_COMP_LEN] + ".."

                item = ('{event_id}|"{message}"').format(event_id=event_id,
                                                         message=message_fmt)

                W.hook_completion_list_add(completion, item, 0,
                                           W.WEECHAT_LIST_POS_END)
                added += 1

                if added >= max_events:
                    break

            return W.WEECHAT_RC_OK

    return W.WEECHAT_RC_OK
コード例 #10
0
ファイル: config.py プロジェクト: yankaykas/weechat-matrix
def config_server_buffer_cb(data, option):
    """Callback for the look.server_buffer option.
    Is called when the option is changed and merges/splits the server
    buffer"""

    for server in SERVERS.values():
        server.buffer_merge()
    return 1
コード例 #11
0
def matrix_command_buf_clear_cb(data, buffer, command):
    for server in SERVERS.values():
        if buffer in server.buffers.values():
            room_id = key_from_value(server.buffers, buffer)
            server.rooms[room_id].prev_batch = server.next_batch

            return W.WEECHAT_RC_OK

    return W.WEECHAT_RC_OK
コード例 #12
0
def matrix_room_completion_cb(data, completion_item, buffer, completion):
    """Completion callback for matrix room names."""
    for server in SERVERS.values():
        for room_buffer in server.room_buffers.values():
            name = room_buffer.weechat_buffer.short_name

            W.hook_completion_list_add(completion, name, 0,
                                       W.WEECHAT_LIST_POS_SORT)

    return W.WEECHAT_RC_OK
コード例 #13
0
ファイル: server.py プロジェクト: tylerjw/weechat-matrix
def matrix_config_server_write_cb(data, config_file, section_name):
    if not W.config_write_line(config_file, section_name, ""):
        return W.WECHAT_CONFIG_WRITE_ERROR

    for server in SERVERS.values():
        for option in server.options.values():
            if not W.config_write_option(config_file, option):
                return W.WECHAT_CONFIG_WRITE_ERROR

    return W.WEECHAT_CONFIG_WRITE_OK
コード例 #14
0
def matrix_bar_item_plugin(data, item, window, buffer, extra_info):
    # pylint: disable=unused-argument
    for server in SERVERS.values():
        if (buffer in server.buffers.values() or
                buffer == server.server_buffer):
            return "matrix{color}/{color_fg}{name}".format(
                color=W.color("bar_delim"),
                color_fg=W.color("bar_fg"),
                name=server.name)

    return ""
コード例 #15
0
def buffer_command_cb(data, _, command):
    """Override the buffer command to allow switching buffers by short name."""
    command = command[7:].strip()

    buffer_subcommands = [
        "list", "add", "clear", "move", "swap", "cycle", "merge", "unmerge",
        "hide", "unhide", "renumber", "close", "notify", "localvar", "set",
        "get"
    ]

    if not command:
        return W.WEECHAT_RC_OK

    command_words = command.split()

    if len(command_words) >= 1:
        if command_words[0] in buffer_subcommands:
            return W.WEECHAT_RC_OK

        elif command_words[0].startswith("*"):
            return W.WEECHAT_RC_OK

        try:
            int(command_words[0])
            return W.WEECHAT_RC_OK
        except ValueError:
            pass

    room_buffers = []

    for server in SERVERS.values():
        room_buffers.extend(server.room_buffers.values())

    sorted_buffers = sorted(room_buffers,
                            key=lambda b: b.weechat_buffer.number)

    for room_buffer in sorted_buffers:
        buffer = room_buffer.weechat_buffer

        if command in buffer.short_name:
            displayed = W.current_buffer() == buffer._ptr

            if displayed:
                continue

            W.buffer_set(buffer._ptr, 'display', '1')
            return W.WEECHAT_RC_OK_EAT

    return W.WEECHAT_RC_OK
コード例 #16
0
def buffer_switch_cb(_, _signal, buffer_ptr):
    """Do some buffer operations when we switch buffers.

    This function is called every time we switch a buffer. The pointer of
    the new buffer is given to us by weechat.

    If it is one of our room buffers we check if the members for the room
    aren't fetched and fetch them now if they aren't.

    Read receipts are send out from here as well.
    """
    for server in SERVERS.values():
        if buffer_ptr == server.server_buffer:
            return W.WEECHAT_RC_OK

        if buffer_ptr not in server.buffers.values():
            continue

        room_buffer = server.find_room_from_ptr(buffer_ptr)
        if not room_buffer:
            continue

        last_event_id = room_buffer.last_event_id

        if room_buffer.should_send_read_marker:
            # A buffer may not have any events, in that case no event id is
            # here returned
            if last_event_id:
                server.room_send_read_marker(room_buffer.room.room_id,
                                             last_event_id)
                room_buffer.last_read_event = last_event_id

        if not room_buffer.members_fetched:
            room_id = room_buffer.room.room_id
            server.get_joined_members(room_id)

        # The buffer is empty and we are seeing it for the first time.
        # Let us fetch some messages from the room history so it doesn't feel so
        # empty.
        if room_buffer.first_view and room_buffer.weechat_buffer.num_lines < 10:
            # TODO we may want to fetch 10 - num_lines messages here for
            # consistency reasons.
            server.room_get_messages(room_buffer.room.room_id)

        break

    return W.WEECHAT_RC_OK
コード例 #17
0
def matrix_bar_item_buffer_modes(data, item, window, buffer, extra_info):
    # pylint: disable=unused-argument
    for server in SERVERS.values():
        if buffer in server.buffers.values():
            room_id = key_from_value(server.buffers, buffer)
            room = server.rooms[room_id]
            modes = []

            if room.encrypted:
                modes.append("�")

            if room.backlog_pending:
                modes.append("�")

            return "".join(modes)

    return ""
コード例 #18
0
def typing_notification_cb(data, signal, buffer_ptr):
    """Send out typing notifications if the user is typing.

    This function is called every time the input text is changed.
    It checks if we are on a buffer we own, and if we are sends out a typing
    notification if the room is configured to send them out.
    """
    for server in SERVERS.values():
        room_buffer = server.find_room_from_ptr(buffer_ptr)
        if room_buffer:
            server.room_send_typing_notice(room_buffer)
            return W.WEECHAT_RC_OK

        if buffer_ptr == server.server_buffer:
            return W.WEECHAT_RC_OK

    return W.WEECHAT_RC_OK
コード例 #19
0
def matrix_bar_item_lag(data, item, window, buffer, extra_info):
    # pylint: disable=unused-argument
    for server in SERVERS.values():
        if (buffer in server.buffers.values() or
                buffer == server.server_buffer):
            if server.lag >= 500:
                color = W.color("irc.color.item_lag_counting")
                if server.lag_done:
                    color = W.color("irc.color.item_lag_finished")

                lag = "{0:.3f}" if round(server.lag) < 1000 else "{0:.0f}"
                lag_string = "Lag: {color}{lag}{ncolor}".format(
                    lag=lag.format((server.lag / 1000)),
                    color=color,
                    ncolor=W.color("reset"))
                return lag_string
            return ""

    return ""
コード例 #20
0
def matrix_redact_command_cb(data, buffer, args):
    for server in SERVERS.values():
        if buffer in server.buffers.values():
            room_id = key_from_value(server.buffers, buffer)

            matches = re.match(r"(\d+)(:\".*\")? ?(.*)?", args)

            if not matches:
                message = (
                    "{prefix}matrix: Invalid command arguments (see /help redact)"
                ).format(prefix=W.prefix("error"))
                W.prnt("", message)
                return W.WEECHAT_RC_ERROR

            line_string, _, reason = matches.groups()
            line = int(line_string)

            event_id = event_id_from_line(buffer, line)

            if not event_id:
                message = ("{prefix}matrix: No such message with number "
                           "{number} found").format(prefix=W.prefix("error"),
                                                    number=line)
                W.prnt("", message)
                return W.WEECHAT_RC_OK

            message = MatrixRedactMessage(server.client,
                                          room_id=room_id,
                                          event_id=event_id,
                                          reason=reason)
            server.send_or_queue(message)

            return W.WEECHAT_RC_OK

        elif buffer == server.server_buffer:
            message = ("{prefix}matrix: command \"redact\" must be "
                       "executed on a Matrix channel buffer").format(
                           prefix=W.prefix("error"))
            W.prnt("", message)
            return W.WEECHAT_RC_OK

    return W.WEECHAT_RC_OK
コード例 #21
0
def matrix_command_pgup_cb(data, buffer, command):
    # TODO the highlight status of a line isn't allowed to be updated/changed
    # via hdata, therefore the highlight status of a messages can't be
    # reoredered this would need to be fixed in weechat
    # TODO we shouldn't fetch and print out more messages than
    # max_buffer_lines_number or older messages than max_buffer_lines_minutes
    for server in SERVERS.values():
        if buffer in server.buffers.values():
            window = W.window_search_with_buffer(buffer)

            first_line_displayed = bool(
                W.window_get_integer(window, "first_line_displayed"))

            if first_line_displayed:
                room_id = key_from_value(server.buffers, buffer)
                matrix_fetch_old_messages(server, room_id)

            return W.WEECHAT_RC_OK

    return W.WEECHAT_RC_OK
コード例 #22
0
ファイル: utils.py プロジェクト: tylerjw/weechat-matrix
def server_buffer_merge(buffer):
    if OPTIONS.look_server_buf == ServerBufferType.MERGE_CORE:
        num = W.buffer_get_integer(W.buffer_search_main(), "number")
        W.buffer_unmerge(buffer, num + 1)
        W.buffer_merge(buffer, W.buffer_search_main())
    elif OPTIONS.look_server_buf == ServerBufferType.MERGE:
        if SERVERS:
            first = None
            for server in SERVERS.values():
                if server.server_buffer:
                    first = server.server_buffer
                    break
            if first:
                num = W.buffer_get_integer(W.buffer_search_main(), "number")
                W.buffer_unmerge(buffer, num + 1)
                if buffer is not first:
                    W.buffer_merge(buffer, first)
    else:
        num = W.buffer_get_integer(W.buffer_search_main(), "number")
        W.buffer_unmerge(buffer, num + 1)
コード例 #23
0
def buffer_switch_cb(_, _signal, buffer_ptr):
    """Do some buffer operations when we switch buffers.

    This function is called every time we switch a buffer. The pointer of
    the new buffer is given to us by weechat.

    If it is one of our room buffers we check if the members for the room
    aren't fetched and fetch them now if they aren't.

    Read receipts are send out from here as well.
    """
    for server in SERVERS.values():
        if buffer_ptr == server.server_buffer:
            return W.WEECHAT_RC_OK

        if buffer_ptr not in server.buffers.values():
            continue

        room_buffer = server.find_room_from_ptr(buffer_ptr)
        if not room_buffer:
            continue

        if room_buffer.should_send_read_marker:
            event_id = room_buffer.last_event_id

            # A buffer may not have any events, in that case no event id is
            # here returned
            if event_id:
                server.room_send_read_marker(room_buffer.room.room_id,
                                             event_id)
                room_buffer.last_read_event = event_id

        if room_buffer.members_fetched:
            return W.WEECHAT_RC_OK

        room_id = room_buffer.room.room_id
        server.get_joined_members(room_id)

        break

    return W.WEECHAT_RC_OK
コード例 #24
0
def matrix_user_completion_cb(data, completion_item, buffer, completion):
    def add_user(completion, user):
        W.hook_completion_list_add(completion, user, 0,
                                   W.WEECHAT_LIST_POS_SORT)

    for server in SERVERS.values():
        if buffer == server.server_buffer:
            return W.WEECHAT_RC_OK

        room_buffer = server.find_room_from_ptr(buffer)

        if not room_buffer:
            continue

        users = room_buffer.room.users

        users = [user[1:] for user in users]

        for user in users:
            add_user(completion, user)

    return W.WEECHAT_RC_OK
コード例 #25
0
def matrix_command_join_cb(data, buffer, command):
    def join(server, args):
        split_args = args.split(" ", 1)

        # TODO handle join for non public rooms
        if len(split_args) != 2:
            message = ("{prefix}Error with command \"/join\" (help on "
                       "command: /help join)").format(prefix=W.prefix("error"))
            W.prnt("", message)
            return

        _, room_id = split_args
        message = MatrixJoinMessage(server.client, room_id=room_id)
        server.send_or_queue(message)

    for server in SERVERS.values():
        if buffer in server.buffers.values():
            join(server, command)
            return W.WEECHAT_RC_OK_EAT
        elif buffer == server.server_buffer:
            join(server, command)
            return W.WEECHAT_RC_OK_EAT

    return W.WEECHAT_RC_OK
コード例 #26
0
def matrix_command_topic_cb(data, buffer, command):
    for server in SERVERS.values():
        if buffer in server.buffers.values():
            topic = None
            room_id = key_from_value(server.buffers, buffer)
            split_command = command.split(' ', 1)

            if len(split_command) == 2:
                topic = split_command[1]

            if not topic:
                room = server.rooms[room_id]
                if not room.topic:
                    return W.WEECHAT_RC_OK

                if room.is_named():
                    message = ('{prefix}Topic for {color}{room}{ncolor} is '
                               '"{topic}"').format(
                                   prefix=W.prefix("network"),
                                   color=W.color("chat_buffer"),
                                   ncolor=W.color("reset"),
                                   room=room.named_room_name(),
                                   topic=room.topic)
                else:
                    message = ('{prefix}Topic is "{topic}"').format(
                        prefix=W.prefix("network"), topic=room.topic)

                date = int(time.time())
                topic_date = room.topic_date.strftime("%a, %d %b %Y "
                                                      "%H:%M:%S")

                tags = "matrix_topic,log1"
                W.prnt_date_tags(buffer, date, tags, message)

                # TODO the nick should be colored

                # TODO we should use the display name as well as
                # the user name here
                message = ("{prefix}Topic set by {author} on "
                           "{date}").format(prefix=W.prefix("network"),
                                            author=room.topic_author,
                                            date=topic_date)
                W.prnt_date_tags(buffer, date, tags, message)

                return W.WEECHAT_RC_OK_EAT

            message = MatrixTopicMessage(server.client,
                                         room_id=room_id,
                                         topic=topic)
            server.send_or_queue(message)

            return W.WEECHAT_RC_OK_EAT

        elif buffer == server.server_buffer:
            message = ("{prefix}matrix: command \"topic\" must be "
                       "executed on a Matrix channel buffer").format(
                           prefix=W.prefix("error"))
            W.prnt(buffer, message)
            return W.WEECHAT_RC_OK_EAT

    return W.WEECHAT_RC_OK