diff --git a/CHANGELOG.md b/CHANGELOG.md index 231b54c..4682217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,21 @@ All notable changes to this project will be documented in this file. -## [1.0.0] - 2022-08-11 - -Initial Release +## [1.1.0] - unreleased ### Added + * `!quickvote` feature (see README.md for details) + * `!ping` command added + ### Changed + * The bot replies with a chat message when `!ton` or `!toff` is used + ### Fixed + + * Improved error handling + +## [1.0.0] - 2022-08-11 + +Initial Release diff --git a/README.md b/README.md index 753c936..e8fe4b9 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,10 @@ messages: whitelist: "Sorry, you are not allowed to use TTS." ready: "TTS bot alpha ready!" says: "says" + votestart: "Quickvote started. Send #yourchoice to participate." + voteend: "Quickvote ended. The results are:" + votenobody: "Nobody casted a vote. :(" + votes: "Votes" log: level: "INFO" @@ -100,6 +104,10 @@ whitelist: * `whitelist`: The bots reply if `whitelist` is set and user isn't on the list. * `ready`: The bots init message * `says`: Prefix to add between username and message + * `votestart`: Message when a quickvote is started. + * `voteend`: Message if a quickvote ends. + * `votenobody`: Message if quickvote ends, but nobody has voted. + * `votes`: Suffix to vote count. ##### log @@ -144,6 +152,10 @@ Additional commands (broadcaster and mods only) are: * `!dtts `: Disable TTS for the given user * `!ptts `: Allow TTS for the given user +### Additional features + +The bot also contains a `!quickvote` feature. If a broadcaster or moderator send the `!quickvote` command a vote will be started (or a already running vote will be ended). After a quickvote has been started your community can casts votes by sending a chat message starting with `#`. You can include a message after `!quickvote` (e.g. `!quickvote Is pizza hawaii any good? #yes/#no`). If you do so, this message will be repeated every 60 seconds, so everyone keeps in mind, that a vote is still active. + ## Build If you prefer to build your own `tts.exe` instead of using the shipped one, you can do as follows: diff --git a/config-dist.yml b/config-dist.yml index 1929c0d..a83fc22 100644 --- a/config-dist.yml +++ b/config-dist.yml @@ -23,6 +23,10 @@ messages: modonly: "Sorry, TTS is a mod-only feature." ready: "TTS bot alpha ready!" says: "says" + votestart: "Quickvote started. Send #yourchoice to participate." + voteend: "Quickvote ended. The results are:" + votenobody: "Nobody casted a vote. :(" + votes: "Votes" log: level: "INFO" diff --git a/tts.py b/tts.py index ceccd82..cb6c4f9 100644 --- a/tts.py +++ b/tts.py @@ -31,6 +31,7 @@ import socketserver from threading import Thread from http.server import BaseHTTPRequestHandler from urllib.parse import parse_qs +from collections import Counter class IRC: irc = socket.socket() @@ -40,6 +41,10 @@ class IRC: self.tts_denied = [] self.tts_allowed = [] self.tts_status = True + self.quickvote = False + self.votemsg = False + self.poll = {} + self.pollcount = 0 if 'WHITELIST_USER' in conf: self.tts_allowed = conf['WHITELIST_USER'] @@ -63,9 +68,9 @@ class IRC: try: self.irc.send(bytes("JOIN " + channel + "\r\n", "UTF-8")) except ConnectionResetError: - logging.warn('JOIN was refused, will try again in 5 seconds.') + logging.warning('JOIN was refused, will try again in 5 seconds.') time.sleep(5) - logging.warn('Please check your credentials, if this error persists.') + logging.warning('Please check your credentials, if this error persists.') self.irc.send(bytes("JOIN " + channel + "\r\n", "UTF-8")) def sendpriv(self, channel, user, msg): @@ -171,11 +176,48 @@ class IRC: return True if msg.startswith('!ping'): - logging.debug('Ping check received.') + logging.debug("Ping check received.") self.sendpriv(conf['IRC_CHANNEL'], "@"+str(user), "Pong!") return True + if msg.startswith('!quickvote'): + logging.info("!quickvote command detected") + if self.quickvote: + logging.debug('Quickvote stopped') + + if self.pollcount == 0: + logging.info("Nobody voted") + self.sendpriv(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTEEND']) + self.sendpriv(conf['IRC_CHANNEL'], "*", conf['MESSAGE']['VOTENOBODY']) + self.quickvote = False + self.poll = {} + return False + + logging.info("Counting votes") + count = 0 + count = Counter(self.poll.values()).most_common(5) + self.sendpriv(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTEEND']) + + logging.debug(count) + + for key, value in count: + self.sendpriv(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.sendpriv(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART'] + " (" + str(self.votemsg) + ")") + else: + self.sendpriv(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART']) + return True + if msg.startswith('!ptts'): logging.debug("!ptts command detected") user = msg.replace('!ptts', '').strip().lower() @@ -193,6 +235,12 @@ class IRC: return True + if msg.startswith('#') and self.quickvote == True: + logging.info('Quickvote: Cast detected') + self.pollcount += 1 + self.poll[user] = msg.lower() + logging.debug(self.poll) + if msg.startswith('!toff'): logging.info('TTS is now turned off') msg_queue.clear() @@ -398,6 +446,11 @@ def load_config(): conf['MESSAGE']['WHITELISTONLY'] = cfg['messages']['whitelist'] or False conf['MESSAGE']['SAYS'] = cfg['messages']['says'] or "says" + conf['MESSAGE']['VOTESTART'] = cfg['messages']['votestart'] or "Quickvote started. Send #yourchoice to participate." + conf['MESSAGE']['VOTEEND'] = cfg['messages']['voteend'] or "Quickvote ended. The results are:" + conf['MESSAGE']['VOTENOBODY'] = cfg['messages']['votenobody'] or "Nobody casted a vote. :(" + conf['MESSAGE']['VOTES'] = cfg['messages']['votes'] or "Stimmen" + conf['USERMAP'] = cfg['usermapping'] or [] if 'whitelist' in cfg: @@ -473,6 +526,10 @@ def main(): if confreload - lastreload > datetime.timedelta(seconds=60): conf = load_config() lastreload = datetime.datetime.now() + + if irc.quickvote and irc.votemsg: + logging.info('Quickvote is active') + irc.sendpriv(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART'] + " (" + str(irc.votemsg) + ")") logging.debug('Raw message queue:') logging.debug(msg_queue_raw)