Improved HTTP handling

This commit is contained in:
gpkvt 2022-08-19 03:10:38 +02:00
parent 60749f6828
commit a18a9d1ee4
5 changed files with 80 additions and 34 deletions

2
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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:

Binary file not shown.

96
tts.py
View File

@ -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
@ -421,7 +423,7 @@ class IRC:
def addquote(self, tags, msg): def addquote(self, tags, msg):
""" !addquote command """ !addquote command
Adds a newline to quotes.txt Adds a newline to quotes.txt
""" """
@ -433,25 +435,53 @@ 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
quote = msg.replace("!addquote ", "").strip() quote = msg.replace("!addquote ", "").strip()
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,
@ -483,38 +513,42 @@ class IRC:
try: try:
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 = []
for match, score in matches: for match, score in matches:
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')
with open("quotes.txt", "rb") as file: with open("quotes.txt", "rb") as file:
lines = file.read().splitlines() lines = file.read().splitlines()
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()