class Locale(commands.Cog, name='Reminder'): def __init__(self, client, lang, logger, db, cursor): self.client = client self.lang = lang self.logger = logger self.db = db self.cursor = cursor self.edit = EditLocale(db, cursor) self.hand = Handler(client, lang, logger, db, cursor) @commands.command(name="update", usage="[arg]", help="Updates the meta data (date and time) of the event." "Per default all users which are slotted for the event, are" "messaged the changed time and date. If the arg '--supress' is given," "this is not the case.", brief="Updates the internal meta data (date and time) of the event.") @has_role(cfg["role"]) @commands.cooldown(1, 0.5, commands.BucketType.channel) @commands.guild_only() async def update(self, ctx, args=""): def getAllUser(): sql = "SELECT User FROM Slot WHERE Event = %s AND User IS NOT NULL;" self.cursor.execute(sql, [ctx.message.channel.id]) return [channel.guild.get_member(int(x[0])) for x in self.cursor.fetchall() if x[0].isnumeric()] channel = ctx.message.channel time = "" if (before := self.edit.getEvent(channel.id)) is not None: try: date = [int(x) for x in channel.name.split("-")[:3]] date = dt.date(*date) except ValueError: await ctx.message.delete() await channel.send(ctx.message.author.mention + " " + self.lang["update"]["command"]["date_error"].format(channel.name), delete_after=5) return async for msg in channel.history(limit=10, oldest_first=True): if content := re.findall(r"Eventstart:.*$", msg.content.replace("*", ""), re.MULTILINE): if msg.author == ctx.message.author: time = re.sub("[^0-9]", "", content[0]) break if time == "" or date == "": await ctx.message.delete() await channel.send(ctx.message.author.mention + " " + self.lang["update"]["command"]["error"].format(channel.name), delete_after=5) return else: if not (0 < int(time) < 2400): await channel.send(ctx.message.author.mention + " " + self.lang["update"]["command"]["time_error"].format(channel.name), delete_after=5) return time = time[:2] + ':' + time[2:] + ":00" self.edit.updateNotify(channel.id, str(before[0]) + " " + str(before[1]), str(date) + " " + str(time)) if self.edit.updateEvent(channel.id, channel.name, date, time): await channel.send(ctx.message.author.mention + " " + self.lang["update"]["command"]["success"].format(channel.name), delete_after=5) if args != "--suppress": for user in getAllUser(): await user.send(self.lang["update"]["command"]["broadcast"].format(channel.id, time)) else: await channel.send(ctx.message.author.mention + " " + self.lang["update"]["command"]["error"].format(channel.name), delete_after=5)
class Handler(commands.Cog): def __init__(self, client, lang, logger, db, cursor): self.client = client self.lang = lang self.logger = logger self.db = db self.cursor = cursor self.edit = EditLocale(db, cursor) self.util = Util(client, db, cursor) async def notify(self, event, user_id, delay): """ Calculates datetime for notification Args: event(string): ID of an event user_id(string): User ID delay(int): delay in sec. """ await asyncio.sleep(delay) user = self.client.get_user(int(user_id)) if user: sql = "SELECT Time FROM Notify WHERE Event = %s AND User = %s" self.cursor.execute(sql, [event, user_id]) result = self.cursor.fetchall() if not result: return now = dt.datetime.now() delta = (result[0][0] - now).total_seconds() if abs(delta) > 1200: return sql = "SELECT Name, Time FROM Event WHERE ID = %s;" self.cursor.execute(sql, [event]) result = self.cursor.fetchone() guild = self.client.get_guild(int(cfg['guild'])) nickname = guild.get_member(int(user_id)).display_name try: await user.send(self.lang["notify_global"]["noti"].format( nickname, str(result[0]), str(result[1]))) except discord.errors.Forbidden: log = "User: "******"\t" log += "Channel:" + str(event).ljust(20) + "\t" log += "Command: " + "Notify: discord.errors.Forbidden".ljust( 20) + "\t" self.logger.log(log) @commands.Cog.listener() async def on_ready(self): sql = "SELECT n.User, n.Time, n.Event FROM Notify n, User u \ WHERE n.User = u.ID AND u.Notify AND n.Enabled AND n.Time >= CURDATE();" self.cursor.execute(sql) result = self.cursor.fetchall() for elem in result: now = dt.datetime.now() delta = (elem[1] - now).total_seconds() if delta > 0: asyncio.create_task(self.notify(elem[2], elem[0], delta)) @commands.Cog.listener() async def on_guild_channel_update(self, before, after): if before.name != after.name: if (event := self.edit.getEvent(after.id)) is not None: author = self.util.get_channel_author(after) try: date = [int(x) for x in after.name.split("-")[:3]] date = dt.date(*date) except ValueError: await author.send( self.lang["update"]["auto"]["date_error"].format( after.name)) return self.edit.updateNotify(after.id, str(event[0]) + " " + str(event[1]), str(date) + " " + str(event[1])) if self.edit.updateEvent(after.id, after.name, date): await author.send( self.lang["update"]["auto"]["success"].format( after.name)) else: await author.send( self.lang["update"]["auto"]["error"].format(after.name) ) return