diff --git a/sopel/bot.py b/sopel/bot.py index 7e0fefc866..c43773f30c 100644 --- a/sopel/bot.py +++ b/sopel/bot.py @@ -305,18 +305,32 @@ def say(self, text, recipient, max_messages=1): recipient_id = Identifier(recipient) - if recipient_id not in self.stack: - self.stack[recipient_id] = [] - elif self.stack[recipient_id]: - elapsed = time.time() - self.stack[recipient_id][-1][0] - if elapsed < 3: - penalty = float(max(0, len(text) - 40)) / 70 - wait = 0.8 + penalty - if elapsed < wait: - time.sleep(wait - elapsed) + reciprec = self.stack.get(recipient_id) + if not reciprec: + reciprec = self.stack[recipient_id] = { + 'messages': [], + 'burst': self.config.core.bucket_burst_tokens, + } + + if not reciprec['burst']: + elapsed = time.time() - reciprec['messages'][-1][0] + reciprec['burst'] = min( + self.config.core.bucket_burst_tokens, + int(elapsed) * self.config.core.bucket_refill_rate) + + if not reciprec['burst']: + elapsed = time.time() - reciprec['messages'][-1][0] + penalty = float(max(0, len(text) - 50)) / 70 +<<<<<<< HEAD + wait = self.config.core.bucket_empty_wait + penalty +======= + wait = min(self.config.core.flood_empty_wait + penalty, 2) # Maximum wait time is 2 sec +>>>>>>> dd3c407d... Update bot.py + if elapsed < wait: + time.sleep(wait - elapsed) # Loop detection - messages = [m[1] for m in self.stack[recipient_id][-8:]] + messages = [m[1] for m in reciprec['messages'][-8:]] # If what we about to send repeated at least 5 times in the # last 2 minutes, replace with '...' @@ -327,8 +341,9 @@ def say(self, text, recipient, max_messages=1): return self.write(('PRIVMSG', recipient), text) - self.stack[recipient_id].append((time.time(), self.safe(text))) - self.stack[recipient_id] = self.stack[recipient_id][-10:] + reciprec['burst'] = max(0, reciprec['burst'] - 1) + reciprec['messages'].append((time.time(), self.safe(text))) + reciprec['messages'] = reciprec['messages'][-10:] finally: self.sending.release() # Now that we've sent the first part, we need to send the rest. Doing diff --git a/sopel/config/core_section.py b/sopel/config/core_section.py index b08fdbcf13..ec96b871f1 100644 --- a/sopel/config/core_section.py +++ b/sopel/config/core_section.py @@ -216,3 +216,16 @@ def homedir(self): verify_ssl = ValidatedAttribute('verify_ssl', bool, default=True) """Whether to require a trusted SSL certificate for SSL connections.""" + + bucket_burst_tokens = ValidatedAttribute('bucket_burst_tokens', int, + default=4) + """How many messages can be sent in burst mode.""" + + bucket_refill_rate = ValidatedAttribute('bucket_refill_rate', int, + default=1) + """How many tokens/second to add to the token bucket.""" + + bucket_empty_wait = ValidatedAttribute('bucket_empty_wait', float, + default=0.7) + """How long to wait before sending a messaging when not in burst + mode."""