mirror of
				https://gitlab.com/gpvkt/twitchtts.git
				synced 2025-10-31 17:17:35 +01:00 
			
		
		
		
	Improved HTTP handling
This commit is contained in:
		
							parent
							
								
									9fd8c17889
								
							
						
					
					
						commit
						e9a2c0bd61
					
				
					 5 changed files with 80 additions and 34 deletions
				
			
		
							
								
								
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -1,6 +1,6 @@ | ||||||
| config.yml | config.yml | ||||||
| build | build | ||||||
|  | dist | ||||||
| tts.spec | tts.spec | ||||||
| tts.exe |  | ||||||
| random*.txt | random*.txt | ||||||
| quotes.txt | quotes.txt | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								CHANGELOG.md
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								CHANGELOG.md
									
										
									
									
									
								
							|  | @ -2,6 +2,16 @@ | ||||||
| 
 | 
 | ||||||
| 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.3.1] - 2022-08-19 | ||||||
|  | 
 | ||||||
|  | ### Added 1.3.1 | ||||||
|  | 
 | ||||||
|  | * Added `game_name` and date to quote | ||||||
|  | 
 | ||||||
|  | ### Fixed (hopefully) 1.3.1 | ||||||
|  | 
 | ||||||
|  | * Improved HTTP request handling (hopefully removes delay in Chrome) | ||||||
|  | 
 | ||||||
| ## [1.3.0] - 2022-08-18 | ## [1.3.0] - 2022-08-18 | ||||||
| 
 | 
 | ||||||
| ### Added 1.3.0 | ### Added 1.3.0 | ||||||
|  |  | ||||||
|  | @ -28,11 +28,13 @@ By using Javascript for the actual TTS part it's not only very easy to access th | ||||||
| 
 | 
 | ||||||
