did what I said I would sooner than I thought I would. centralised persisting timers through bot restarts.
This commit is contained in:
parent
9eff1b8931
commit
bc12c77891
4 changed files with 39 additions and 55 deletions
27
IRCBot.py
27
IRCBot.py
|
@ -14,6 +14,7 @@ class Bot(object):
|
||||||
self.events = EventManager.EventHook(self)
|
self.events = EventManager.EventHook(self)
|
||||||
self.timers = []
|
self.timers = []
|
||||||
self.events.on("timer").on("reconnect").hook(self.reconnect)
|
self.events.on("timer").on("reconnect").hook(self.reconnect)
|
||||||
|
self.events.on("boot").on("done").hook(self.setup_timers)
|
||||||
|
|
||||||
def add_server(self, id, hostname, port, password, ipv4, tls,
|
def add_server(self, id, hostname, port, password, ipv4, tls,
|
||||||
nickname, username, realname, connect=False):
|
nickname, username, realname, connect=False):
|
||||||
|
@ -36,9 +37,24 @@ class Bot(object):
|
||||||
for server in self.servers.values():
|
for server in self.servers.values():
|
||||||
self.connect(server)
|
self.connect(server)
|
||||||
|
|
||||||
def add_timer(self, event_name, delay, **kwargs):
|
def setup_timers(self, event):
|
||||||
timer = Timer.Timer(self, event_name, delay, **kwargs)
|
for setting, value in self.find_settings("timer-%"):
|
||||||
timer.set_started_time()
|
id = setting.split("timer-", 1)[1]
|
||||||
|
self.add_timer(value["event-name"], value["delay"], value[
|
||||||
|
"next-due"], id, **value["kwargs"])
|
||||||
|
def timer_setting(self, timer):
|
||||||
|
self.set_setting("timer-%s" % timer.id, {
|
||||||
|
"event-name": timer.event_name, "delay": timer.delay,
|
||||||
|
"next-due": timer.next_due, "kwargs": timer.kwargs})
|
||||||
|
def timer_setting_remove(self, timer):
|
||||||
|
self.timers.remove(timer)
|
||||||
|
self.del_setting("timer-%s" % timer.id)
|
||||||
|
def add_timer(self, event_name, delay, next_due=None, id=None, **kwargs):
|
||||||
|
timer = Timer.Timer(self, event_name, delay, next_due, **kwargs)
|
||||||
|
if id:
|
||||||
|
timer.id = id
|
||||||
|
else:
|
||||||
|
self.timer_setting(timer)
|
||||||
self.timers.append(timer)
|
self.timers.append(timer)
|
||||||
def next_timer(self):
|
def next_timer(self):
|
||||||
next = None
|
next = None
|
||||||
|
@ -50,10 +66,11 @@ class Bot(object):
|
||||||
def call_timers(self):
|
def call_timers(self):
|
||||||
for timer in self.timers[:]:
|
for timer in self.timers[:]:
|
||||||
if timer.due():
|
if timer.due():
|
||||||
print(timer.event_name)
|
|
||||||
timer.call()
|
timer.call()
|
||||||
if timer.done():
|
if timer.done():
|
||||||
self.timers.remove(timer)
|
self.timer_setting_remove(timer)
|
||||||
|
else:
|
||||||
|
self.timer_setting(timer)
|
||||||
|
|
||||||
def register_read(self, server):
|
def register_read(self, server):
|
||||||
self.poll.modify(server.fileno(), select.EPOLLIN)
|
self.poll.modify(server.fileno(), select.EPOLLIN)
|
||||||
|
|
10
IRCServer.py
10
IRCServer.py
|
@ -41,6 +41,7 @@ class Server(object):
|
||||||
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||||
self.socket = context.wrap_socket(self.socket)
|
self.socket = context.wrap_socket(self.socket)
|
||||||
self.cached_fileno = self.socket.fileno()
|
self.cached_fileno = self.socket.fileno()
|
||||||
|
self.bot.events.on("timer").on("rejoin").hook(self.try_rejoin)
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s:%s%s" % (self.target_hostname, "+" if self.tls else "",
|
return "%s:%s%s" % (self.target_hostname, "+" if self.tls else "",
|
||||||
self.port)
|
self.port)
|
||||||
|
@ -177,11 +178,12 @@ class Server(object):
|
||||||
self.send("PING :%s" % nonce)
|
self.send("PING :%s" % nonce)
|
||||||
def send_pong(self, nonce="hello"):
|
def send_pong(self, nonce="hello"):
|
||||||
self.send("PONG :%s" % nonce)
|
self.send("PONG :%s" % nonce)
|
||||||
def try_rejoin(self, timer, channel_name, key):
|
def try_rejoin(self, event):
|
||||||
if channel_name in self.attempted_join:
|
if event["server_id"] == self.id and event["channel_name"
|
||||||
self.send_join(channel_name, key)
|
] in self.attempted_join:
|
||||||
|
self.send_join(event["channel_name"], event["key"])
|
||||||
def send_join(self, channel_name, key=None):
|
def send_join(self, channel_name, key=None):
|
||||||
self.attempted_join[channel_name.lower()] = None
|
self.attempted_join[channel_name.lower()] = key
|
||||||
self.send("JOIN %s%s" % (channel_name,
|
self.send("JOIN %s%s" % (channel_name,
|
||||||
"" if key == None else " %s" % key))
|
"" if key == None else " %s" % key))
|
||||||
def send_part(self, channel_name, reason=None):
|
def send_part(self, channel_name, reason=None):
|
||||||
|
|
17
Timer.py
17
Timer.py
|
@ -1,22 +1,27 @@
|
||||||
import time
|
import time, uuid
|
||||||
|
|
||||||
class Timer(object):
|
class Timer(object):
|
||||||
def __init__(self, bot, event_name, delay, **kwargs):
|
def __init__(self, bot, event_name, delay, next_due=None, **kwargs):
|
||||||
|
self.id = uuid.uuid4().hex
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.event_name = event_name
|
self.event_name = event_name
|
||||||
self.delay = delay
|
self.delay = delay
|
||||||
|
if next_due:
|
||||||
|
self.next_due = next_due
|
||||||
|
else:
|
||||||
|
self.set_next_due()
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self._done = False
|
self._done = False
|
||||||
self.call_count = 0
|
self.call_count = 0
|
||||||
|
|
||||||
def set_started_time(self):
|
def set_next_due(self):
|
||||||
self.started_time = time.time()
|
self.next_due = time.time()+self.delay
|
||||||
|
|
||||||
def due(self):
|
def due(self):
|
||||||
return self.time_left() <= 0
|
return self.time_left() <= 0
|
||||||
|
|
||||||
def time_left(self):
|
def time_left(self):
|
||||||
return (self.started_time+self.delay)-time.time()
|
return self.next_due-time.time()
|
||||||
|
|
||||||
def call(self):
|
def call(self):
|
||||||
self._done = True
|
self._done = True
|
||||||
|
@ -26,7 +31,7 @@ class Timer(object):
|
||||||
|
|
||||||
def redo(self):
|
def redo(self):
|
||||||
self._done = False
|
self._done = False
|
||||||
self.set_started_time()
|
self.set_next_due()
|
||||||
|
|
||||||
def done(self):
|
def done(self):
|
||||||
return self._done
|
return self._done
|
||||||
|
|
|
@ -10,40 +10,8 @@ class Module(object):
|
||||||
bot.events.on("received").on("command").on("in").hook(
|
bot.events.on("received").on("command").on("in").hook(
|
||||||
self.in_command, min_args=2,
|
self.in_command, min_args=2,
|
||||||
help="Set a reminder", usage="<time> <message>")
|
help="Set a reminder", usage="<time> <message>")
|
||||||
bot.events.on("received").on("numeric").on("001").hook(
|
|
||||||
self.on_connect)
|
|
||||||
bot.events.on("timer").on("in").hook(self.timer_due)
|
bot.events.on("timer").on("in").hook(self.timer_due)
|
||||||
|
|
||||||
def on_connect(self, event):
|
|
||||||
self.load_reminders(event["server"])
|
|
||||||
|
|
||||||
def remove_timer(self, target, due_time, server_id, nickname, message):
|
|
||||||
setting = "in-%s" % nickname
|
|
||||||
reminders = self.bot.database.get_server_setting(server_id, setting, [])
|
|
||||||
try:
|
|
||||||
reminders.remove([target, due_time, server_id, nickname, message])
|
|
||||||
except:
|
|
||||||
print("failed to remove a reminder. huh.")
|
|
||||||
if reminders:
|
|
||||||
self.bot.database.set_server_setting(server_id,
|
|
||||||
setting, reminders)
|
|
||||||
else:
|
|
||||||
self.bot.database.del_server_setting(server_id,
|
|
||||||
setting)
|
|
||||||
|
|
||||||
def load_reminders(self, server):
|
|
||||||
reminders = server.find_settings("in-%")
|
|
||||||
for user_reminders in reminders:
|
|
||||||
for target, due_time, server_id, nickname, message in user_reminders[1]:
|
|
||||||
time_left = due_time-time.time()
|
|
||||||
if time_left > 0:
|
|
||||||
self.bot.add_timer("in", time_left, target=target,
|
|
||||||
due_time=due_time, server_id=server_id, nickname=nickname,
|
|
||||||
message=message)
|
|
||||||
else:
|
|
||||||
self.remove_timer(target, due_time, server_id, nickname,
|
|
||||||
message)
|
|
||||||
|
|
||||||
def in_command(self, event):
|
def in_command(self, event):
|
||||||
seconds = Utils.from_pretty_time(event["args_split"][0])
|
seconds = Utils.from_pretty_time(event["args_split"][0])
|
||||||
message = " ".join(event["args_split"][1:])
|
message = " ".join(event["args_split"][1:])
|
||||||
|
@ -51,12 +19,6 @@ class Module(object):
|
||||||
if seconds <= SECONDS_MAX:
|
if seconds <= SECONDS_MAX:
|
||||||
due_time = int(time.time())+seconds
|
due_time = int(time.time())+seconds
|
||||||
|
|
||||||
setting = "in-%s" % event["user"].nickname
|
|
||||||
reminders = event["server"].get_setting(setting, [])
|
|
||||||
reminders.append([event["target"].name, due_time,
|
|
||||||
event["server"].id, event["user"].nickname, message])
|
|
||||||
event["server"].set_setting(setting, reminders)
|
|
||||||
|
|
||||||
self.bot.add_timer("in", seconds,
|
self.bot.add_timer("in", seconds,
|
||||||
target=event["target"].name, due_time=due_time,
|
target=event["target"].name, due_time=due_time,
|
||||||
server_id=event["server"].id, nickname=event["user"].nickname,
|
server_id=event["server"].id, nickname=event["user"].nickname,
|
||||||
|
@ -77,5 +39,3 @@ class Module(object):
|
||||||
"%s, this is your reminder: %s" % (
|
"%s, this is your reminder: %s" % (
|
||||||
event["nickname"], event["message"]))
|
event["nickname"], event["message"]))
|
||||||
break
|
break
|
||||||
self.remove_timer(event["target"], event["due_time"],
|
|
||||||
event["server_id"], event["nickname"], event["message"])
|
|
||||||
|
|
Loading…
Reference in a new issue