diff options
Diffstat (limited to 'http2irc.py')
| -rw-r--r-- | http2irc.py | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/http2irc.py b/http2irc.py index da47dc2..5294923 100644 --- a/http2irc.py +++ b/http2irc.py @@ -104,7 +104,7 @@ class Config(dict): except (ValueError, AssertionError) as e: raise InvalidConfig('Invalid log format: parsing failed') from e if 'irc' in obj: - if any(x not in ('host', 'port', 'ssl', 'family', 'nick', 'real', 'certfile', 'certkeyfile') for x in obj['irc']): + if any(x not in ('host', 'port', 'ssl', 'family', 'nick', 'real', 'certfile', 'certkeyfile', 'sendratelimit') for x in obj['irc']): raise InvalidConfig('Unknown key found in irc section') if 'host' in obj['irc'] and not isinstance(obj['irc']['host'], str): #TODO: Check whether it's a valid hostname raise InvalidConfig('Invalid IRC host') @@ -126,6 +126,9 @@ class Config(dict): raise InvalidConfig('Invalid IRC nick: NICK command too long') if 'real' in obj['irc'] and not isinstance(obj['irc']['real'], str): raise InvalidConfig('Invalid IRC realname') + if 'sendratelimit' in obj['irc']: + if not isinstance(obj['irc']['sendratelimit'], (int, float)): + raise InvalidConfig('Invalid ratelimit: must be numeric') if len(IRCClientProtocol.user_command(obj['irc']['nick'], obj['irc']['real'])) > 510: raise InvalidConfig('Invalid IRC nick/realname combination: USER command too long') if ('certfile' in obj['irc']) != ('certkeyfile' in obj['irc']): @@ -225,7 +228,7 @@ class Config(dict): # Default values finalObj = { 'logging': {'level': 'INFO', 'format': '{asctime} {levelname} {name} {message}'}, - 'irc': {'host': 'irc.hackint.org', 'port': 6697, 'ssl': 'yes', 'family': 0, 'nick': 'h2ibot', 'real': 'I am an http2irc bot.', 'certfile': None, 'certkeyfile': None}, + 'irc': {'host': 'irc.hackint.org', 'port': 6697, 'ssl': 'yes', 'family': 0, 'nick': 'h2ibot', 'real': 'I am an http2irc bot.', 'certfile': None, 'certkeyfile': None, 'sendratelimit': 1 }, 'web': {'host': '127.0.0.1', 'port': 8080, 'maxrequestsize': 1048576}, 'maps': {} } @@ -484,9 +487,10 @@ class IRCClientProtocol(asyncio.Protocol): data = t.result() self.logger.debug(f'Got {data!r} from send queue') now = time.time() - if self.lastSentTime is not None and now - self.lastSentTime < 1: + sendTimeLimit = 1 / self.config['irc']['sendratelimit'] + if self.lastSentTime is not None and now - self.lastSentTime < sendTimeLimit: self.logger.debug(f'Rate limited') - await wait_cancel_pending({asyncio.create_task(self.connectionClosedEvent.wait())}, timeout = self.lastSentTime + 1 - now) + await wait_cancel_pending({asyncio.create_task(self.connectionClosedEvent.wait())}, timeout = self.lastSentTime + sendTimeLimit - now) if self.connectionClosedEvent.is_set(): break time_ = self._direct_send(data) @@ -871,7 +875,11 @@ class IRCClient: self._protocol = None def update_config(self, config): - needReconnect = self.config['irc'] != config['irc'] + ircReconnectNeededKeys = [ + 'host', 'port', 'ssl', 'family', + 'nick', 'real', 'certfile', 'certkeyfile', + ] + needReconnect = True in [self.config['irc'][key] != config['irc'][key] for key in ircReconnectNeededKeys] self.config = config if self._transport: # if currently connected: if needReconnect: @@ -879,6 +887,7 @@ class IRCClient: else: self.channels = {map_['ircchannel'] for map_ in config['maps'].values()} self._protocol.update_channels(self.channels) + self._protocol.config['irc'] = config['irc'] def _get_ssl_context(self): ctx = SSL_CONTEXTS[self.config['irc']['ssl']] |
