Example #1
0
    def __init__(self, socket_, floodcontrol_mode, floodcontrol_config):
        super().__init__(socket_)
        self.output_raw = logging.getLogger("raw.output")

        self.flood_control = FloodControlManager(floodcontrol_mode,
                                                 floodcontrol_config)
Example #2
0
    def __init__(self, socket_,
                 floodcontrol_mode, floodcontrol_config):
        super().__init__(socket_)
        self.output_raw = logging.getLogger("raw.output")

        self.flood_control = FloodControlManager(floodcontrol_mode, floodcontrol_config)
Example #3
0
class SendSocket(SocketThread):
    # These coefficients are used in calculating
    # the wait time between sending each message.
    _coefficient_a, _coefficient_b, _base_c = None, None, None

    def __init__(self, socket_, floodcontrol_mode, floodcontrol_config):
        super().__init__(socket_)
        self.output_raw = logging.getLogger("raw.output")

        self.flood_control = FloodControlManager(floodcontrol_mode,
                                                 floodcontrol_config)

    def run(self):
        messages_sent = 0
        last_time = time()

        last_send = 0
        accumulated_wait_time = 0

        while not self._stop:
            #prefix, command, args, message = self._buffer.get()
            #msg = self._pack_msg(prefix, command, args, message) + "\r\n"

            msg = self._buffer.get()
            self.output_raw.info("%s", msg)
            self._socket.send(msg)

            self._buffer.task_done()
            """
            # The wait time is calculated based on how many
            # messages have been sent.
            # To reduce the wait time after a longer while of
            # no messages being sent, messages_sent will be
            # reduced for every 2 seconds that have passed.
            messages_sent += 1
            now = time()
            diff = now - last_time

            wait_time = self._calc_time(messages_sent)

            if diff > wait_time:
                messages_sent -= (diff // 2)*1
                if messages_sent < 0:
                    messages_sent = 0

                wait_time = self._calc_time(messages_sent)
            last_time = now"""
            wait_time = self.flood_control.calculate_delay(msg)

            print("Wait time:", wait_time)

            sleep(wait_time)

    @staticmethod
    def _pack_msg(prefix, command, arguments, message):
        msg_assembly = []

        if prefix is not None:
            msg_assembly.append(":" + prefix)
        msg_assembly.append(command)

        msg_assembly.extend(arguments)

        if message is not None:
            msg_assembly.append(":" + message)

        msg = " ".join(msg_assembly)
        return msg

    def send_msg(self, command, arguments=tuple(), message=None, prefix=None):
        if len(arguments) > 15:
            raise TooManyArgumentsError(arguments)

        for arg in arguments:
            # Arguments cannot contain space characters. To prevent the irc server
            # from interpreting our message incorrectly, we will raise an exception
            # right here.
            if " " in arg:
                raise SpaceInArgumentError(arguments, arg)

        msg = self._pack_msg(prefix, command, arguments, message) + "\r\n"
        encoded_msg = msg.encode(self.encoding)

        if len(encoded_msg) > 512:
            raise MessageLimitExceededError(encoded_msg)

        self._buffer.put(encoded_msg)

    # Using this function, a list of arguments will be partitioned into several
    # lists so that each list contains no more than arg_limit arguments, and the length
    # of all arguments in a single list do not exceed the message length limit.
    # If a single argument exceeds the length limit, it will be put into its own list,
    # which can
    def partition_arguments(self, arguments, arg_limit=15, msg_limit=400):
        partitions = []

        current_partition = []
        current_size = 0

        for arg in arguments:
            bytes_repr = arg.encode(self.encoding)

            if (current_size + len(bytes_repr) + 1 > msg_limit
                    or len(current_partition) + 1 > arg_limit):

                partitions.append(current_partition)

                current_partition = []
                current_size = 0

            current_partition.append(arg)
            current_size += len(bytes_repr) + 1

        if len(current_partition) > 0:
            partitions.append(current_partition)

        return partitions

    def set_wait_coefficient(self, a, b, c):
        self._coefficient_a, self._coefficient_b, self._base_c = a, b, c

    def _calc_time(self, messages_sent):
        n = messages_sent
        result = self._coefficient_a * (
            n**2) + self._coefficient_b * n + self._base_c

        # base_c specifies the minimum wait time.
        # Also, there is no point in a wait time of more than 2 seconds
        # because 2 seconds is the sweet spot for how long the bot
        # should wait between sending messages.
        if result < self._base_c:
            result = self._base_c
        if result > 2:
            result = 2

        return result
Example #4
0
class SendSocket(SocketThread):
    # These coefficients are used in calculating
    # the wait time between sending each message.
    _coefficient_a, _coefficient_b, _base_c = None, None, None

    def __init__(self, socket_,
                 floodcontrol_mode, floodcontrol_config):
        super().__init__(socket_)
        self.output_raw = logging.getLogger("raw.output")

        self.flood_control = FloodControlManager(floodcontrol_mode, floodcontrol_config)

    def run(self):
        messages_sent = 0
        last_time = time()

        last_send = 0
        accumulated_wait_time = 0

        while not self._stop:
            #prefix, command, args, message = self._buffer.get()
            #msg = self._pack_msg(prefix, command, args, message) + "\r\n"

            msg = self._buffer.get()
            self.output_raw.info("%s", msg)
            self._socket.send(msg)

            self._buffer.task_done()
            """
            # The wait time is calculated based on how many
            # messages have been sent.
            # To reduce the wait time after a longer while of
            # no messages being sent, messages_sent will be
            # reduced for every 2 seconds that have passed.
            messages_sent += 1
            now = time()
            diff = now - last_time

            wait_time = self._calc_time(messages_sent)

            if diff > wait_time:
                messages_sent -= (diff // 2)*1
                if messages_sent < 0:
                    messages_sent = 0

                wait_time = self._calc_time(messages_sent)
            last_time = now"""
            wait_time = self.flood_control.calculate_delay(msg)

            print("Wait time:", wait_time)

            sleep(wait_time)

    @staticmethod
    def _pack_msg(prefix, command, arguments, message):
        msg_assembly = []

        if prefix is not None:
            msg_assembly.append(":"+prefix)
        msg_assembly.append(command)

        msg_assembly.extend(arguments)

        if message is not None:
            msg_assembly.append(":"+message)

        msg = " ".join(msg_assembly)
        return msg

    def send_msg(self, command, arguments=tuple(), message=None, prefix=None):
        if len(arguments) > 15:
            raise TooManyArgumentsError(arguments)

        for arg in arguments:
            # Arguments cannot contain space characters. To prevent the irc server
            # from interpreting our message incorrectly, we will raise an exception
            # right here.
            if " " in arg:
                raise SpaceInArgumentError(arguments, arg)

        msg = self._pack_msg(prefix, command, arguments, message) + "\r\n"
        encoded_msg = msg.encode(self.encoding)

        if len(encoded_msg) > 512:
            raise MessageLimitExceededError(encoded_msg)

        self._buffer.put(encoded_msg)


    # Using this function, a list of arguments will be partitioned into several
    # lists so that each list contains no more than arg_limit arguments, and the length
    # of all arguments in a single list do not exceed the message length limit.
    # If a single argument exceeds the length limit, it will be put into its own list,
    # which can
    def partition_arguments(self, arguments, arg_limit=15, msg_limit=400):
        partitions = []

        current_partition = []
        current_size = 0

        for arg in arguments:
            bytes_repr = arg.encode(self.encoding)

            if (current_size + len(bytes_repr) + 1 > msg_limit
                    or len(current_partition) + 1 > arg_limit):

                partitions.append(current_partition)

                current_partition = []
                current_size = 0

            current_partition.append(arg)
            current_size += len(bytes_repr) + 1

        if len(current_partition) > 0:
            partitions.append(current_partition)

        return partitions


    def set_wait_coefficient(self, a, b, c):
        self._coefficient_a, self._coefficient_b, self._base_c = a, b, c

    def _calc_time(self, messages_sent):
        n = messages_sent
        result = self._coefficient_a*(n**2) + self._coefficient_b*n + self._base_c

        # base_c specifies the minimum wait time.
        # Also, there is no point in a wait time of more than 2 seconds
        # because 2 seconds is the sweet spot for how long the bot
        # should wait between sending messages.
        if result < self._base_c:
            result = self._base_c
        if result > 2:
            result = 2

        return result