diff --git a/CHANGELOG.md b/CHANGELOG.md index b1f2010..9db44f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,49 +2,60 @@ All notable changes to this project will be documented in this file. If there is a `Changed` section please read carefully, as this often means that you will need to adapt your `config.yml`, otherwise the bot might fail to start. +## [1.2.2] - 2022-08-13 + +### Changed 1.2.2 + +* The message queue is only queried when the Init button is pressed +* Further code optimization + +### Fixed 1.2.2 + +* Minor fixes + ## [1.2.1] - 2022-08-13 -### Changed +### Changed 1.2.1 - * Reworked internal code structure +* Reworked internal code structure -### Fixed +### Fixed 1.2.1 - * Publish vote info in chat when reloading config was not working when TTS was disabled - * Casting votes was allowed for broadcaster and mods only +* Publish vote info in chat when reloading config was not working when TTS was disabled +* Casting votes was allowed for broadcaster and mods only ## [1.2.0] - 2022-08-13 ### Added - * `!random` feature (see README.md for details) +* `!random` feature (see README.md for details) -### Changed +### Changed 1.2.0 - * The vote result will be read out +* The vote result will be read out -### Fixed +### Fixed 1.2.0 - * Improved handling of missing config values. +* Improved handling of missing config values ## [1.1.0] - 2022-08-12 -### Added +### Added 1.1.0 - * `!quickvote` feature (see README.md for details) - * `!ping` command added - * Configoption to start TTS in disabled mode - * OAuth-Token generator - * Webbrowser autostart +* `!quickvote` feature (see README.md for details) +* `!ping` command added +* Configoption to start TTS in disabled mode +* OAuth-Token generator +* Webbrowser autostart -### Changed +### Changed 1.1.0 - * You need to review your `config.yml` as there a new config values added. - * The bot replies with a chat message when `!ton` or `!toff` is used +* You need to review your `config.yml` as there a new config values added. +* The bot replies with a chat message when `!ton` or `!toff` is used -### Fixed +### Fixed 1.1.0 - * Improved error handling +* Improved error handling ## [1.0.0] - 2022-08-11 diff --git a/README.md b/README.md index 57725af..d8ebce7 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ By using Javascript for the actual TTS part it's not only very easy to access th Adapt `config.yml` to your needs. Example: -``` +``` lang=yaml irc: channel: "#gpkvt" username: "ttsbot" @@ -82,11 +82,11 @@ whitelist: ##### irc - * `channel`: Channel you want to monitor (e.g. #gpkvt) - * `username`: The bots username (e.g. gpkvt) - * `oauth_token`: The bots OAUTH-Token (e.g. oauth:ohkoace0wooghue8she9xaN0nooSau) - * `server`: Twitch IRC server to be used (default should be fine) - * `clearmsg_timeout`: Time to wait for an moderator to delete a message, before it's added to the TTS queue +* `channel`: Channel you want to monitor (e.g. #gpkvt) +* `username`: The bots username (e.g. gpkvt) +* `oauth_token`: The bots OAUTH-Token (e.g. oauth:ohkoace0wooghue8she9xaN0nooSau) +* `server`: Twitch IRC server to be used (default should be fine) +* `clearmsg_timeout`: Time to wait for an moderator to delete a message, before it's added to the TTS queue You can generate your `oauth_token` by leaving the value empty when starting `tts.exe/tts.py`. The integrated webserver will then provide an OAuth-Generator. Due to limitations to the `redirect_url` parameter used by twitch, this is only possible if you use Port `8080` or `80` as `http:bind`. If you use a different port, you will need to use another [Twitch OAuth Generator](https://html.duckduckgo.com/html/?q=twitch+oauth+token+generator). The bot will need `chat:edit` and `chat:read` permissions. @@ -94,36 +94,36 @@ Please note that the `oauth_token` is valid for approximately 60 days. If it bec ##### http - * `port`: Internal Webserver Port to listen to (e.g. 8080) - * `bind`: Interface/IP to bind server to (e.g. localhost) +* `port`: Internal Webserver Port to listen to (e.g. 8080) +* `bind`: Interface/IP to bind server to (e.g. localhost) ##### bot - * `start_enabled`: Enable the bot on start? If `False` you need to use `!ton` first to make TTS work. - * `subonly`: If `True` only Subs can use TTS - * `modonly`: If `True` only Mods can use TTS - * `message_length`: Maximum allowed message length for TTS +* `start_enabled`: Enable the bot on start? If `False` you need to use `!ton` first to make TTS work. +* `subonly`: If `True` only Subs can use TTS +* `modonly`: If `True` only Mods can use TTS +* `message_length`: Maximum allowed message length for TTS ##### messages - * `toff`: The bots reply when `!toff` is used. - * `ton`: The bots reply when `!ton` is used. - * `too_long`: The bots reply if message exceeds `message_length` - * `disabled`: The bots reply if TTS is disabled - * `denied`: The bots reply if the user is not allowed to use TTS - * `subonly`: The bots reply if `subonly` is active and the user isn't one. - * `whitelist`: The bots reply if `whitelist` is set and user isn't on the list. - * `ready`: The bots init message - * `says`: Prefix to add between username and message - * `votestart`: Message when a quickvote is started. - * `voteend`: Message if a quickvote ends. - * `votenobody`: Message if quickvote ends, but nobody has voted. - * `voteresult`: Prefix for the result (will be read out) - * `votes`: Suffix to vote count. +* `toff`: The bots reply when `!toff` is used. +* `ton`: The bots reply when `!ton` is used. +* `too_long`: The bots reply if message exceeds `message_length` +* `disabled`: The bots reply if TTS is disabled +* `denied`: The bots reply if the user is not allowed to use TTS +* `subonly`: The bots reply if `subonly` is active and the user isn't one. +* `whitelist`: The bots reply if `whitelist` is set and user isn't on the list. +* `ready`: The bots init message +* `says`: Prefix to add between username and message +* `votestart`: Message when a quickvote is started. +* `voteend`: Message if a quickvote ends. +* `votenobody`: Message if quickvote ends, but nobody has voted. +* `voteresult`: Prefix for the result (will be read out) +* `votes`: Suffix to vote count. ##### log - * `level`: The loglevel, valid values are: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` +* `level`: The loglevel, valid values are: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` Do not use `DEBUG` in a production environment. @@ -139,7 +139,7 @@ You can add a whitelist section to `config.yml`, a whitelist will override any o A whitelist looks as follows: -``` +``` lang=yaml whitelist: - gpkvt - foo @@ -152,7 +152,7 @@ Please note: Usernames MUST be lowercase. ### Executing program -Execute `tts.exe` (or `tts.py` if you have Python installed), open the TTS webpage in your browser (the URL depends on your `bind` and `port` configuration, usually it's just http://localhost). Click the `Init` button at the button of the TTS webpage (you should hear `Init complete`). +Execute `tts.exe` (or `tts.py` if you have Python installed), open the TTS webpage in your browser (the URL depends on your `bind` and `port` configuration, usually it's just `http://localhost`). Click the `Init` button at the button of the TTS webpage (you should hear `Init complete`). Connect to the configured Twitch channel and send a message starting with `!tts`. After a few seconds (depending on your `clearmsg_timeout` config), the message should be read. @@ -160,11 +160,11 @@ Connect to the configured Twitch channel and send a message starting with `!tts` Additional commands (broadcaster and mods only) are: - * `!ping`: Check if bot is alive (the bot should reply: `Pong!`) - * `!toff`: Turn TTS off (will also empty the current TTS queue) - * `!ton`: Turn TTS back on - * `!dtts `: Disable TTS for the given user - * `!ptts `: Allow TTS for the given user +* `!ping`: Check if bot is alive (the bot should reply: `Pong!`) +* `!toff`: Turn TTS off (will also empty the current TTS queue) +* `!ton`: Turn TTS back on +* `!dtts `: Disable TTS for the given user +* `!ptts `: Allow TTS for the given user ### Additional features @@ -180,10 +180,10 @@ The `!random` command will read a random line from a file called `random.txt`. Y If you prefer to build your own `tts.exe` instead of using the shipped one, you can do as follows: - * Install Python 3 - * Install pyinstaller: `pip install pyinstaller` - * Install the required dependencies: `pip install -r requirements.txt -v` - * Create the executeable: `pyinstaller --onefile tts.py` +* Install Python 3 +* Install pyinstaller: `pip install pyinstaller` +* Install the required dependencies: `pip install -r requirements.txt -v` +* Create the executeable: `pyinstaller --onefile tts.py` ## Voices @@ -211,9 +211,9 @@ This project is licensed under the GPLv3 License - see [LICENSE](https://gitlab. ### Ideas and Testing -* [GERBrowny and community](https://www.twitch.tv/gerbrowny/) ![](https://static-cdn.jtvnw.net/emoticons/v2/303172270/static/light/1.0) -* [DerZugger and community](https://www.twitch.tv/derzugger/) ![](https://static-cdn.jtvnw.net/emoticons/v2/302400142/static/light/1.0) -* [Timmeh74 and community](https://www.twitch.tv/timmeh74/) ![](https://static-cdn.jtvnw.net/emoticons/v2/300192675/static/light/1.0) +* [GERBrowny and community](https://www.twitch.tv/gerbrowny/) ![Emote](https://static-cdn.jtvnw.net/emoticons/v2/303172270/static/light/1.0) +* [DerZugger and community](https://www.twitch.tv/derzugger/) ![Emote](https://static-cdn.jtvnw.net/emoticons/v2/302400142/static/light/1.0) +* [Timmeh74 and community](https://www.twitch.tv/timmeh74/) ![Emote](https://static-cdn.jtvnw.net/emoticons/v2/300192675/static/light/1.0) ### Libraries diff --git a/tts.js b/tts.js index d9a7fce..92dbb22 100644 --- a/tts.js +++ b/tts.js @@ -34,6 +34,7 @@ document.querySelector("#start").addEventListener("click", () => { speech.text = "Init complete"; window.speechSynthesis.speak(speech); $("#start").hide(); + init(); }); document.querySelector("#pause").addEventListener("click", () => { @@ -54,7 +55,7 @@ function sleep(ms) { reload = true; -$(document).ready(function() { +function init() { setInterval(function(){ if (reload) { $.ajax({ @@ -89,4 +90,4 @@ $(document).ready(function() { }); } }, 1000); -}); +}; diff --git a/tts.py b/tts.py index 441be3a..bef7f15 100644 --- a/tts.py +++ b/tts.py @@ -95,6 +95,277 @@ class IRC: """ self.irc.send(bytes("PRIVMSG "+channel+" :"+user+" "+msg+"\r\n", "UTF-8")) + def resp_ping(self): + """ Respond to PING """ + logging.debug('PING received') + self.irc.send(bytes('PONG :tmi.twitch.tv\r\n', "UTF-8")) + + def resp_notice(self, resp): + """ Respond to NOTICE """ + if 'Login authentication failed' in resp: + try: + raise RuntimeError() + except RuntimeError: + logging.exception('Login failed, please check your credentials and try again.') + sys.exit(251) + + def resp_clearmsg(self, resp): + """ Respond to CLEARMSG """ + logging.info('CLEARMSG received') + msgid = False + + global msg_queue_raw # pylint: disable=global-statement,invalid-name + filtered_msg_queue = [] + + tags = resp.split(';') + for tag in tags: + if "target-msg-id=" in tag: + msgid = tag.rsplit('target-msg-id=',1)[1] + logging.debug('Trying to suppress message') + logging.debug(msgid) + + for msg in list(msg_queue_raw): + if msg['msgid'] == msgid: + logging.info('Suppressing message %s', msgid) + else: + filtered_msg_queue.append(msg) + + msg_queue_raw = filtered_msg_queue + + def resp_privmsg(self, resp): + """ Respond to PRIVMSG """ + logging.debug('PRIVMSG received') + + tags = self.get_tags(resp) + message = self.get_message(resp) + + user = tags['user'] + msg = message['message'] + msglen = message['length'] + + logging.debug('Msg: %s', msg) + logging.debug('Msg length: %s', msglen) + logging.debug('Deny List:') + logging.debug(self.tts_denied) + + self.priviledged_commands(message, tags) + + if msg.startswith('#') and self.quickvote_status is True: + logging.info('Quickvote: Cast detected') + self.pollcount += 1 + self.poll[user] = msg.lower() + logging.debug(self.poll) + + if msg.startswith('!tts'): + logging.info('!tts command detected') + self.tts_command(message, tags) + + def get_tags(self, resp): + """ Strip tags from response """ + + tags = resp.split(';') + for tag in tags: + if tag.startswith('badges='): + badges = tag.rsplit('badges=',1)[1] + if tag.startswith('subscriber='): + subscriber = tag.rsplit('subscriber=',1)[1] + logging.debug('Subscriber: %s', subscriber) + if tag.startswith('id='): + msgid = tag.rsplit('id=',1)[1] + logging.debug('Message ID: %s', msgid) + if tag.startswith('display-name='): + user = tag.rsplit('display-name=',1)[1].lower() + logging.debug('Username: %s', user) + + tags = {} + tags['badges'] = badges + tags['subscriber'] = subscriber + tags['msgid'] = msgid + tags['user'] = user + + return tags + + def get_message(self, resp): + """ Process message """ + + msg = {} + msg['message'] = resp.rsplit('PRIVMSG #',1)[1].split(':',1)[1].replace('\r\n','') + msg['length'] = len(msg['message']) + + return msg + + def priviledged_commands(self, message, tags): + """ Process priviledged commands """ + + msg = message['message'] + badges = tags['badges'] + user = tags['user'] + + if 'broadcaster' in badges or 'moderator' in badges: + if msg.startswith('!ping'): + logging.debug("Ping check received.") + self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), "Pong!") + + elif msg.startswith('!dtts'): + logging.debug("!dtts command detected") + self.Commands.dtts(self, msg) + + elif msg.startswith('!random'): + logging.info('!random command detected') + self.Commands.random(self, msg) + + elif msg.startswith('!quickvote'): + logging.info("!quickvote command detected") + self.Commands.quickvote(self, msg) + + elif msg.startswith('!ptts'): + logging.debug("!ptts command detected") + self.Commands.ptts(self, msg) + + elif msg.startswith('!toff'): + logging.info('TTS is now turned off') + msg_queue.clear() + msg_queue_raw.clear() + self.tts_status = False + self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['TOFF']) + + elif msg.startswith('!ton'): + logging.info('TTS is now turned on') + msg_queue.clear() + msg_queue_raw.clear() + self.tts_status = True + self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['TON']) + + def check_subonly(self, tags): + """ subonly """ + + if not conf['IRC_SUBONLY']: + return False + + subscriber = tags['subscriber'] + badges = tags['badges'] + user = tags['user'] + + if subscriber != "0" or 'moderator' in badges or 'broadcaster' in badges: + logging.info('TTS is sub-only and user has allowance') + return False + + logging.debug('TTS is sub-only') + self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['SUBONLY']) + return True + + def check_modonly(self, tags): + """ modonly """ + + if not conf['IRC_MODONLY']: + return False + + badges = tags['badges'] + user = tags['user'] + + if 'moderator' in badges or 'broadcaster' in badges: + logging.info('TTS is mod-only and user has allowance') + return False + + logging.debug('TTS is mod-only') + self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['MODONLY']) + return True + + def check_tts_disabled(self, user): + """ Check if TTS is disabled """ + if not self.tts_status: + self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['DISABLED']) + return True + + logging.debug('TTS is enabled') + return False + + def check_msg_too_long(self, message, user): + """ Check if message is too long """ + + if message['length'] > conf['IRC_TTS_LEN']: + self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['TOO_LONG']) + return True + + logging.debug('Check length: Message is ok') + return False + + def check_user_denied(self, user): + """ Check if user is on denied list """ + if user in self.tts_denied: + logging.info("%s is not allowed to use TTS", user) + self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['DENIED']) + return True + + logging.debug("%s is allowed to use TTS", user) + return False + + def check_whitelist(self, user): + """ Check Whitelist """ + + if conf['WHITELIST']: + if user not in self.tts_allowed: + logging.debug("tts_allowed: %s", self.tts_allowed) + self.sendmsg( + conf['IRC_CHANNEL'], + "@"+str(user), conf['MESSAGE']['WHITELISTONLY'] + ) + return False + return True + return False + + def send_tts_msg(self, message, tags): + """ Send message to TTS queue """ + logging.info('Valid TTS message, adding to raw queue') + + tts = True + now = datetime.datetime.now() + timestamp = str(time.time_ns()) + + user = tags['user'] + msgid = tags['msgid'] + badges = tags['badges'] + subscriber = tags['subscriber'] + + msg = message['message'] + msglen = message['length'] + msg = msg.replace('!tts','',1) + + msg = { + "TTS": tts, + "msg": msg, + "badges": badges, + "subscriber": subscriber, + "msgid": msgid, + "user": user, + "length": msglen, + "queuetime": now, + "timestamp": timestamp + } + + msg_queue_raw.append(msg) + + def tts_command(self, message, tags): + """ Process !tts command """ + + user = tags['user'] + + if self.check_tts_disabled(user): + logging.info('TTS is disabled') + elif self.check_msg_too_long(message, user): + logging.info('TTS message is too long') + elif self.check_user_denied(user): + logging.info('User is not allowed to use TTS') + elif self.check_subonly(tags): + logging.info('TTS is sub-only') + elif self.check_modonly(tags): + logging.info('TTS is mod-only') + elif self.check_whitelist(user): + logging.info('User is not on whitelist') + else: + logging.info('Sending TTS message to raw_queue') + self.send_tts_msg(message, tags) + def get_response(self): """Get and process response from IRC""" try: @@ -102,202 +373,22 @@ class IRC: logging.debug('resp:') logging.debug(resp) except socket.timeout: - return False + return except Exception: # pylint: disable=broad-except logging.exception('An unknown error occured while getting a IRC response.') sys.exit(255) if resp.find('PING') != -1: - logging.debug('PING received') - self.irc.send(bytes('PONG :tmi.twitch.tv\r\n', "UTF-8")) + self.resp_ping() if resp.find('CLEARMSG') != -1: - logging.info('CLEARMSG received') - msgid = False - - global msg_queue_raw # pylint: disable=global-statement,invalid-name - filtered_msg_queue = [] - - tags = resp.split(';') - for tag in tags: - if "target-msg-id=" in tag: - msgid = tag.rsplit('target-msg-id=',1)[1] - logging.debug('Trying to suppress message') - logging.debug(msgid) - - for msg in list(msg_queue_raw): - if msg['msgid'] == msgid: - logging.info('Suppressing message %s', msgid) - else: - filtered_msg_queue.append(msg) - - msg_queue_raw = filtered_msg_queue - - return True + self.resp_clearmsg(resp) if resp.find('NOTICE') != -1: - if 'Login authentication failed' in resp: - try: - raise RuntimeError() - except RuntimeError: - logging.exception('Login failed, please check your credentials and try again.') - sys.exit(251) + self.resp_notice(resp) if resp.find('PRIVMSG') != -1: - logging.debug('PRIVMSG received') - badges = False - subscriber = False - msgid = False - msg = False - msglen = False - user = False - tts = False - - tags = resp.split(';') - for tag in tags: - if tag.startswith('badges='): - badges = tag.rsplit('badges=',1)[1] - if tag.startswith('subscriber='): - subscriber = tag.rsplit('subscriber=',1)[1] - logging.debug('Subscriber: %s', subscriber) - if tag.startswith('id='): - msgid = tag.rsplit('id=',1)[1] - logging.debug('Message ID: %s', msgid) - if tag.startswith('display-name='): - user = tag.rsplit('display-name=',1)[1].lower() - logging.debug('Username: %s', user) - - msg = resp.rsplit('PRIVMSG #',1)[1] - msg = msg.split(':',1)[1] - msg = msg.replace('\r\n','') - msglen = len(msg) - - logging.debug('Msg: %s', msg) - logging.debug('Msg length: %s', msglen) - logging.debug('Deny List:') - logging.debug(self.tts_denied) - - if msg.startswith('#') and self.quickvote_status is True: - logging.info('Quickvote: Cast detected') - self.pollcount += 1 - self.poll[user] = msg.lower() - logging.debug(self.poll) - return True - - if 'broadcaster' in badges or 'moderator' in badges: - if msg.startswith('!ping'): - logging.debug("Ping check received.") - self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), "Pong!") - return True - - if msg.startswith('!dtts'): - logging.debug("!dtts command detected") - self.Commands.dtts(self, msg) - return True - - if msg.startswith('!random'): - logging.info('!random command detected') - self.Commands.random(self, msg) - return True - - if msg.startswith('!quickvote'): - logging.info("!quickvote command detected") - self.Commands.quickvote(self, msg) - return True - - if msg.startswith('!ptts'): - logging.debug("!ptts command detected") - self.Commands.ptts(self, msg) - return True - - if msg.startswith('!toff'): - logging.info('TTS is now turned off') - msg_queue.clear() - msg_queue_raw.clear() - self.tts_status = False - self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['TOFF']) - return True - - if msg.startswith('!ton'): - logging.info('TTS is now turned on') - msg_queue.clear() - msg_queue_raw.clear() - self.tts_status = True - self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['TON']) - return True - - if msg.startswith('!tts'): - logging.debug('!tts command detected') - logging.debug("tts status: %s", self.tts_status) - - if not self.tts_status: - logging.info('TTS is disabled') - self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['DISABLED']) - return False - - if msglen > conf['IRC_TTS_LEN']: - logging.info('TTS message is to long') - self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['TOO_LONG']) - return False - - if conf['IRC_SUBONLY']: - if subscriber != "0" or 'moderator' in badges or 'broadcaster' in badges: - logging.debug('TTS is sub-only and user has allowance') - else: - logging.info('TTS is sub-only') - self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['SUBONLY']) - return False - - if conf['IRC_MODONLY']: - if 'moderator' in badges or 'broadcaster' in badges: - logging.debug('TTS is mod-only and user has allowance') - else: - logging.info('TTS is sub-only') - self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['MODONLY']) - return False - - if user in self.tts_denied: - logging.info("%s is not allowed to use TTS", user) - self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['DENIED']) - return False - - if conf['WHITELIST']: - if user not in self.tts_allowed: - logging.info('User is not on whitelist') - logging.info(self.tts_allowed) - self.sendmsg( - conf['IRC_CHANNEL'], - "@"+str(user), conf['MESSAGE']['WHITELISTONLY'] - ) - return False - - logging.warning('Nobody is on the whitelist.') - self.sendmsg( - conf['IRC_CHANNEL'], - "@"+str(user), conf['MESSAGE']['WHITELISTONLY'] - ) - return False - - logging.info('Valid TTS message, adding to raw queue') - tts = True - now = datetime.datetime.now() - msg = msg.replace('!tts','',1) - msg = { - "TTS": tts, - "msg": msg, - "badges": badges, - "subscriber": subscriber, - "msgid": msgid, - "user": user, - "length": msglen, - "queuetime": now, - "timestamp": str(time.time_ns()) - } - msg_queue_raw.append(msg) - - return True - - return False + self.resp_privmsg(resp) class Commands(): """ Bot commands """ @@ -345,7 +436,7 @@ class IRC: self.quickvote_status = False self.poll = {} - return False + return logging.info("Counting votes") count = 0 @@ -640,7 +731,7 @@ def load_config(): conf['IRC_SUBONLY'] = cfg.get('bot', {}).get('subonly', False) conf['IRC_MODONLY'] = cfg.get('bot', {}).get('modonly', False) conf['IRC_TTS_LEN'] = cfg.get('bot', {}).get('message_length', 200) - conf['TTS_STARTENABLED'] = cfg.get('bot', {}).get('start_enabled', False) + conf['TTS_STARTENABLED'] = cfg.get('bot', {}).get('start_enabled', True) conf['LOG_LEVEL'] = cfg.get('log', {}).get('level', "INFO") conf['HTTP_PORT'] = cfg.get('http', {}).get('port', 80) @@ -704,9 +795,25 @@ sys.tracebacklimit = 0 if sys.argv[1:]: if sys.argv[1] == "--version": print('Simple TTS Bot') - print('Version 1.2.1') + print('Version 1.2.2') sys.exit(1) +def send_tts_queue(): + """ Send messages to TTS """ + + for raw_msg in msg_queue_raw: + logging.debug('Raw msg: %s', msg_queue_raw) + + now = datetime.datetime.now() + if now - raw_msg['queuetime'] > datetime.timedelta(seconds=conf['IRC_CLEARMSG_TIMEOUT']): + logging.debug('clearmsg_timeout reached') + if raw_msg['timestamp'] not in msg_queue: + logging.info('Sending TTS message') + msg_queue[raw_msg['timestamp']] = [raw_msg['user'], raw_msg['msg']] + logging.debug("msg_queue: %s", msg_queue) + else: + logging.debug('Msg is already in queue') + def main(): """Main loop""" @@ -734,58 +841,42 @@ def main(): logging.info('Please complete the OAuth process within the next 15 minutes.') time.sleep(900) sys.exit(250) - else: - logging.info("Starting IRC bot") - irc = IRC() - irc.connect(conf['IRC_SERVER'], 6667, conf['IRC_CHANNEL'], conf['IRC_USERNAME'], conf['IRC_OAUTH_TOKEN']) - irc.sendmsg(conf['IRC_CHANNEL'], 'MrDestructoid', conf['MESSAGE']['READY']) + logging.info("Starting IRC bot") + irc = IRC() - logging.info("Please open your browser and visit: http://%s:%s/", conf['HTTP_BIND'], conf['HTTP_PORT']) - url = 'http://'+str(conf['HTTP_BIND'])+':'+str(conf['HTTP_PORT']) - webbrowser.open_new_tab(url) + irc.connect(conf['IRC_SERVER'], 6667, conf['IRC_CHANNEL'], conf['IRC_USERNAME'], conf['IRC_OAUTH_TOKEN']) + irc.sendmsg(conf['IRC_CHANNEL'], 'MrDestructoid', conf['MESSAGE']['READY']) - while True: - if conf['LOG_LEVEL'] == "DEBUG": - time.sleep(1) + logging.info("Please open your browser and visit: http://%s:%s/", conf['HTTP_BIND'], conf['HTTP_PORT']) + url = 'http://'+str(conf['HTTP_BIND'])+':'+str(conf['HTTP_PORT']) + webbrowser.open_new_tab(url) - try: - irc.get_response() + while True: + if conf['LOG_LEVEL'] == "DEBUG": + time.sleep(1) - confreload = datetime.datetime.now() - if confreload - lastreload > datetime.timedelta(seconds=60): - conf = load_config() - lastreload = datetime.datetime.now() + try: + irc.get_response() - if irc.quickvote_status and irc.votemsg: - logging.info('Quickvote is active') - irc.sendmsg(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART'] + " (" + str(irc.votemsg) + ")") + confreload = datetime.datetime.now() + if confreload - lastreload > datetime.timedelta(seconds=60): + conf = load_config() + lastreload = datetime.datetime.now() - if not irc.tts_status: - logging.debug("TTS is disabled") - if conf['LOG_LEVEL'] == "DEBUG": - time.sleep(1) - continue + if irc.quickvote_status and irc.votemsg: + logging.info('Quickvote is active') + irc.sendmsg(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART'] + " (" + str(irc.votemsg) + ")") - logging.debug('Raw message queue:') - logging.debug(msg_queue_raw) + if not irc.tts_status: + continue - for raw_msg in msg_queue_raw: - logging.debug('Raw msg:') - logging.debug(msg_queue_raw) + logging.debug('msg_queue_raw: %s', msg_queue_raw) + send_tts_queue() - now = datetime.datetime.now() - if now - raw_msg['queuetime'] > datetime.timedelta(seconds=conf['IRC_CLEARMSG_TIMEOUT']): - logging.debug('clearmsg_timeout reached') - if raw_msg['timestamp'] not in msg_queue: - logging.info('Sending TTS message') - msg_queue[raw_msg['timestamp']] = [raw_msg['user'], raw_msg['msg']] - logging.debug(msg_queue) - else: - logging.debug('Msg is already in queue') - except KeyboardInterrupt: - logging.info('Exiting...') - sys.exit() + except KeyboardInterrupt: + logging.info('Exiting...') + sys.exit() if __name__ == "__main__": main()