126 lines
4.3 KiB
Python
126 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)
|
|
self.timers = []
|
|
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))
|