Files
timerbot/Timer.py
T
2021-09-02 21:48:13 +02:00

125 lines
4.3 KiB
Python

import discord
import pickle
from discord.ext import commands, tasks
from dateutil.rrule import *
from dateutil.parser import *
from dateutil.tz import gettz
from datetime import datetime
class TrackTimer():
def __init__(self, id, what, when, channel, author):
self.id = id
self.what = what
self.when = when
self.channel = channel
self.author = author
self.remind = next(self.when)
self.tz = self.remind.tzinfo
self.validate()
def __str__(self):
return self.what
def __eq__(self, other):
return self.id == other
def valid(self):
return datetime.now(self.tz) < (self.remind)
def validate(self):
while not self.valid():
self.remind = next(self.when)
def status(self):
return f"I'm going to tell {self.author.display_name} to {self.what.replace(' my ', ' their ')} at {self.remind}"
def next(self):
self.remind = next(self.when)
return f"I'm going to tell you again at {self.remind}"
def shout(self):
return f"Hey {self.author.mention}! **Go {self.what.replace(' my ', ' your ')}!**"
class PickleTimer():
def __init__(self, id, what, when, ctx):
self.id = id
self.what = what
self.when = when
self.channel = ctx.channel.id
self.author = ctx.author.id
try:
self.guild = ctx.channel.guild.id
except:
pass
def __eq__(self, other):
return self.id == other
class Timer(commands.Cog):
"""Timer commands."""
def __init__(self, bot):
self.bot = bot
self.id = 1
self.check_timers.start()
self.timers = []
self.pickle_timers = []
self.tz = {"AWST": gettz("Australia/Perth"), "ACWST": gettz("Australia/Eucla")}
@commands.Cog.listener()
async def on_ready(self):
await self.bot.wait_until_ready()
file = open('timerlist', 'rb')
self.pickle_timers = pickle.load(file)
for timer in self.pickle_timers:
if timer.id >= self.id:
self.id = timer.id + 1
t_timer = await self.tracked_timer(timer)
t_timer.validate()
self.timers.append(t_timer)
async def tracked_timer(self, pt):
channel = await self.bot.fetch_channel(pt.channel)
user = await self.bot.fetch_user(pt.author)
repeat_rule = rrule(DAILY, parse(pt.when, fuzzy=True, tzinfos=self.tz))
return TrackTimer(pt.id, pt.what, iter(repeat_rule), channel, user)
@tasks.loop(seconds=2.0)
async def check_timers(self):
for timer in self.timers:
if not timer.valid():
await timer.channel.send(f"{timer.shout()} {timer.next()}")
def save(self):
with open('timerlist', 'wb') as file:
pickle.dump(self.pickle_timers, file)
@commands.command(pass_context=True, hidden=False)
async def remindme(self, ctx, what: str, *when: str,):
try:
when = " ".join(when)
repeat_rule = rrule(DAILY, parse(when, fuzzy=True, tzinfos=self.tz))
timer = TrackTimer(self.id, what, iter(repeat_rule), ctx.channel, ctx.author)
self.pickle_timers.append(PickleTimer(self.id, what, when, ctx))
self.timers.append(timer)
self.id += 1
msg = f"Fine. {timer.status()}"
self.save()
await ctx.channel.send(msg)
except Exception as e:
await ctx.channel.send(f"You idiot. Send the command right: {e}")
@commands.command(pass_context=True, hidden=True)
async def reminders(self, ctx):
if len(self.timers) > 0:
msg = "Here's what I'm gonna do:\n"
for timer in self.timers:
msg += f"\t{timer.id}:\t{timer.status()}\n"
msg += "*Use `!delete <id>` to delete a standing reminder*"
await ctx.channel.send(msg)
else:
await ctx.channel.send("Idiot. You have to set reminders first.")
@commands.command(pass_context=True, hidden=True)
async def delete(self, ctx, id: int):
self.timers.remove(id)
self.pickle_timers.remove(id)
self.save()
await ctx.channel.send(f"Fine. Deleting reminder {id}..")
def setup(bot):
bot.add_cog(Timer(bot))