mirror of
				https://gitlab.com/gpvkt/twitchtts.git
				synced 2025-10-31 17:17:35 +01:00 
			
		
		
		
	Merge branch 'dev'
This commit is contained in:
		
						commit
						fedcc96610
					
				
					 5 changed files with 397 additions and 294 deletions
				
			
		
							
								
								
									
										27
									
								
								CHANGELOG.md
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								CHANGELOG.md
									
										
									
									
									
								
							|  | @ -2,13 +2,24 @@ | ||||||
| 
 | 
 | ||||||
| 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. | 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 | ## [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 | * Publish vote info in chat when reloading config was not working when TTS was disabled | ||||||
| * Casting votes was allowed for broadcaster and mods only | * Casting votes was allowed for broadcaster and mods only | ||||||
|  | @ -19,17 +30,17 @@ All notable changes to this project will be documented in this file. If there is | ||||||
| 
 | 
 | ||||||
| * `!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 | ## [1.1.0] - 2022-08-12 | ||||||
| 
 | 
 | ||||||
| ### Added | ### Added 1.1.0 | ||||||
| 
 | 
 | ||||||
| * `!quickvote` feature (see README.md for details) | * `!quickvote` feature (see README.md for details) | ||||||
| * `!ping` command added | * `!ping` command added | ||||||
|  | @ -37,12 +48,12 @@ All notable changes to this project will be documented in this file. If there is | ||||||
| * OAuth-Token generator | * OAuth-Token generator | ||||||
| * Webbrowser autostart | * Webbrowser autostart | ||||||
| 
 | 
 | ||||||
| ### Changed | ### Changed 1.1.0 | ||||||
| 
 | 
 | ||||||
| * You need to review your `config.yml` as there a new config values added. | * 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 | * The bot replies with a chat message when `!ton` or `!toff` is used | ||||||
| 
 | 
 | ||||||
| ### Fixed | ### Fixed 1.1.0 | ||||||
| 
 | 
 | ||||||
| * Improved error handling | * Improved error handling | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								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: | Adapt `config.yml` to your needs. Example: | ||||||
| 
 | 
 | ||||||
| ``` | ``` lang=yaml | ||||||
| irc: | irc: | ||||||
|   channel: "#gpkvt" |   channel: "#gpkvt" | ||||||
|   username: "ttsbot" |   username: "ttsbot" | ||||||
|  | @ -139,7 +139,7 @@ You can add a whitelist section to `config.yml`, a whitelist will override any o | ||||||
| 
 | 
 | ||||||
| A whitelist looks as follows: | A whitelist looks as follows: | ||||||
| 
 | 
 | ||||||
| ``` | ``` lang=yaml | ||||||
| whitelist: | whitelist: | ||||||
|   - gpkvt |   - gpkvt | ||||||
|   - foo |   - foo | ||||||
|  | @ -152,7 +152,7 @@ Please note: Usernames MUST be lowercase. | ||||||
| 
 | 
 | ||||||
| ### Executing program | ### 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. | 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. | ||||||
| 
 | 
 | ||||||
|  | @ -211,9 +211,9 @@ This project is licensed under the GPLv3 License - see [LICENSE](https://gitlab. | ||||||
| 
 | 
 | ||||||
| ### Ideas and Testing | ### Ideas and Testing | ||||||
| 
 | 
 | ||||||
| * [GERBrowny and community](https://www.twitch.tv/gerbrowny/)  | * [GERBrowny and community](https://www.twitch.tv/gerbrowny/)  | ||||||
| * [DerZugger and community](https://www.twitch.tv/derzugger/)  | * [DerZugger and community](https://www.twitch.tv/derzugger/)  | ||||||
| * [Timmeh74 and community](https://www.twitch.tv/timmeh74/)  | * [Timmeh74 and community](https://www.twitch.tv/timmeh74/)  | ||||||
| 
 | 
 | ||||||
| ### Libraries | ### Libraries | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								dist/tts.exe
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								dist/tts.exe
									
										
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										5
									
								
								tts.js
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								tts.js
									
										
									
									
									
								
							|  | @ -34,6 +34,7 @@ document.querySelector("#start").addEventListener("click", () => { | ||||||
|   speech.text = "Init complete"; |   speech.text = "Init complete"; | ||||||
|   window.speechSynthesis.speak(speech); |   window.speechSynthesis.speak(speech); | ||||||
|   $("#start").hide(); |   $("#start").hide(); | ||||||
|  |   init(); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| document.querySelector("#pause").addEventListener("click", () => { | document.querySelector("#pause").addEventListener("click", () => { | ||||||
|  | @ -54,7 +55,7 @@ function sleep(ms) { | ||||||
| 
 | 
 | ||||||
| reload = true; | reload = true; | ||||||
| 
 | 
 | ||||||
| $(document).ready(function() { | function init() { | ||||||
|     setInterval(function(){ |     setInterval(function(){ | ||||||
|       if (reload) { |       if (reload) { | ||||||
|         $.ajax({ |         $.ajax({ | ||||||
|  | @ -89,4 +90,4 @@ $(document).ready(function() { | ||||||
|         }); |         }); | ||||||
|       } |       } | ||||||
|     }, 1000); |     }, 1000); | ||||||
| }); | }; | ||||||
|  |  | ||||||
							
								
								
									
										319
									
								
								tts.py
									
										
									
									
									
								
							
							
						
						
									
										319
									
								
								tts.py
									
										
									
									
									
								
							|  | @ -95,23 +95,22 @@ class IRC: | ||||||
|         """ |         """ | ||||||
|         self.irc.send(bytes("PRIVMSG "+channel+" :"+user+" "+msg+"\r\n", "UTF-8")) |         self.irc.send(bytes("PRIVMSG "+channel+" :"+user+" "+msg+"\r\n", "UTF-8")) | ||||||
| 
 | 
 | ||||||
|     def get_response(self): |     def resp_ping(self): | ||||||
|         """Get and process response from IRC""" |         """ Respond to PING """ | ||||||
|         try: |  | ||||||
|             resp = self.irc.recv(2048).decode("UTF-8") |  | ||||||
|             logging.debug('resp:') |  | ||||||
|             logging.debug(resp) |  | ||||||
|         except socket.timeout: |  | ||||||
|             return False |  | ||||||
|         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') |         logging.debug('PING received') | ||||||
|         self.irc.send(bytes('PONG :tmi.twitch.tv\r\n', "UTF-8")) |         self.irc.send(bytes('PONG :tmi.twitch.tv\r\n', "UTF-8")) | ||||||
| 
 | 
 | ||||||
|         if resp.find('CLEARMSG') != -1: |     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') |         logging.info('CLEARMSG received') | ||||||
|         msgid = False |         msgid = False | ||||||
| 
 | 
 | ||||||
|  | @ -133,25 +132,36 @@ class IRC: | ||||||
| 
 | 
 | ||||||
|                 msg_queue_raw = filtered_msg_queue |                 msg_queue_raw = filtered_msg_queue | ||||||
| 
 | 
 | ||||||
|             return True |     def resp_privmsg(self, resp): | ||||||
| 
 |         """ Respond to PRIVMSG """ | ||||||
|         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) |  | ||||||
| 
 |  | ||||||
|         if resp.find('PRIVMSG') != -1: |  | ||||||
|         logging.debug('PRIVMSG received') |         logging.debug('PRIVMSG received') | ||||||
|             badges = False | 
 | ||||||
|             subscriber = False |         tags = self.get_tags(resp) | ||||||
|             msgid = False |         message = self.get_message(resp) | ||||||
|             msg = False | 
 | ||||||
|             msglen = False |         user = tags['user'] | ||||||
|             user = False |         msg = message['message'] | ||||||
|             tts = False |         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(';') |         tags = resp.split(';') | ||||||
|         for tag in tags: |         for tag in tags: | ||||||
|  | @ -167,121 +177,160 @@ class IRC: | ||||||
|                 user = tag.rsplit('display-name=',1)[1].lower() |                 user = tag.rsplit('display-name=',1)[1].lower() | ||||||
|                 logging.debug('Username: %s', user) |                 logging.debug('Username: %s', user) | ||||||
| 
 | 
 | ||||||
|             msg = resp.rsplit('PRIVMSG #',1)[1] |         tags = {} | ||||||
|             msg = msg.split(':',1)[1] |         tags['badges'] = badges | ||||||
|             msg = msg.replace('\r\n','') |         tags['subscriber'] = subscriber | ||||||
|             msglen = len(msg) |         tags['msgid'] = msgid | ||||||
|  |         tags['user'] = user | ||||||
| 
 | 
 | ||||||
|             logging.debug('Msg: %s', msg) |         return tags | ||||||
|             logging.debug('Msg length: %s', msglen) |  | ||||||
|             logging.debug('Deny List:') |  | ||||||
|             logging.debug(self.tts_denied) |  | ||||||
| 
 | 
 | ||||||
|             if msg.startswith('#') and self.quickvote_status is True: |     def get_message(self, resp): | ||||||
|                 logging.info('Quickvote: Cast detected') |         """ Process message """ | ||||||
|                 self.pollcount += 1 | 
 | ||||||
|                 self.poll[user] = msg.lower() |         msg = {} | ||||||
|                 logging.debug(self.poll) |         msg['message'] = resp.rsplit('PRIVMSG #',1)[1].split(':',1)[1].replace('\r\n','') | ||||||
|                 return True |         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 'broadcaster' in badges or 'moderator' in badges: | ||||||
|             if msg.startswith('!ping'): |             if msg.startswith('!ping'): | ||||||
|                 logging.debug("Ping check received.") |                 logging.debug("Ping check received.") | ||||||
|                 self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), "Pong!") |                 self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), "Pong!") | ||||||
|                     return True |  | ||||||
| 
 | 
 | ||||||
|                 if msg.startswith('!dtts'): |             elif msg.startswith('!dtts'): | ||||||
|                 logging.debug("!dtts command detected") |                 logging.debug("!dtts command detected") | ||||||
|                 self.Commands.dtts(self, msg) |                 self.Commands.dtts(self, msg) | ||||||
|                     return True |  | ||||||
| 
 | 
 | ||||||
|                 if msg.startswith('!random'): |             elif msg.startswith('!random'): | ||||||
|                 logging.info('!random command detected') |                 logging.info('!random command detected') | ||||||
|                 self.Commands.random(self, msg) |                 self.Commands.random(self, msg) | ||||||
|                     return True |  | ||||||
| 
 | 
 | ||||||
|                 if msg.startswith('!quickvote'): |             elif msg.startswith('!quickvote'): | ||||||
|                 logging.info("!quickvote command detected") |                 logging.info("!quickvote command detected") | ||||||
|                 self.Commands.quickvote(self, msg) |                 self.Commands.quickvote(self, msg) | ||||||
|                     return True |  | ||||||
| 
 | 
 | ||||||
|                 if msg.startswith('!ptts'): |             elif msg.startswith('!ptts'): | ||||||
|                 logging.debug("!ptts command detected") |                 logging.debug("!ptts command detected") | ||||||
|                 self.Commands.ptts(self, msg) |                 self.Commands.ptts(self, msg) | ||||||
|                     return True |  | ||||||
| 
 | 
 | ||||||
|                 if msg.startswith('!toff'): |             elif msg.startswith('!toff'): | ||||||
|                 logging.info('TTS is now turned off') |                 logging.info('TTS is now turned off') | ||||||
|                 msg_queue.clear() |                 msg_queue.clear() | ||||||
|                 msg_queue_raw.clear() |                 msg_queue_raw.clear() | ||||||
|                 self.tts_status = False |                 self.tts_status = False | ||||||
|                 self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['TOFF']) |                 self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['TOFF']) | ||||||
|                     return True |  | ||||||
| 
 | 
 | ||||||
|                 if msg.startswith('!ton'): |             elif msg.startswith('!ton'): | ||||||
|                 logging.info('TTS is now turned on') |                 logging.info('TTS is now turned on') | ||||||
|                 msg_queue.clear() |                 msg_queue.clear() | ||||||
|                 msg_queue_raw.clear() |                 msg_queue_raw.clear() | ||||||
|                 self.tts_status = True |                 self.tts_status = True | ||||||
|                 self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['TON']) |                 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 |         return True | ||||||
| 
 | 
 | ||||||
|             if msg.startswith('!tts'): |     def check_modonly(self, tags): | ||||||
|                 logging.debug('!tts command detected') |         """ modonly """ | ||||||
|                 logging.debug("tts status: %s", self.tts_status) |  | ||||||
| 
 | 
 | ||||||
|                 if not self.tts_status: |         if not conf['IRC_MODONLY']: | ||||||
|                     logging.info('TTS is disabled') |  | ||||||
|                     self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['DISABLED']) |  | ||||||
|             return False |             return False | ||||||
| 
 | 
 | ||||||
|                 if msglen > conf['IRC_TTS_LEN']: |         badges = tags['badges'] | ||||||
|                     logging.info('TTS message is to long') |         user = tags['user'] | ||||||
|                     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: |         if 'moderator' in badges or 'broadcaster' in badges: | ||||||
|                         logging.debug('TTS is mod-only and user has allowance') |             logging.info('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 |             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: |         if user in self.tts_denied: | ||||||
|             logging.info("%s is not allowed to use TTS", user) |             logging.info("%s is not allowed to use TTS", user) | ||||||
|             self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['DENIED']) |             self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['DENIED']) | ||||||
|  |             return True | ||||||
|  | 
 | ||||||
|  |         logging.debug("%s is allowed to use TTS", user) | ||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
|  |     def check_whitelist(self, user): | ||||||
|  |         """ Check Whitelist """ | ||||||
|  | 
 | ||||||
|         if conf['WHITELIST']: |         if conf['WHITELIST']: | ||||||
|             if user not in self.tts_allowed: |             if user not in self.tts_allowed: | ||||||
|                         logging.info('User is not on whitelist') |                 logging.debug("tts_allowed: %s", self.tts_allowed) | ||||||
|                         logging.info(self.tts_allowed) |  | ||||||
|                 self.sendmsg( |                 self.sendmsg( | ||||||
|                     conf['IRC_CHANNEL'], |                     conf['IRC_CHANNEL'], | ||||||
|                     "@"+str(user), conf['MESSAGE']['WHITELISTONLY'] |                     "@"+str(user), conf['MESSAGE']['WHITELISTONLY'] | ||||||
|                 ) |                 ) | ||||||
|                 return False |                 return False | ||||||
| 
 |             return True | ||||||
|                     logging.warning('Nobody is on the whitelist.') |  | ||||||
|                     self.sendmsg( |  | ||||||
|                         conf['IRC_CHANNEL'], |  | ||||||
|                         "@"+str(user), conf['MESSAGE']['WHITELISTONLY'] |  | ||||||
|                     ) |  | ||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
|  |     def send_tts_msg(self, message, tags): | ||||||
|  |         """ Send message to TTS queue """ | ||||||
|         logging.info('Valid TTS message, adding to raw queue') |         logging.info('Valid TTS message, adding to raw queue') | ||||||
|  | 
 | ||||||
|         tts = True |         tts = True | ||||||
|         now = datetime.datetime.now() |         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 = msg.replace('!tts','',1) | ||||||
|  | 
 | ||||||
|         msg = { |         msg = { | ||||||
|             "TTS": tts, |             "TTS": tts, | ||||||
|             "msg": msg, |             "msg": msg, | ||||||
|  | @ -291,13 +340,55 @@ class IRC: | ||||||
|             "user": user, |             "user": user, | ||||||
|             "length": msglen, |             "length": msglen, | ||||||
|             "queuetime": now, |             "queuetime": now, | ||||||
|                     "timestamp": str(time.time_ns()) |             "timestamp": timestamp | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         msg_queue_raw.append(msg) |         msg_queue_raw.append(msg) | ||||||
| 
 | 
 | ||||||
|                 return True |     def tts_command(self, message, tags): | ||||||
|  |         """ Process !tts command """ | ||||||
| 
 | 
 | ||||||
|         return False |         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: | ||||||
|  |             resp = self.irc.recv(2048).decode("UTF-8") | ||||||
|  |             logging.debug('resp:') | ||||||
|  |             logging.debug(resp) | ||||||
|  |         except socket.timeout: | ||||||
|  |             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: | ||||||
|  |             self.resp_ping() | ||||||
|  | 
 | ||||||
|  |         if resp.find('CLEARMSG') != -1: | ||||||
|  |             self.resp_clearmsg(resp) | ||||||
|  | 
 | ||||||
|  |         if resp.find('NOTICE') != -1: | ||||||
|  |             self.resp_notice(resp) | ||||||
|  | 
 | ||||||
|  |         if resp.find('PRIVMSG') != -1: | ||||||
|  |             self.resp_privmsg(resp) | ||||||
| 
 | 
 | ||||||
|     class Commands(): |     class Commands(): | ||||||
|         """ Bot commands """ |         """ Bot commands """ | ||||||
|  | @ -345,7 +436,7 @@ class IRC: | ||||||
| 
 | 
 | ||||||
|                     self.quickvote_status = False |                     self.quickvote_status = False | ||||||
|                     self.poll = {} |                     self.poll = {} | ||||||
|                     return False |                     return | ||||||
| 
 | 
 | ||||||
|                 logging.info("Counting votes") |                 logging.info("Counting votes") | ||||||
|                 count = 0 |                 count = 0 | ||||||
|  | @ -640,7 +731,7 @@ def load_config(): | ||||||
|             conf['IRC_SUBONLY'] = cfg.get('bot', {}).get('subonly', False) |             conf['IRC_SUBONLY'] = cfg.get('bot', {}).get('subonly', False) | ||||||
|             conf['IRC_MODONLY'] = cfg.get('bot', {}).get('modonly', False) |             conf['IRC_MODONLY'] = cfg.get('bot', {}).get('modonly', False) | ||||||
|             conf['IRC_TTS_LEN'] = cfg.get('bot', {}).get('message_length', 200) |             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['LOG_LEVEL'] = cfg.get('log', {}).get('level', "INFO") | ||||||
|             conf['HTTP_PORT'] = cfg.get('http', {}).get('port', 80) |             conf['HTTP_PORT'] = cfg.get('http', {}).get('port', 80) | ||||||
|  | @ -704,9 +795,25 @@ sys.tracebacklimit = 0 | ||||||
| if sys.argv[1:]: | if sys.argv[1:]: | ||||||
|     if sys.argv[1] == "--version": |     if sys.argv[1] == "--version": | ||||||
|         print('Simple TTS Bot') |         print('Simple TTS Bot') | ||||||
|         print('Version 1.2.1') |         print('Version 1.2.2') | ||||||
|         sys.exit(1) |         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(): | def main(): | ||||||
|     """Main loop""" |     """Main loop""" | ||||||
| 
 | 
 | ||||||
|  | @ -734,7 +841,7 @@ def main(): | ||||||
|         logging.info('Please complete the OAuth process within the next 15 minutes.') |         logging.info('Please complete the OAuth process within the next 15 minutes.') | ||||||
|         time.sleep(900) |         time.sleep(900) | ||||||
|         sys.exit(250) |         sys.exit(250) | ||||||
|     else: | 
 | ||||||
|     logging.info("Starting IRC bot") |     logging.info("Starting IRC bot") | ||||||
|     irc = IRC() |     irc = IRC() | ||||||
| 
 | 
 | ||||||
|  | @ -762,27 +869,11 @@ def main(): | ||||||
|                     irc.sendmsg(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART'] + " (" + str(irc.votemsg) + ")") |                     irc.sendmsg(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART'] + " (" + str(irc.votemsg) + ")") | ||||||
| 
 | 
 | ||||||
|             if not irc.tts_status: |             if not irc.tts_status: | ||||||
|                     logging.debug("TTS is disabled") |  | ||||||
|                     if conf['LOG_LEVEL'] == "DEBUG": |  | ||||||
|                         time.sleep(1) |  | ||||||
|                 continue |                 continue | ||||||
| 
 | 
 | ||||||
|                 logging.debug('Raw message queue:') |             logging.debug('msg_queue_raw: %s', msg_queue_raw) | ||||||
|                 logging.debug(msg_queue_raw) |             send_tts_queue() | ||||||
| 
 | 
 | ||||||
|                 for raw_msg in msg_queue_raw: |  | ||||||
|                     logging.debug('Raw msg:') |  | ||||||
|                     logging.debug(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) |  | ||||||
|                         else: |  | ||||||
|                             logging.debug('Msg is already in queue') |  | ||||||
|         except KeyboardInterrupt: |         except KeyboardInterrupt: | ||||||
|             logging.info('Exiting...') |             logging.info('Exiting...') | ||||||
|             sys.exit() |             sys.exit() | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue