Пример #1
0
    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)
Пример #2
0
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)
Пример #3
0
    def __init__(self, db, cursor):
        self.db = db
        self.cursor = cursor

        self.notify = EditLocale(db, cursor)
Пример #4
0
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
Пример #5
0
class EditList:
    def __init__(self, db, cursor):
        self.db = db
        self.cursor = cursor

        self.notify = EditLocale(db, cursor)

    def slotEvent(self,
                  channel,
                  user_id,
                  num,
                  user_displayname=None,
                  force=False):
        """
               Slots a given user in the given slot
               Args:
                    channel (channel): Server channel
                    user_id (int): User ID
                    num (string): Number of the slot
                    user_displayname (string): User nickname (optional)
                    force (bool): If true, accept duplicates (optional)

               Returns:
                   (bool): if successful

        """

        sql = "SELECT User FROM Slot, Event WHERE Event.ID = Slot.Event and Event = %s and Number = %s and (NOT Event.Locked OR %s);"
        var = [channel.id, num, force]
        self.cursor.execute(sql, var)
        slot = self.cursor.fetchone()

        if slot is None or slot[0] is not None:
            return False

        sql = "SELECT ID, Nickname FROM User WHERE ID = %s;"
        self.cursor.execute(sql, [user_id])
        result = self.cursor.fetchone()

        if (not force) and (result is None):
            sql = "INSERT INTO User (ID, Nickname) VALUES (%s, %s);"
            var = [str(user_id), user_displayname]
            self.cursor.execute(sql, var)
            self.db.commit()
        elif not force and (result
                            is not None) and result[1] != user_displayname:
            sql = "UPDATE User SET Nickname= %s WHERE ID = %s;"
            var = [str(user_displayname), str(user_id)]
            self.cursor.execute(sql, var)
            self.db.commit()

        if not force:
            sql = "UPDATE Slot SET User = NULL WHERE STRCMP(User, %s) = 0 AND Event = %s;"
            var = [str(user_id), str(channel.id)]
            self.cursor.execute(sql, var)
            self.db.commit()

        self.notify.create(channel.id, user_id)

        try:
            sql = "UPDATE Slot SET User = %s WHERE Number = %s and Event = %s;"
            var = [user_id, num, channel.id]
            self.cursor.execute(sql, var)
            self.db.commit()

        except mysql.connector.errors.DatabaseError:
            return False

        return True

    def unslotEvent(self, channel, user_id="", slot=""):
        """
                Unslots a user or clears an slot from an Event
                Args:
                    channel (channel): Server channel
                    user_id (string): User ID
                    slot (string) ; Slotnumber

               Returns:
                   (bool): if successful

           """
        type = ['Number', 'User'][int(slot == "")]
        arg = [slot, user_id][int(slot == "")]

        sql = f"SELECT Number FROM Slot WHERE STRCMP({type} , %s) = 0 and Event = %s;"
        var = [arg, channel.id]
        self.cursor.execute(sql, var)
        result = self.cursor.fetchone()

        if result:

            sql = f"UPDATE Slot SET User = NULL WHERE STRCMP({type}, %s) = 0 and Event = %s;"
            var = [arg, channel.id]
            self.cursor.execute(sql, var)
            self.db.commit()

            self.notify.toggle(channel.id, user_id, True)

            return result[0]
        else:
            return False

    def addSlot(self, channel, slot, group, desc):
        """
               Adds a slot to a given event
               Args:
                    channel (channel): Server channel
                    slot (int): Slot-Number
                    group (string): Group-Number (counting form 0) or Group-Name
                    desc (string): Name

               Returns:
                   (bool): if successful

           """

        sql = "SELECT Description FROM Slot WHERE Event = %s and Number = %s;"
        var = [channel.id, slot]
        self.cursor.execute(sql, var)

        result = self.cursor.fetchone()

        # Pushes Reserve Slots
        if result and (result[0] == "Reserve" and not desc == "Reserve"):
            sql = "SELECT Number FROM Slot WHERE Event = %s and Description = %s"
            self.cursor.execute(sql, [channel.id, 'Reserve'])

            result = self.cursor.fetchall()
            new = [(int(x[0]) + 10, channel.id, x[0]) for x in result]

            sql = "UPDATE Slot SET Number = %s WHERE Event=%s and Number = %s"
            self.cursor.executemany(sql, new)
            self.db.commit()

        elif result:
            return False

        if group.isdigit():

            sql = "SELECT Number FROM SlotGroup WHERE Event = %s AND Number = %s;"
            self.cursor.execute(sql, [channel.id, group])

            if self.cursor.fetchall() is None:
                return False

        else:

            sql = "SELECT Number FROM SlotGroup WHERE Event = %s and Name = %s;"
            var = [channel.id, group]
            self.cursor.execute(sql, var)
            group = self.cursor.fetchone()[0]

            if not group:
                return False

        sql = "INSERT INTO Slot (Event, Number, Description, GroupNumber) VALUES (%s, %s, %s, %s);"
        var = [channel.id, slot, desc, group]
        self.cursor.execute(sql, var)
        self.db.commit()

        length = len(str(slot)) + len(desc) + 15

        sql = "UPDATE SlotGroup SET Length = Length + %s WHERE Number = %s and Event = %s;"
        var = [length, group, channel.id]

        self.cursor.execute(sql, var)
        self.db.commit()

        return True

    def delSlot(self, channel, slot):
        """
               Deletes a given slot
               Args:
                    channel (channel): Server channel
                    slot (string): Slot-Number

               Returns:
                   (bool): if successful

           """

        sql = "SELECT Description, GroupNumber FROM Slot WHERE Event = %s and Number = %s;"
        var = [channel.id, slot]
        self.cursor.execute(sql, var)
        desc = self.cursor.fetchone()
        if not desc:
            return False

        length = len(str(slot)) + len(desc[0]) + 15

        sql = "DELETE FROM Slot WHERE Event = %s AND Number = %s;"
        self.cursor.execute(sql, [channel.id, slot])
        self.db.commit()

        sql = "UPDATE SlotGroup SET Length = Length - %s WHERE Number = %s AND Event = %s"
        var = [length, desc[1], channel.id]
        self.cursor.execute(sql, var)
        self.db.commit()

        return True

    def editSlot(self, channel, slot, desc):
        """
               Edits a slot name
               Args:
                   channel (channel): Server channel
                   slot (string): Slot-Number
                   desc (string): Name

               Returns:
                   (bool): if successful

        """

        sql = "SELECT Description, GroupNumber FROM Slot WHERE Event = %s and Number = %s;"
        var = [channel.id, slot]
        self.cursor.execute(sql, var)
        old_desc = self.cursor.fetchone()
        if not old_desc:
            return False

        sql = "UPDATE Slot SET Description = %s WHERE Number = %s AND Event = %s;"
        var = [desc, slot, channel.id]
        self.cursor.execute(sql, var)
        self.db.commit()

        length = len(desc) - len(old_desc[0])

        sql = "UPDATE SlotGroup SET Length = Length + %s WHERE Event = %s AND Number = %s;"
        var = [length, channel.id, old_desc[1]]
        self.cursor.execute(sql, var)
        self.db.commit()

        return True

    def addGroup(self, channel, number, name=""):
        """
               Adds a slot-group to a given event
               Args:
                    channel (channel): Server channel
                    number (int): Group-Number (counting from 0)
                    name (string): Group-Name (optional)

               Returns:
                    (bool): if successful

           """
        sql = "SELECT Name, Number FROM SlotGroup WHERE Event = %s and Number = %s;"
        var = [channel.id, int(number)]
        self.cursor.execute(sql, var)
        result = self.cursor.fetchone()
        if result and result[0] == "Reserve":
            sql = "UPDATE SlotGroup SET Number = %s WHERE Event = %s and Name = %s"
            var = [int(number) + 1, channel.id, 'Reserve']
            self.cursor.execute(sql, var)
            self.db.commit()

        elif result:
            return False

        sql = "INSERT INTO SlotGroup (Number, Event, Name, Struct, Length) VALUES (%s, %s, %s, '\n', %s);"
        length = len(name) + 1
        var = [number, channel.id, name, length]
        self.cursor.execute(sql, var)
        self.db.commit()

        return True

    def delGroup(self, channel, group):
        """
                Deletes a slot from a given event
                Args:
                    channel (channel): Server channel
                    group (string): Group-Number (counting form 0) or Group-Name

                Returns:
                   (bool): if successful

        """

        if group.isdigit():
            sql = "SELECT Number FROM SlotGroup WHERE Event = %s AND Number = %s;"
            self.cursor.execute(sql, [channel.id, group])

            if self.cursor.fetchone() is None:
                return False

        else:
            sql = "SELECT Number FROM SlotGroup WHERE Event = %s AND Name = %s;"
            var = [channel.id, group]
            self.cursor.execute(sql, var)

            if not group:
                return False

            group = self.cursor.fetchone()[0]

        sql = "DELETE FROM Slot WHERE GroupNumber = %s AND Event = %s;"
        self.cursor.execute(sql, [group, channel.id])
        self.db.commit()

        sql = "DELETE FROM SlotGroup WHERE Number = %s AND Event = %s;"
        self.cursor.execute(sql, [group, channel.id])
        self.db.commit()

        return True

    def toggleLock(self, channel):
        """
        Toggles the lock on an event
        Args:
            channel (channel): Server channel

        Returns:
            (bool): if successful
        """

        sql = "UPDATE Event SET Locked = NOT Locked WHERE ID = %s;"
        self.cursor.execute(sql, [channel.id])
        self.db.commit()

        return self.cursor.rowcount == 1