This commit is contained in:
gpkvt 2022-08-13 12:58:26 +00:00
parent e377f5b424
commit 3891a6192e
3 changed files with 234 additions and 163 deletions

View File

@ -2,6 +2,17 @@
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.1] - unreleased
### Changed
* Reworked internal code structure
### Fixed
* 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

BIN
dist/tts.exe vendored

Binary file not shown.

442
tts.py
View File

@ -49,7 +49,7 @@ class IRC:
self.tts_denied = []
self.tts_allowed = []
self.tts_status = conf['TTS_STARTENABLED']
self.quickvote = False
self.quickvote_status = False
self.votemsg = False
self.poll = {}
self.pollcount = 0
@ -177,33 +177,238 @@ class IRC:
logging.debug('Deny List:')
logging.debug(self.tts_denied)
if 'broadcaster' in badges or 'moderator' in badges:
if msg.startswith('!dtts'):
logging.debug("!dtts command detected")
user = msg.replace('!dtts', '').strip().lower()
if user.startswith('@'):
logging.debug('Removing "@" from username')
user = user.replace('@', '')
if user not in self.tts_denied:
logging.info("Adding %s to deny list", user)
self.tts_denied.append(user)
if user in self.tts_allowed:
logging.info("Removing %s from allowed list", user)
self.tts_allowed.remove(user)
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
class Commands():
""" Bot commands """
def __init__(self):
self.tts_denied = []
self.tts_allowed = []
self.quickvote_status = self.quickvote_status
self.votemsg = self.votemsg
self.poll = self.poll
self.pollcount = self.pollcount
def quickvote(self, msg):
""" !quickvote command
Starts or stops the !quickvote function. On stop calculates the 5 most casted
votes and send them to chat. The highest vote is send to msg_queue.
:param str msg: The IRC message triggering the command
"""
if self.quickvote_status:
logging.debug('Quickvote stopped')
if self.pollcount == 0:
logging.info("Nobody voted")
IRC.sendmsg(self, conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTEEND'])
IRC.sendmsg(self, conf['IRC_CHANNEL'], "*", conf['MESSAGE']['VOTENOBODY'])
raw_msg = {
"TTS": True,
"msg": conf['MESSAGE']['VOTENOBODY'],
"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']]
logging.info('The result is: %s', conf['MESSAGE']['VOTENOBODY'])
logging.debug('Votemsg: %s', msg)
self.quickvote_status = False
self.poll = {}
return False
logging.info("Counting votes")
count = 0
count = Counter(self.poll.values()).most_common(5)
IRC.sendmsg(self, conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTEEND'])
logging.debug(count)
raw_msg = {
"TTS": True,
"msg": conf['MESSAGE']['VOTERESULT'] +" "+ str(count[0][0].replace('#','')),
"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']]
logging.info('The result is: %s', conf['MESSAGE']['VOTERESULT'] +" "+ str(count[0]))
logging.debug('Votemsg: %s', msg)
for key, value in count:
IRC.sendmsg(
self,
conf['IRC_CHANNEL'], "*",
str(key)+" ("+str(value)+ " "+ conf['MESSAGE']['VOTES'] + ")"
)
self.quickvote_status = False
self.poll = {}
self.pollcount = 0
return
logging.debug('Quickvote started')
self.quickvote_status = True
self.votemsg = msg.split('!quickvote', 1)[1].strip()
if self.votemsg:
IRC.sendmsg(self,
conf['IRC_CHANNEL'], "@chat",
conf['MESSAGE']['VOTESTART'] + " (" + str(self.votemsg) + ")"
)
else:
IRC.sendmsg(self, conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART'])
return
def random(self, msg):
""" !random command
Read a random line from randomfile and put it into msg_queue
If no file is given in msg a standard file will be used
:param str msg: The IRC message triggering the command
:raise: FileNotFoundError if randomfile does not exists
:return: True if line was successfully read and added to msg_queue
:rtype: bool
"""
randomfile = msg.replace('!random', '').strip().lower()
if randomfile:
randomfile = "random_"+str(os.path.basename(randomfile))+".txt"
else:
@ -232,84 +437,14 @@ class IRC:
return True
if msg.startswith('!quickvote'):
logging.info("!quickvote command detected")
if self.quickvote:
logging.debug('Quickvote stopped')
def ptts(self, msg):
""" !ptts command
if self.pollcount == 0:
logging.info("Nobody voted")
self.sendmsg(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTEEND'])
self.sendmsg(conf['IRC_CHANNEL'], "*", conf['MESSAGE']['VOTENOBODY'])
Add user to tts_allowed list and remove user from tts_denied list
raw_msg = {
"TTS": True,
"msg": conf['MESSAGE']['VOTENOBODY'],
"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']]
:param str msg: The IRC message triggering the command
"""
logging.info('The result is: %s', conf['MESSAGE']['VOTENOBODY'])
logging.debug('Votemsg: %s', msg)
self.quickvote = False
self.poll = {}
return False
logging.info("Counting votes")
count = 0
count = Counter(self.poll.values()).most_common(5)
self.sendmsg(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTEEND'])
logging.debug(count)
raw_msg = {
"TTS": True,
"msg": conf['MESSAGE']['VOTERESULT'] +" "+ str(count[0][0].replace('#','')),
"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']]
logging.info('The result is: %s', conf['MESSAGE']['VOTERESULT'] +" "+ str(count[0]))
logging.debug('Votemsg: %s', msg)
for key, value in count:
self.sendmsg(
conf['IRC_CHANNEL'], "*",
str(key)+" ("+str(value)+ " "+ conf['MESSAGE']['VOTES'] + ")"
)
self.quickvote = False
self.poll = {}
self.pollcount = 0
return True
else:
logging.debug('Quickvote started')
self.quickvote = True
self.votemsg = resp.split('!quickvote', 1)[1].strip()
if self.votemsg:
self.sendmsg(
conf['IRC_CHANNEL'], "@chat",
conf['MESSAGE']['VOTESTART'] + " (" + str(self.votemsg) + ")"
)
else:
self.sendmsg(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART'])
return True
if msg.startswith('!ptts'):
logging.debug("!ptts command detected")
user = msg.replace('!ptts', '').strip().lower()
if user.startswith('@'):
@ -323,106 +458,31 @@ class IRC:
logging.info("Removing %s from deny list", user)
self.tts_denied.remove(user)
return True
return
if msg.startswith('#') and self.quickvote is True:
logging.info('Quickvote: Cast detected')
self.pollcount += 1
self.poll[user] = msg.lower()
logging.debug(self.poll)
def dtts(self, msg):
""" !dtts command
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'])
Add user to tts_denied list and remove user from tts_allowed list
return True
:param str msg: The IRC message triggering the command
"""
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'])
user = msg.replace('!dtts', '').strip().lower()
return True
if user.startswith('@'):
logging.debug('Removing "@" from username')
user = user.replace('@', '')
if msg.startswith('!tts'):
logging.debug('!tts command detected')
if user not in self.tts_denied:
logging.info("Adding %s to deny list", user)
self.tts_denied.append(user)
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 user in self.tts_allowed:
logging.info("Removing %s from allowed list", user)
self.tts_allowed.remove(user)
logging.debug("tts status: %s", self.tts_status)
logging.debug(conf['TTS_STARTENABLED'])
if not self.tts_status:
logging.info('TTS is disabled')
self.sendmsg(conf['IRC_CHANNEL'], "@"+str(user), conf['MESSAGE']['DISABLED'])
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['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 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
else:
logging.info('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
return
class HTTPserv(BaseHTTPRequestHandler):
"""Simple HTTP Server"""
@ -644,7 +704,7 @@ sys.tracebacklimit = 0
if sys.argv[1:]:
if sys.argv[1] == "--version":
print('Simple TTS Bot')
print('Version 1.2.0')
print('Version 1.2.1')
sys.exit(1)
def main():
@ -692,21 +752,21 @@ def main():
try:
irc.get_response()
if not irc.tts_status:
logging.debug("TTS is disabled")
if conf['LOG_LEVEL'] == "DEBUG":
time.sleep(1)
continue
confreload = datetime.datetime.now()
if confreload - lastreload > datetime.timedelta(seconds=60):
conf = load_config()
lastreload = datetime.datetime.now()
if irc.quickvote and irc.votemsg:
if irc.quickvote_status and irc.votemsg:
logging.info('Quickvote is active')
irc.sendmsg(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART'] + " (" + str(irc.votemsg) + ")")
if not irc.tts_status:
logging.debug("TTS is disabled")
if conf['LOG_LEVEL'] == "DEBUG":
time.sleep(1)
continue
logging.debug('Raw message queue:')
logging.debug(msg_queue_raw)