diff --git a/bot.py b/bot.py index 1c316fb..cd5c70c 100644 --- a/bot.py +++ b/bot.py @@ -1,12 +1,23 @@ import teambot, sys, tasks, json import os.path as fs +def loadSubscribers(): + if not fs.exists("subscribers.json"): + return [] + with open("subscribers.json") as f: + return json.load(f)["subscribers"] + +def saveSubscribers(subscribers): + with open("subscribers.json","w") as f: + return json.dump(dict(subscribers=subscribers),f) + class RadioBot(teambot.Handler): def __init__(self,*args): super(RadioBot,self).__init__(*args) self.tasks = tasks.TaskPool(handler=self) - self.tasks.add_coroutine(self.check_nowplaying,1) + self.tasks.add_coroutine(self.check_nowplaying,1,dict(dj_live=False,dj=None,song="",listeners)) self.channels = [x.split()[0] for x in self._bot.chanlist] + self.subscribers = loadSubscribers() self.tasks.run() def check_nowplaying(self,state,basestate): if not hasattr(self._bot,"conn"): @@ -15,7 +26,10 @@ class RadioBot(teambot.Handler): with open(fs.expanduser("~khuxkm/public_html/radiobot/now_playing.json")) as f: resp = json.loads(f.read().rstrip()) if resp["dj"] is not None and not state.get("dj_live",False): - bot.say(bot.channels[0],"{} is now live!".format(resp["dj"])) + notify = [bot.channels[0]] + notify.extend(self.subscribers) + for channel in notify: + bot.say(channel,"{} is now live!".format(resp["dj"])) state["dj"] = resp["dj"] state["dj_live"]=True if resp["dj"] is None and state.get("dj_live",True): @@ -40,6 +54,20 @@ class RadioBot(teambot.Handler): self.say(channel,nick+": nobody is live right now.") elif cmd=="np": self.say(channel,nick+": now playing: {} ({!s} listeners{})".format(self.task_state["song"],self.task_state["listeners"],(", played by "+self.task_state["dj"] if self.task_state["dj_live"] else ""))) + elif cmd=="subscribe": + if nick in self.subscribers: + self.say(channel,nick+": you're already on my list!") + else: + self.subscribers.append(nick) + saveSubscribers(self.subscribers) + self.say(channel,nick+": I'll notify you when someone goes live!") + elif cmd=="unsubscribe": + if nick not in self.subscribers: + self.say(channel,nick+": you're not on my list!") + else: + self.subscribers.remove(nick) + saveSubscribers(self.subscribers) + self.say(channel,nick+": I'll leave you alone then.") elif cmd=="radio": # joke command self.say(channel,"eat the poop or die!!1") elif cmd=="paymybills": # joke command diff --git a/tasks.py b/tasks.py new file mode 100644 index 0000000..c2a61c5 --- /dev/null +++ b/tasks.py @@ -0,0 +1,40 @@ +import sched,time +from threading import Thread +from sys import exit +class TaskPool: + def __init__(self,**kwargs): + self.base_state = kwargs + self.base_state["task_pool"] = self + self.scheduler = sched.scheduler(time.time,time.sleep) + self.thread = Thread(target=self.worker,args=(self,)) + self.coroutines = [] + self.states = {} + self.killswitch = False + + def periodical(self,scheduler,interval,action,index,state=dict()): + if self.killswitch: + return + + self.states[index] = action(state,self.base_state) + if not self.killswitch: + scheduler.enter(interval,1,self.periodical,(scheduler,interval,action,index,self.states[index])) + + def worker(self,tasks): + for c,coro in enumerate(tasks.coroutines): + interval = coro["interval"] + action = coro["action"] + state = coro.get("state",dict()) + tasks.periodical(tasks.scheduler,interval,action,c,state) + tasks.scheduler.run() + exit(0) + + def run(self): + self.thread.daemon = True + self.thread.start() + + def stop(self): + list(map(self.scheduler.cancel, self.scheduler.queue)) + self.killswitch = True # kill any lingering tasks + + def add_coroutine(self,action,interval,state=dict()): + self.coroutines.append(dict(action=action,interval=interval,state=state))