| 1. Clone the repo, or download and unzip the newest [Release](https://gitlab.com/gpvkt/twitchtts/-/releases) | 1. Clone the repo, or download and unzip the newest [Release](https://gitlab.com/gpvkt/twitchtts/-/releases) | ||||||
| 2. Rename/copy `config-dist.yml` to `config.yml` | 2. Rename/copy `config-dist.yml` to `config.yml` | ||||||
| 3. Move/copy `./dist/tts.exe` into the main directory (you can omit this step if you have Python installed) | 3. Adapt `config.yml` to your needs. See `Configuration` for details. | ||||||
| 
 | 
 | ||||||
| ### Configuration | ### Configuration | ||||||
| 
 | 
 | ||||||
| Adapt `config.yml` to your needs. Please use `UTF-8` as encoding. Example: | Please use `UTF-8` as encoding, when editing `config.yml`. | ||||||
|  | 
 | ||||||
|  | Example: | ||||||
| 
 | 
 | ||||||
| ``` lang=yaml | ``` lang=yaml | ||||||
| irc: | irc: | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								tts.exe
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								tts.exe
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										86
									
								
								tts.py
									
										
									
									
									
								
							
							
						
						
									
										86
									
								
								tts.py
									
										
									
									
									
								
							|  | @ -1,6 +1,6 @@ | ||||||
| #!/usr/bin/python3 | #!/usr/bin/python3 | ||||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||||
| # pylint: disable=line-too-long | # pylint: disable=line-too-long,too-many-lines | ||||||
| 
 | 
 | ||||||
| """ | """ | ||||||
|     TwitchTTS |     TwitchTTS | ||||||
|  | @ -24,12 +24,12 @@ import os | ||||||
| import sys | import sys | ||||||
| import time | import time | ||||||
| import json | import json | ||||||
|  | import signal | ||||||
| import socket | import socket | ||||||
| import random | import random | ||||||
| import logging | import logging | ||||||
| import datetime | import datetime | ||||||
| import webbrowser | import webbrowser | ||||||
| import socketserver |  | ||||||
| import urllib.parse | import urllib.parse | ||||||
| import urllib.request | import urllib.request | ||||||
| 
 | 
 | ||||||
|  | @ -37,9 +37,11 @@ from threading import Thread | ||||||
| from collections import Counter | from collections import Counter | ||||||
| from urllib.parse import parse_qs | from urllib.parse import parse_qs | ||||||
| from urllib.error import HTTPError | from urllib.error import HTTPError | ||||||
| from http.server import BaseHTTPRequestHandler | from http.server import HTTPServer, BaseHTTPRequestHandler | ||||||
|  | from socketserver import ThreadingMixIn | ||||||
| 
 | 
 | ||||||
| import yaml | import yaml | ||||||
|  | import requests | ||||||
| 
 | 
 | ||||||
| from fuzzywuzzy import process | from fuzzywuzzy import process | ||||||
| 
 | 
 | ||||||
|  | @ -433,11 +435,11 @@ class IRC: | ||||||
|                 logging.info('TTS is sub-only') |                 logging.info('TTS is sub-only') | ||||||
|             else: |             else: | ||||||
|                 try: |                 try: | ||||||
|                     with open("quotes.txt", "rb") as fp: |                     with open("quotes.txt", "rb") as file: | ||||||
|                         nol = len(fp.readlines()) |                         nol = len(file.readlines()) | ||||||
|                     fp.close() |                     file.close() | ||||||
|                 except FileNotFoundError: |                 except FileNotFoundError: | ||||||
|                     logging.warn("quotes.txt does not exists, will create") |                     logging.warning("quotes.txt does not exists, will create") | ||||||
|                     nol = 0 |                     nol = 0 | ||||||
| 
 | 
 | ||||||
|                 nol = nol + 1 |                 nol = nol + 1 | ||||||
|  | @ -445,13 +447,41 @@ class IRC: | ||||||
|                 quote = quote.split(" ",1) |                 quote = quote.split(" ",1) | ||||||
|                 username = quote[0] |                 username = quote[0] | ||||||
| 
 | 
 | ||||||
|                 quote = '#%s: "%s" -%s' % (nol, quote[1], username) |                 date = time.strftime("%d.%m.%Y") | ||||||
|  | 
 | ||||||
|  |                 try: | ||||||
|  |                     token = conf['IRC_OAUTH_TOKEN'].replace('oauth:','') | ||||||
|  |                     login = conf['IRC_CHANNEL'].replace('#','') | ||||||
|  |                     api_endpoint = "https://api.twitch.tv/helix/users?login="+str(login) | ||||||
|  |                     headers = { | ||||||
|  |                         'Content-type': 'application/x-form-urlencoded', | ||||||
|  |                         'Authorization': 'Bearer '+token, | ||||||
|  |                         'Client-Id': 'ebo548vs6tq54c9zlrgin2yfzzlrrs' | ||||||
|  |                     } | ||||||
|  |                     req = requests.get(url=api_endpoint, headers=headers) | ||||||
|  |                     data = req.json() | ||||||
|  |                     user_id = data['data'][0]['id'] | ||||||
|  | 
 | ||||||
|  |                     api_endpoint = "https://api.twitch.tv/helix/channels?broadcaster_id="+str(user_id) | ||||||
|  |                     headers = { | ||||||
|  |                         'Content-type': 'application/x-form-urlencoded', | ||||||
|  |                         'Authorization': 'Bearer '+token, | ||||||
|  |                         'Client-Id': 'ebo548vs6tq54c9zlrgin2yfzzlrrs' | ||||||
|  |                     } | ||||||
|  |                     req = requests.get(url=api_endpoint, headers=headers) | ||||||
|  |                     data = req.json() | ||||||
|  |                     game = data['data'][0]['game_name'] | ||||||
|  | 
 | ||||||
|  |                     quote = f"#{nol}: \"{quote[1]}\" -{username}/{game} ({date})\n" | ||||||
|  |                 except: # pylint: disable=bare-except | ||||||
|  |                     logging.warning('Could not get metadata for quote') | ||||||
|  |                     quote = f"#{nol}: \"{quote[1]}\" -{username} ({date})\n" | ||||||
|  | 
 | ||||||
|                 logging.info('Adding quote %s', quote) |                 logging.info('Adding quote %s', quote) | ||||||
|  |                 with open("quotes.txt", "ab") as file: | ||||||
|  |                     file.write(quote.encode('utf-8')) | ||||||
| 
 | 
 | ||||||
|                 with open("quotes.txt", "ab") as fp: |                 msg = f"{conf['MESSAGE']['QUOTE_ADDED_PREFIX']} #{nol} {conf['MESSAGE']['QUOTE_ADDED_SUFFIX']}" | ||||||
|                     fp.write(quote.encode('utf-8')) |  | ||||||
| 
 |  | ||||||
|                 msg = "%s #%s %s" % (conf['MESSAGE']['QUOTE_ADDED_PREFIX'], nol, conf['MESSAGE']['QUOTE_ADDED_SUFFIX']) |  | ||||||
| 
 | 
 | ||||||
|                 raw_msg = { |                 raw_msg = { | ||||||
|                     "TTS": True, |                     "TTS": True, | ||||||
|  | @ -484,20 +514,20 @@ class IRC: | ||||||
|                 if query.isdigit(): |                 if query.isdigit(): | ||||||
|                     logging.info('Fetching quote #%s', query) |                     logging.info('Fetching quote #%s', query) | ||||||
| 
 | 
 | ||||||
|                     fp = open("quotes.txt", "rb") |                     file = open("quotes.txt", "rb") | ||||||
|                     quotes = fp.readlines() |                     quotes = file.readlines() | ||||||
| 
 | 
 | ||||||
|                     for line in quotes: |                     for line in quotes: | ||||||
|                         if line.decode('utf-8').startswith("#"+str(query)+":"): |                         if line.decode('utf-8').startswith("#"+str(query)+":"): | ||||||
|                             quote = line |                             quote = line | ||||||
|                             break |                             break | ||||||
|                     fp.close() |                     file.close() | ||||||
| 
 | 
 | ||||||
|                 elif query != "": |                 elif query != "": | ||||||
|                     logging.info('Fetching match for %s', query) |                     logging.info('Fetching match for %s', query) | ||||||
| 
 | 
 | ||||||
|                     fp = open("quotes.txt", "rb") |                     file = open("quotes.txt", "rb") | ||||||
|                     quotes = fp.readlines() |                     quotes = file.readlines() | ||||||
|                     matches = process.extract(query, quotes, limit=20) |                     matches = process.extract(query, quotes, limit=20) | ||||||
|                     quotes = [] |                     quotes = [] | ||||||
| 
 | 
 | ||||||
|  | @ -505,7 +535,9 @@ class IRC: | ||||||
|                         if score >= 60: |                         if score >= 60: | ||||||
|                             quotes.append(match) |                             quotes.append(match) | ||||||
| 
 | 
 | ||||||
|                     quote = random.choice(quotes) |                     logging.debug('Quotes: %s', quotes) | ||||||
|  |                     if len(quotes) >= 1: | ||||||
|  |                         quote = random.choice(quotes) | ||||||
| 
 | 
 | ||||||
|                 else: |                 else: | ||||||
|                     logging.info('Fetching random quote') |                     logging.info('Fetching random quote') | ||||||
|  | @ -515,6 +547,8 @@ class IRC: | ||||||
|                         quote = random.choice(lines) |                         quote = random.choice(lines) | ||||||
|             except FileNotFoundError: |             except FileNotFoundError: | ||||||
|                 logging.error('"quotes.txt does not exists.') |                 logging.error('"quotes.txt does not exists.') | ||||||
|  |             except IndexError: | ||||||
|  |                 logging.error('Error fetching quote.') | ||||||
| 
 | 
 | ||||||
|             if not 'quote' in vars(): |             if not 'quote' in vars(): | ||||||
|                 logging.info('No quote found.') |                 logging.info('No quote found.') | ||||||
|  | @ -522,9 +556,7 @@ class IRC: | ||||||
|                 IRC.sendmsg(self, conf['IRC_CHANNEL'], "", quote) |                 IRC.sendmsg(self, conf['IRC_CHANNEL'], "", quote) | ||||||
|                 return False |                 return False | ||||||
| 
 | 
 | ||||||
|             if isinstance(quote, str): |             if not isinstance(quote, str): | ||||||
|                 quote = quote |  | ||||||
|             else: |  | ||||||
|                 quote = quote.decode('utf-8') |                 quote = quote.decode('utf-8') | ||||||
| 
 | 
 | ||||||
|             if IRC.check_tts_disabled(self, user): |             if IRC.check_tts_disabled(self, user): | ||||||
|  | @ -733,6 +765,9 @@ class IRC: | ||||||
| 
 | 
 | ||||||
|             return |             return | ||||||
| 
 | 
 | ||||||
|  | class ThreadingSimpleServer(ThreadingMixIn, HTTPServer): | ||||||
|  |     """ Threaded HTTP Server """ | ||||||
|  | 
 | ||||||
| class HTTPserv(BaseHTTPRequestHandler): | class HTTPserv(BaseHTTPRequestHandler): | ||||||
|     """Simple HTTP Server""" |     """Simple HTTP Server""" | ||||||
| 
 | 
 | ||||||
|  | @ -1015,9 +1050,7 @@ def main(): | ||||||
|         sys.tracebacklimit = 5 |         sys.tracebacklimit = 5 | ||||||
| 
 | 
 | ||||||
|     logging.info("Starting Webserver") |     logging.info("Starting Webserver") | ||||||
|     httpd = socketserver.TCPServer((conf['HTTP_BIND'], conf['HTTP_PORT']), HTTPserv) |     httpd = ThreadingSimpleServer((conf['HTTP_BIND'], conf['HTTP_PORT']), HTTPserv) | ||||||
|     httpd.allow_reuse_port = True |  | ||||||
|     httpd.allow_reuse_address = True |  | ||||||
| 
 | 
 | ||||||
|     http_thread = Thread(target=http_serve_forever, daemon=True, args=(httpd, )) |     http_thread = Thread(target=http_serve_forever, daemon=True, args=(httpd, )) | ||||||
|     http_thread.start() |     http_thread.start() | ||||||
|  | @ -1057,8 +1090,9 @@ def main(): | ||||||
|             send_tts_queue() |             send_tts_queue() | ||||||
| 
 | 
 | ||||||
|         except KeyboardInterrupt: |         except KeyboardInterrupt: | ||||||
|  |             httpd.shutdown() | ||||||
|             logging.info('Exiting...') |             logging.info('Exiting...') | ||||||
|             sys.exit() |             os.kill(os.getpid(), signal.SIGTERM) | ||||||
| 
 | 
 | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(module)s %(threadName)s %(levelname)s: %(message)s') |     logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(module)s %(threadName)s %(levelname)s: %(message)s') | ||||||
|  | @ -1072,7 +1106,7 @@ if __name__ == "__main__": | ||||||
|     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.3.0') |             print('Version 1.3.1') | ||||||
|             sys.exit(1) |             sys.exit(1) | ||||||
| 
 | 
 | ||||||
|     main() |     main() | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue