Quote function added

This commit is contained in:
gpkvt 2022-08-18 16:45:11 +02:00
parent 57e55f0946
commit bf1d61a33b
4 changed files with 177 additions and 2 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ build
tts.spec tts.spec
tts.exe tts.exe
random*.txt random*.txt
quotes.txt

View File

@ -118,8 +118,11 @@ Please note that the `oauth_token` is valid for approximately 60 days. If it bec
* `votestart`: Message when a quickvote is started. * `votestart`: Message when a quickvote is started.
* `voteend`: Message if a quickvote ends. * `voteend`: Message if a quickvote ends.
* `votenobody`: Message if quickvote ends, but nobody has voted. * `votenobody`: Message if quickvote ends, but nobody has voted.
* `voteresult`: Prefix for the result (will be read out) * `voteresult`: Prefix for the result (will be read out).
* `votes`: Suffix to vote count. * `votes`: Suffix to vote count.
* `quotenotfound`: Message if requests quote wasn't found.
* `quoteaddedprefix`: Prefix for `Quote <number> added` message.
* `quoteaddedsuffix`: Suffix for `Quote <number> added` message.
##### log ##### log
@ -176,6 +179,22 @@ The `!quickvote` feature implements a simple vote system. If a broadcaster or mo
The `!random` command will read a random line from a file called `random.txt`. You can also use multiple files, if you call `!random foo` the bot fetch the random line from a file called `random_foo.txt` instead of `random.txt`. `!random bar` will use the file `random_bar.txt` and so on. The `!random` command is restricted to the broadcaster and moderators. The `!random` command will read a random line from a file called `random.txt`. You can also use multiple files, if you call `!random foo` the bot fetch the random line from a file called `random_foo.txt` instead of `random.txt`. `!random bar` will use the file `random_bar.txt` and so on. The `!random` command is restricted to the broadcaster and moderators.
#### !smartvote
The `!smartvote` command will read a line from a file called `quotes.txt`. You can add a parameter after the command. If the parameter is numeric the bot will search for a line starting with `#$number`. If the parameter is a string it will search for a line matching the parameter. If no parameter is given it will search for a completely random line.
The format of `quotes.txt` looks as follows:
``` lang=text
#1: "the quote" -username (date)
```
#### !addquote
The `!addvote` command adds a new line to `quotes.txt`. It expects two parameters: `!addquote username quote` where `username` is the name of the user to be quoted.
Only Subs, Mods and Broadcaster are allowed to add quotes.
## Build ## Build
If you prefer to build your own `tts.exe` instead of using the shipped one, you can do as follows: If you prefer to build your own `tts.exe` instead of using the shipped one, you can do as follows:

View File

@ -1 +1,2 @@
fuzzywuzzy==0.18.0
PyYAML==6.0 PyYAML==6.0

156
tts.py
View File

@ -41,6 +41,8 @@ from http.server import BaseHTTPRequestHandler
import yaml import yaml
from fuzzywuzzy import process
class IRC: class IRC:
""" IRC bot """ """ IRC bot """
irc = socket.socket() irc = socket.socket()
@ -207,6 +209,14 @@ class IRC:
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!")
if msg.startswith('!addquote'):
logging.debug("!addquote command detected")
self.Commands.addquote(self, tags, msg)
if msg.startswith('!smartquote'):
logging.debug("!smartquote command detected")
self.Commands.quote(self, tags, msg)
elif 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)
@ -408,6 +418,146 @@ class IRC:
logging.info('Sending TTS message to raw_queue') logging.info('Sending TTS message to raw_queue')
IRC.send_tts_msg(self, msg, tags) IRC.send_tts_msg(self, msg, tags)
def addquote(self, tags, msg):
""" !addquote command
Adds a newline to quotes.txt
"""
user = tags['user']
if IRC.check_user_denied(self, user):
logging.info('User is not allowed to use TTS')
elif IRC.check_subonly(self, tags):
logging.info('TTS is sub-only')
else:
try:
with open("quotes.txt", "rb") as fp:
nol = len(fp.readlines())
fp.close()
except FileNotFoundError:
logging.warn("quotes.txt does not exists, will create")
nol = 0
nol = nol + 1
quote = msg.replace("!addquote ", "").strip()
quote = quote.split(" ",1)
username = quote[0]
quote = '#%s: "%s" -%s' % (nol, quote[1], username)
logging.info('Adding quote %s', quote)
with open("quotes.txt", "ab") as fp:
fp.write(quote.encode('utf-8'))
msg = "%s #%s %s" % (conf['MESSAGE']['QUOTE_ADDED_PREFIX'], nol, conf['MESSAGE']['QUOTE_ADDED_SUFFIX'])
raw_msg = {
"TTS": True,
"msg": msg,
"badges": True,
"subscriber": True,
"msgid": True,
"user": conf['IRC_USERNAME'],
"length": conf['IRC_TTS_LEN'],
"queuetime": datetime.datetime.now(),
"timestamp": str(time.time_ns())
}
msg_queue[raw_msg['timestamp']] = [raw_msg['user'], raw_msg['msg']]
IRC.sendmsg(self, conf['IRC_CHANNEL'], "@"+str(user), msg)
def quote(self, tags, msg = False):
""" !q command
Gets a line from quotes.txt. If a number if given as msg
it fetch the given line number. If a string is given
it fetch the best matching line. If nothing is given
it fetch a random line.
"""
user = tags['user']
query = msg.replace('!smartquote', '').strip()
try:
if query.isdigit():
logging.info('Fetching quote #%s', query)
fp = open("quotes.txt", "rb")
quotes = fp.readlines()
for line in quotes:
if line.decode('utf-8').startswith("#"+str(query)+":"):
quote = line
break
fp.close()
elif query != "":
logging.info('Fetching match for %s', query)
fp = open("quotes.txt", "rb")
quotes = fp.readlines()
matches = process.extract(query, quotes, limit=20)
quotes = []
for match, score in matches:
if score >= 60:
quotes.append(match)
quote = random.choice(quotes)
else:
logging.info('Fetching random quote')
with open("quotes.txt", "rb") as file:
lines = file.read().splitlines()
quote = random.choice(lines)
except FileNotFoundError:
logging.error('"quotes.txt does not exists.')
if not 'quote' in vars():
logging.info('No quote found.')
quote = conf['MESSAGE']['QUOTE_NOT_FOUND']
IRC.sendmsg(self, conf['IRC_CHANNEL'], "", quote)
return False
if isinstance(quote, str):
quote = quote
else:
quote = quote.decode('utf-8')
if IRC.check_tts_disabled(self, user):
logging.info('TTS is disabled')
elif IRC.check_user_denied(self, user):
logging.info('User is not allowed to use TTS')
elif IRC.check_subonly(self, tags):
logging.info('TTS is sub-only')
elif IRC.check_modonly(self, tags):
logging.info('TTS is mod-only')
elif IRC.check_whitelist(self, user):
logging.info('User is not on whitelist')
else:
logging.info('Sending quote to TTS')
logging.debug("Quote: %s", quote)
IRC.sendmsg(self, conf['IRC_CHANNEL'], "", quote)
quote = quote.rsplit('(', 1)[0]
raw_msg = {
"TTS": True,
"msg": quote,
"badges": True,
"subscriber": True,
"msgid": True,
"user": conf['IRC_USERNAME'],
"length": conf['IRC_TTS_LEN'],
"queuetime": datetime.datetime.now(),
"timestamp": str(time.time_ns())
}
msg_queue[raw_msg['timestamp']] = [raw_msg['user'], raw_msg['msg']]
return True
def quickvote(self, msg): def quickvote(self, msg):
""" !quickvote command """ !quickvote command
@ -760,7 +910,11 @@ def load_config():
conf['MESSAGE']['VOTEEND'] = cfg.get('messages', {}).get('voteend', "Quickvote ended. The results are:") conf['MESSAGE']['VOTEEND'] = cfg.get('messages', {}).get('voteend', "Quickvote ended. The results are:")
conf['MESSAGE']['VOTENOBODY'] = cfg.get('messages', {}).get('votenobody', "Nobody casted a vote. :(") conf['MESSAGE']['VOTENOBODY'] = cfg.get('messages', {}).get('votenobody', "Nobody casted a vote. :(")
conf['MESSAGE']['VOTERESULT'] = cfg.get('messages', {}).get('voteresult', "Voting has ended. The result is:") conf['MESSAGE']['VOTERESULT'] = cfg.get('messages', {}).get('voteresult', "Voting has ended. The result is:")
conf['MESSAGE']['VOTES'] = cfg.get('messages', {}).get('votes', "Stimmen") conf['MESSAGE']['VOTES'] = cfg.get('messages', {}).get('votes', "Votes")
conf['MESSAGE']['QUOTE_NOT_FOUND'] = cfg.get('messages', {}).get('quotenotfound', "Sorry, no quote found.")
conf['MESSAGE']['QUOTE_ADDED_PREFIX'] = cfg.get('messages', {}).get('quoteaddedprefix', "Quote:")
conf['MESSAGE']['QUOTE_ADDED_SUFFIX'] = cfg.get('messages', {}).get('quoteaddedsuffix', "added.")
conf['USERMAP'] = cfg.get('usermapping', []) conf['USERMAP'] = cfg.get('usermapping', [])