obschatbot/services/TimedMessageService.py

149 lines
5.0 KiB
Python

from datetime import datetime, timedelta
from obspython import *
from services.Service import Service
from threading import Thread
import os.path
import time
KNOWN_COMMANDS = ["addmsg", "delmsg", "listmsg"]
SEPARATOR = ";"
SUBST_SEP = ".,"
class TimedMessageService(Service):
title = "Timed Message Service"
enabled = False
msg_added = ""
msg_deleted = ""
msg_not_deleted = ""
file = ""
messages = {}
interval = 60
running = False
def knows(self, command):
return command in KNOWN_COMMANDS
def eval(self, command, response, users):
can_manage = False
for badge in response["tags"]["badges"]:
if badge["name"] in ["broadcaster", "moderator"]:
can_manage = True
if not can_manage:
return
if command == "addmsg":
self.queue.append(self.add(response))
elif command == "delmsg":
self.queue.append(self.delete(response))
elif command == "listmsg":
self.queue.append(self.list(response))
def list_commands(self):
return KNOWN_COMMANDS
def start(self):
self.load_file()
self.init_time()
self.running = True
thread = Thread(target=self.dispatch)
thread.daemon = True
thread.start()
def load_file(self):
if self.file == "" or not os.path.isfile(self.file):
return
with open(self.file, "r", encoding="utf-8") as file:
content = file.read().splitlines()
for line in content:
self.load_message(line)
def load_message(self, line):
components = line.split(SEPARATOR)
starting_time = datetime.now()
self.messages[components[0]] = {
"interval": int(components[1]),
"next_time": "",
"message": components[2].replace(SUBST_SEP, SEPARATOR)
}
def init_time(self):
starting_time = datetime.now()
times = []
for msg_id in self.messages:
new_time = starting_time + timedelta(minutes = self.messages[msg_id]["interval"])
formatted = new_time.strftime("%H:%M")
while formatted in times:
new_time += timedelta(minutes = 3)
formatted = new_time.strftime("%H:%M")
times.append(formatted)
self.messages[msg_id]["next_time"] = formatted
def stop(self):
self.running = False
# OBS subset -----
def create_properties(self):
props = obs_properties_create()
obs_properties_add_path(props, "tmsg_file", "Messages list", OBS_PATH_FILE, "Text file (*.txt)", None)
obs_properties_add_text(props, "tmsg_msg_added", "Message: Message added", OBS_TEXT_DEFAULT)
obs_properties_add_text(props, "tmsg_msg_deleted", "Message: Message deleted", OBS_TEXT_DEFAULT)
obs_properties_add_text(props, "tmsg_msg_not_deleted", "Message: Message not deleted", OBS_TEXT_DEFAULT)
return props
def update(self, settings):
self.file = obs_data_get_string(settings, "tmsg_file")
self.msg_added = obs_data_get_string(settings, "tmsg_msg_added")
self.msg_deleted = obs_data_get_string(settings, "tmsg_msg_deleted")
self.msg_not_deleted = obs_data_get_string(settings, "tmsg_msg_not_deleted")
# Commands -----
def add(self, response):
current_time = datetime.now()
components = response["message"].split(" ", 3)
print(components)
self.messages[components[1]] = {
"interval": int(components[2]),
"next_time": "",
"message": components[3],
}
next_time = current_time + timedelta(minutes = self.messages[components[1]]["interval"])
self.messages[components[1]]["next_time"] = next_time.strftime("%H:%M")
self.write()
return f"{self.msg_added}"
def delete(self, response):
msg_id = response["message"].split(" ", 2)[1]
if msg_id not in self.messages:
return f"{self.msg_not_deleted}"
self.messages.pop(msg_id)
self.write()
return f"{self.msg_deleted}"
def list(self, response):
return " ".join(self.messages)
def write(self):
with open(self.file, "w", encoding="utf-8") as file:
for msg_id, message in self.messages.items():
file.write(f"{msg_id}{SEPARATOR}{message['interval']}{SEPARATOR}{message['message'].replace(SEPARATOR, SUBST_SEP)}\n");
# Main function -----
def dispatch(self):
while self.running:
current_time = datetime.now()
formatted = current_time.strftime("%H:%M")
for msg_id in self.messages:
if self.messages[msg_id]["next_time"] != formatted:
continue
self.queue.append(self.messages[msg_id]["message"])
new_time = current_time + timedelta(minutes = self.messages[msg_id]["interval"])
self.messages[msg_id]["next_time"] = new_time.strftime("%H:%M")
break
time.sleep(self.interval)