예제 #1
0
    async def add_xp(self, guild, user, amount_min, amount_max):
        """
        Adds xp to a specific user in that guild
        :param guild:
        :param user:
        :param amount_min:
        :param amount_max:
        :return:
        """
        conn = self.get_connection()
        if conn is not None:
            rand_amount = random.randrange(1, 10)

            # Creates new voice level entry
            handySQL.create_voice_level_entry(conn, user, guild)
            if guild is None:
                guild_id = 0
            else:
                guild_id = guild.id

            # Retreives the UniqueMemberID
            uniqueMemberID = handySQL.get_uniqueMemberID(conn, user.id, guild_id)

            sql = f"""UPDATE VoiceLevels SET ExperienceAmount = ExperienceAmount + {rand_amount} WHERE UniqueMemberID=?"""
            c = conn.cursor()
            c.execute(sql, (uniqueMemberID,))
            conn.commit()
        else:
            print("ERROR! conn was a None type")
예제 #2
0
    async def add_rep(self, message, member, author):
        """
        Adds the reputation to the file
        """
        conn = self.get_connection()

        # To avoid errors when commands are used in DMs
        try:
            guild_id = message.guild.id
        except AttributeError:
            guild_id = 0
        uniqueID = handySQL.get_uniqueMemberID(conn, member.id, guild_id)

        # Can the user rep yet?
        authorUniqueID = handySQL.get_uniqueMemberID(conn, author.id, guild_id)
        if not self.check_valid_time(conn, authorUniqueID):
            return False

        # Format the reputation message
        msg_list = message.content.split(" ")
        if len(msg_list) > 2:
            msg = " ".join(msg_list[2:])
        else:
            return False

        # Check if the rep is positive
        if msg.startswith("-"):
            isPositive = 0
            msg = msg[1:].strip()
        else:
            isPositive = 1

        # Add to DB
        c = conn.cursor()
        sql = """   INSERT INTO Reputations(
                        UniqueMemberID,
                        ReputationMessage,
                        CreatedAt,
                        AddedByUniqueMemberID,
                        IsPositive
                    )
                    VALUES (?,?,?,?,?)"""
        c.execute(sql, (uniqueID, msg, datetime.datetime.now(), authorUniqueID,
                        isPositive))
        conn.commit()
        return True
예제 #3
0
 async def create_embed(self, display_name, guild_id, user_id,
                        message_columns, reaction_columns):
     embed = discord.Embed(title=f"Statistics for {display_name}")
     conn = self.get_connection()
     c = conn.cursor()
     uniqueID = handySQL.get_uniqueMemberID(conn, user_id, guild_id)
     for column in message_columns:
         sql = f"""  SELECT UniqueMemberID, SUM({column}) as sm
                     FROM UserMessageStatistic
                     GROUP BY UniqueMemberID
                     ORDER BY sm DESC"""
         rank = 0
         val = None
         for row in c.execute(sql):
             rank += 1
             if row[0] == uniqueID:
                 val = row[1]
                 break
         if val is None:
             continue
         if column == "FileTotalSize":
             val = round(val / 1000000.0, 2)
             val = f"{val} MB"
         embed.add_field(name=column, value=f"{val} *({rank}.)*\n")
     for column in reaction_columns:
         sql = f"""  SELECT UniqueMemberID, SUM({column}) as sm
                     FROM UserReactionStatistic
                     GROUP BY UniqueMemberID
                     ORDER BY sm DESC"""
         rank = 0
         val = None
         for row in c.execute(sql):
             rank += 1
             if row[0] == uniqueID:
                 val = row[1]
                 break
         if val is None:
             continue
         embed.add_field(name=column, value=f"{val} *({rank}.)*\n")
     return embed
예제 #4
0
    async def moveToDB(self, ctx, file=""):
        """
        Used to move data from json files to the database
        Permissions: Owner
        """
        conn = self.get_connection()
        if await self.bot.is_owner(ctx.author):
            if file == "levels":
                with open("./data/levels.json", "r") as f:
                    levels = json.load(f)
                for guild_id in levels:
                    count = 0
                    guild_obj = self.bot.get_guild(int(guild_id))
                    if guild_obj is None:
                        print(f"Didn't find Guild with ID: {guild_id}")
                        continue
                    for member_id in levels[guild_id]:
                        if member_id == "on":
                            continue
                        member_obj = guild_obj.get_member(int(member_id))
                        if member_obj is None:
                            print(f"Didn't find Member with ID: {member_id}")
                            continue

                        handySQL.create_voice_level_entry(
                            conn, member_obj, guild_obj)
                        uniqueID = handySQL.get_uniqueMemberID(
                            conn, member_id, guild_id)
                        conn.execute(
                            "UPDATE VoiceLevels SET ExperienceAmount=? WHERE UniqueMemberID=?",
                            (levels[guild_id][member_id], uniqueID))
                        conn.commit()
                        count += 1
                    await ctx.send(
                        f"{count} successful DB entry transfers on guild `{guild_obj.name}`"
                    )
            elif file == "covid":
                with open("./data/covid_points.json", "r") as f:
                    covid = json.load(f)
                for guild in covid:
                    count = 0
                    guild_obj = self.bot.get_guild(int(guild))
                    if guild_obj is None:
                        print(f"Didn't find Guild with ID: {guild}")
                        continue
                    for member in covid[guild]:
                        member_obj = guild_obj.get_member(int(member))
                        if member_obj is None:
                            print(f"Didn't find Member with ID: {member}")
                            continue
                        handySQL.create_covid_guessing_entry(
                            conn, member_obj, guild_obj)
                        uniqueID = handySQL.get_uniqueMemberID(
                            conn, member, guild)
                        total = int(covid[guild][member][1])
                        guessCount = covid[guild][member][2]
                        conn.execute(
                            "UPDATE CovidGuessing SET TotalPointsAmount=?, GuessCount=? WHERE UniqueMemberID=?",
                            (total, guessCount, uniqueID))
                        conn.commit()
                        count += 1
                    await ctx.send(
                        f"{count} successful DB entry transfers on guild `{guild_obj.name}`"
                    )
            elif file == "statistics":
                with open("./data/statistics.json", "r") as f:
                    statistics = json.load(f)
                for guild in statistics:
                    guild_obj = self.bot.get_guild(int(guild))
                    if guild_obj is None:
                        print(f"Didn't find Guild with ID: {guild}")
                        continue
                    count = 0
                    for member in statistics[guild]["messages_sent"]:
                        member_obj = guild_obj.get_member(int(member))
                        if member_obj is None:
                            print(f"Didn't find Member with ID: {member}")
                            continue
                        # Create DB entries
                        msg_result = handySQL.create_message_statistic_entry(
                            conn, member_obj, guild_obj, 0,
                            "UserMessageStatistic")
                        reaction_result = handySQL.create_message_statistic_entry(
                            conn, member_obj, guild_obj, 0,
                            "UserReactionStatistic")
                        uniqueID = handySQL.get_uniqueMemberID(
                            conn, member, guild)
                        sql = """   UPDATE UserMessageStatistic
                                    SET
                                        MessageSentCount=?,
                                        MessageDeletedCount=?,
                                        MessageEditedCount=?,
                                        CharacterCount=?,
                                        WordCount=?,
                                        SpoilerCount=?,
                                        EmojiCount=?,
                                        FileSentCount=?
                                    WHERE UniqueMemberID=? AND SubjectID=0
                                    """
                        s = statistics[guild]
                        for v in ("messages_sent", "messages_deleted",
                                  "messages_edited", "chars_sent",
                                  "words_sent", "spoilers", "emojis",
                                  "files_sent", "reactions_added",
                                  "reactions_received"):
                            if member not in s[v]:
                                s[v][member] = 0
                        conn.execute(
                            sql,
                            (s["messages_sent"][member],
                             s["messages_deleted"][member],
                             s["messages_edited"][member],
                             s["chars_sent"][member], s["words_sent"][member],
                             s["spoilers"][member], s["emojis"][member],
                             s["files_sent"][member], uniqueID))
                        sql = """   UPDATE UserReactionStatistic
                                    SET
                                        ReactionAddedCount=?,
                                        GottenReactionCount=?
                                    WHERE UniqueMemberID=? AND SubjectID=0"""
                        conn.execute(
                            sql, (s["reactions_added"][member],
                                  s["reactions_received"][member], uniqueID))
                        conn.commit()
                        if not msg_result[0]:
                            print(f"Message {msg_result[2]}")
                        if not reaction_result[0]:
                            print(f"Reaction {reaction_result[2]}")
                        if reaction_result[0] and msg_result[0]:
                            count += 1
                    await ctx.send(
                        f"{count} successful DB entry transfers on guild `{guild_obj.name}`"
                    )
            elif file == "reputations":
                with open("./data/reputation.json", "r") as f:
                    reputations = json.load(f)
                for guild in reputations:
                    guild_obj = self.bot.get_guild(int(guild))
                    if guild_obj is None:
                        print(f"Didn't find Guild with ID: {guild}")
                        continue
                    count = 0
                    for member in reputations[guild]["rep"]:
                        member_obj = guild_obj.get_member(int(member))
                        if member_obj is None:
                            print(f"Didn't find Member with ID: {member}")
                            continue
                        for message in reputations[guild]["rep"][member]:
                            sql = """   INSERT INTO Reputations(
                                            UniqueMemberID,
                                            ReputationMessage,
                                            IsPositive)
                                        VALUES (?,?,?)"""
                            uniqueID = handySQL.get_or_create_member(
                                conn, member_obj, guild_obj)
                            # Check if the rep is positive
                            if message.startswith("-"):
                                isPositive = 0
                            else:
                                isPositive = 1
                            conn.execute(sql, (uniqueID, message, isPositive))
                            conn.commit()
                            count += 1
                    await ctx.send(
                        f"{count} successful DB entry transfers on guild `{guild_obj.name}`"
                    )
            else:
                await ctx.send("Unknown file")
        else:
            raise discord.ext.commands.errors.NotOwner
예제 #5
0
    async def moveToDB(self, ctx, file=""):
        """
        Used to move data from json files to the database
        Permissions: Owner
        """
        conn = self.get_connection()
        if await self.bot.is_owner(ctx.author):
            if file == "levels":
                with open("./data/levels.json", "r") as f:
                    levels = json.load(f)
                for guild_id in levels:
                    count = 0
                    guild_obj = self.bot.get_guild(int(guild_id))
                    if guild_obj is None:
                        print(f"Didn't find Guild with ID: {guild_id}")
                        continue
                    for member_id in levels[guild_id]:
                        if member_id == "on":
                            continue
                        member_obj = guild_obj.get_member(int(member_id))
                        if member_obj is None:
                            print(f"Didn't find Member with ID: {member_id}")
                            continue

                        handySQL.create_voice_level_entry(conn, member_obj, guild_obj)
                        uniqueID = handySQL.get_uniqueMemberID(conn, member_id, guild_id)
                        conn.execute("UPDATE VoiceLevels SET ExperienceAmount=? WHERE UniqueMemberID=?", (levels[guild_id][member_id], uniqueID))
                        conn.commit()
                        count += 1
                    await ctx.send(f"{count} successful DB entry transfers on guild `{guild_obj.name}`")
            elif file == "covid":
                with open("./data/covid_points.json", "r") as f:
                    covid = json.load(f)
                for guild in covid:
                    count = 0
                    guild_obj = self.bot.get_guild(int(guild))
                    if guild_obj is None:
                        print(f"Didn't find Guild with ID: {guild}")
                        continue
                    for member in covid[guild]:
                        member_obj = guild_obj.get_member(int(member))
                        if member_obj is None:
                            print(f"Didn't find Member with ID: {member}")
                            continue
                        handySQL.create_covid_guessing_entry(conn, member_obj, guild_obj)
                        uniqueID = handySQL.get_uniqueMemberID(conn, member, guild)
                        total = int(covid[guild][member][1])
                        guessCount = covid[guild][member][2]
                        conn.execute("UPDATE CovidGuessing SET TotalPointsAmount=?, GuessCount=? WHERE UniqueMemberID=?", (total, guessCount, uniqueID))
                        conn.commit()
                        count += 1
                    await ctx.send(f"{count} successful DB entry transfers on guild `{guild_obj.name}`")
            elif file == "statistics":
                with open("./data/statistics.json", "r") as f:
                    statistics = json.load(f)
                for guild in statistics:
                    guild_obj = self.bot.get_guild(int(guild))
                    if guild_obj is None:
                        print(f"Didn't find Guild with ID: {guild}")
                        continue
                    count = 0
                    for member in statistics[guild]["messages_sent"]:
                        member_obj = guild_obj.get_member(int(member))
                        if member_obj is None:
                            print(f"Didn't find Member with ID: {member}")
                            continue
                        # Create DB entries
                        msg_result = handySQL.create_message_statistic_entry(conn, member_obj, guild_obj, 0, "UserMessageStatistic")
                        reaction_result = handySQL.create_message_statistic_entry(conn, member_obj, guild_obj, 0, "UserReactionStatistic")
                        uniqueID = handySQL.get_uniqueMemberID(conn, member, guild)
                        sql = """   UPDATE UserMessageStatistic
                                    SET
                                        MessageSentCount=?,
                                        MessageDeletedCount=?,
                                        MessageEditedCount=?,
                                        CharacterCount=?,
                                        WordCount=?,
                                        SpoilerCount=?,
                                        EmojiCount=?,
                                        FileSentCount=?
                                    WHERE UniqueMemberID=? AND SubjectID=0
                                    """
                        s = statistics[guild]
                        for v in ("messages_sent", "messages_deleted", "messages_edited", "chars_sent", "words_sent", "spoilers", "emojis", "files_sent", "reactions_added", "reactions_received"):
                            if member not in s[v]:
                                s[v][member] = 0
                        conn.execute(sql, (
                            s["messages_sent"][member],
                            s["messages_deleted"][member],
                            s["messages_edited"][member],
                            s["chars_sent"][member],
                            s["words_sent"][member],
                            s["spoilers"][member],
                            s["emojis"][member],
                            s["files_sent"][member],
                            uniqueID
                        ))
                        sql = """   UPDATE UserReactionStatistic
                                    SET
                                        ReactionAddedCount=?,
                                        GottenReactionCount=?
                                    WHERE UniqueMemberID=? AND SubjectID=0"""
                        conn.execute(sql, (
                            s["reactions_added"][member],
                            s["reactions_received"][member],
                            uniqueID
                        ))
                        conn.commit()
                        if not msg_result[0]:
                            print(f"Message {msg_result[2]}")
                        if not reaction_result[0]:
                            print(f"Reaction {reaction_result[2]}")
                        if reaction_result[0] and msg_result[0]:
                            count += 1
                    await ctx.send(f"{count} successful DB entry transfers on guild `{guild_obj.name}`")
            elif file == "reputations":
                with open("./data/reputation.json", "r") as f:
                    reputations = json.load(f)
                for guild in reputations:
                    guild_obj = self.bot.get_guild(int(guild))
                    if guild_obj is None:
                        print(f"Didn't find Guild with ID: {guild}")
                        continue
                    count = 0
                    for member in reputations[guild]["rep"]:
                        member_obj = guild_obj.get_member(int(member))
                        if member_obj is None:
                            print(f"Didn't find Member with ID: {member}")
                            continue
                        for message in reputations[guild]["rep"][member]:
                            sql = """   INSERT INTO Reputations(
                                            UniqueMemberID,
                                            ReputationMessage,
                                            IsPositive)
                                        VALUES (?,?,?)"""
                            uniqueID = handySQL.get_or_create_member(conn, member_obj, guild_obj)
                            # Check if the rep is positive
                            if message.startswith("-"):
                                isPositive = 0
                            else:
                                isPositive = 1
                            conn.execute(sql, (uniqueID, message, isPositive))
                            conn.commit()
                            count += 1
                    await ctx.send(f"{count} successful DB entry transfers on guild `{guild_obj.name}`")
            elif file == "quotes":
                with open("./data/quotes.json", "r") as f:
                    quotes = json.load(f)
                for guild_id in quotes:
                    finished = []
                    total_count = 0
                    count = 0
                    guild_obj = self.bot.get_guild(int(guild_id))
                    if guild_obj is None:
                        print(f"Didn't find Guild with ID: {guild_id}")
                        continue
                    for name in quotes[guild_id]:
                        if len(quotes[guild_id][name]) == 0:
                            continue
                        try:
                            member = discord.utils.find(lambda m: m.name.lower() == name, guild_obj.members)
                        except discord.ext.commands.errors.UserNotFound:
                            member = None
                        uniqueID = None
                        quoted_name = name
                        if member is not None:
                            uniqueID = handySQL.get_uniqueMemberID(conn, member.id, guild_id)
                            quoted_name = member.name
                        for q in quotes[guild_id][name]:
                            if not isascii(q[1]):
                                continue
                            date = datetime.strptime(q[0], "%d/%m/%Y").strftime("%Y-%m-%d %H:%M:%S")
                            sql = """   INSERT INTO Quotes(Quote, Name, UniqueMemberID, DiscordGuildID, CreatedAt)
                                        VALUES(?,?,?,?,?)"""
                            conn.execute(sql, (q[1], quoted_name, uniqueID, guild_id, date))
                            conn.commit()
                            count += 1
                            total_count += 1
                        finished.append(quoted_name)

                        if count >= 200:
                            await ctx.send(f"{count} successful DB entry transfers for names:\n`{', '.join(finished)}`")
                            finished = []
                            count = 0
                    if len(finished) > 0:
                        await ctx.send(f"{count} successful DB entry transfers for names:\n`{', '.join(finished)}`")
                    await ctx.send(f"{total_count} successful DB entry transfers on guild `{guild_obj.name}`")

            else:
                await ctx.send("Unknown file")
        else:
            raise discord.ext.commands.errors.NotOwner
예제 #6
0
    async def event(self, ctx, command=None, event_name=None, date=None, event_time=None, *event_info):
        """
        - The event command is used to keep track of upcoming events. Each user can add a maximum of two events (this might get changed).
        - When creating an event, the **event name** has to be in quotes if there are multiple words and it can be a maximum of 50 characters, \
        any more and the name gets cut off with "...".
        - The description can be a maximum of 700 characters, any more and it gets cut off with "...".
        - **Date** needs to be in the format `DD.MM.YYYY` or `DD.MM.YY` or `DD-MM-YYYY` or `DD-MM-YY`.
        - **Time** needs to be in the format `HH:MM`.

        Events can also be joined/left with the `join` and `leave` keywords , so you can see how many would even be up for an event. \
        In the future you will also get a ping when the event starts.

        Some examples:
        - `$event add "My Birthday" 13.03.2021 00:00 This day is my birthday hehe :)`
        - `$event add 420BlazeIt 20.4.21 4:20 Send me a dm if you wanna join this event!`
        - `$event join 420BlazeIt`
        """
        conn = self.get_connection()
        c = conn.cursor()
        try:
            guild_id = ctx.message.guild.id
            guild_name = ctx.message.guild.name
        except AttributeError:
            guild_id = 0
            guild_name = "Direct Message"

        # Deletes all older events
        c.execute("DELETE FROM Events WHERE EventStartingAt < ?", (str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")), ))
        conn.commit()

        if command is None:
            # list all upcoming events sorted by upcoming order
            sql = """   SELECT E.EventName, E.EventStartingAt
                        FROM Events E
                        INNER JOIN DiscordMembers DM on DM.UniqueMemberID = E.UniqueMemberID
                        WHERE DM.DiscordGuildID=?
                        ORDER BY E.EventStartingAt"""
            c.execute(sql, (guild_id,))
            results = c.fetchall()
            i = 0
            embed = discord.Embed(title=f"Upcoming Events On {guild_name}", color=0xFCF4A3)
            embed.set_footer(text="$event view <name> to get more details about an event")
            for e in results:
                if i == 10:
                    # a max of 10 events are shown
                    break
                dt = datetime.strptime(e[1], "%Y-%m-%d %H:%M:%S")
                form_time = starting_in(e[1])
                embed.add_field(name=e[0], value=f"**At:** {dt}\n**In:** {form_time}")
                i += 1
            if len(results) == 0:
                embed.description = "-- There are no upcoming events --"
            await ctx.send(embed=embed)
        elif command.lower() == "add":
            # check if uniquememberid already exists in db
            uniqueID = handySQL.get_uniqueMemberID(conn, ctx.message.author.id, guild_id)
            c.execute("SELECT EventName FROM Events WHERE UniqueMemberID=?", (uniqueID,))
            result = c.fetchall()
            if len(result) < 2:
                # add the event to the db
                # Make sure the inputs are correct
                if event_name is None or date is None or event_time is None:
                    await ctx.send("ERROR! Incorrect arguments given. Check `$help event` to get more "
                                   f"info about the event command.", delete_after=10)
                    raise discord.ext.commands.errors.BadArgument
                date = format_input_date(date)
                if not date:
                    await ctx.send("ERROR! Incorrect date format given or date is passed. Should be `DD.MM.YYYY` or `DD-MM-YYYY`. Check `$help event` to get more "
                                   f"info about the event command.", delete_after=10)
                    raise discord.ext.commands.errors.BadArgument
                event_time = format_input_time(event_time)
                if not event_time:
                    await ctx.send("ERROR! Incorrect time format given. Should be `HH:MM`. Check `$help event` to get more "
                                   f"info about the event command.", delete_after=10)
                    raise discord.ext.commands.errors.BadArgument

                # Adds the entry to the sql db
                event_description = " ".join(event_info)
                if len(event_description) > 700:
                    event_description = event_description[0: 700] + "..."
                if len(event_name) > 50:
                    event_name = event_name[0: 50] + "..."

                # Check if the same already exists and throw an error if needed
                c.execute("SELECT * FROM Events WHERE EventName LIKE ?", (event_name,))
                if c.fetchone() is not None:
                    await ctx.send("ERROR! There already exists an event with said name! Use a different event name.", delete_after=10)
                    raise discord.ext.commands.errors.BadArgument

                try:
                    dt = datetime(date["year"], date["month"], date["day"], event_time["hour"], event_time["minute"])
                except ValueError:
                    await ctx.send(
                        "ERROR! Incorrect date format given or date is passed. Should be `DD.MM.YYYY` or `DD-MM-YYYY`. Check `$help event` to get more "
                        f"info about the event command.", delete_after=10)
                    raise discord.ext.commands.errors.BadArgument

                # Inserts event into event database
                c.execute("INSERT INTO Events(EventName, EventCreatedAt, EventStartingAt, EventDescription, UniqueMemberID) VALUES (?,?,?,?,?)",
                          (event_name, str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")), str(dt), event_description, uniqueID))
                conn.commit()

                # Inserts user as host to EventJoinedUsers for the newly added event
                row_id = c.lastrowid
                c.execute("SELECT EventID FROM Events WHERE ROWID=?", (row_id,))
                event_id = c.fetchone()[0]
                c.execute("INSERT INTO EventJoinedUsers(EventID, UniqueMemberID, IsHost) VALUES (?,?,?)", (event_id, uniqueID, 1))
                conn.commit()

                # Creates and sends the embed message
                embed = discord.Embed(title="Added New Event", color=0xFCF4A3)
                embed.add_field(name="Event Name", value=event_name, inline=False)
                embed.add_field(name="Event Host", value=ctx.message.author.mention, inline=False)
                embed.add_field(name="Event Starting At", value=str(dt), inline=False)
                embed.add_field(name="Event Description", value=event_description, inline=False)
                await ctx.send(embed=embed)
            else:
                await ctx.send("ERROR! Each member can only add **two** events. (Might get changed in the future)", delete_after=10)
                raise discord.ext.commands.errors.BadArgument
        elif command.lower() == "view":
            if event_name is None:
                await ctx.send(f"ERROR! {ctx.message.author.mention}, you did not specify what event to view. Check `$help event` to get more "
                               f"info about the event command.", delete_after=10)
                raise discord.ext.commands.errors.BadArgument
            else:
                sql = """   SELECT E.EventName, E.EventCreatedAt, E.EventStartingAt, E.EventDescription, DM.DiscordUserID, EventID
                            FROM Events E
                            INNER JOIN DiscordMembers DM on E.UniqueMemberID = DM.UniqueMemberID
                            WHERE E.EventName LIKE ? AND DM.DiscordGuildID=?
                            ORDER BY E.EventStartingAt"""
                c.execute(sql, (f"%{event_name}%", guild_id))
                results = c.fetchall()
                if len(results) == 0:
                    await ctx.send("ERROR! There is no event with a similar name. Simply type `$event` to get a list of upcoming events.", delete_after=10)
                    raise discord.ext.commands.errors.BadArgument
                embed = discord.Embed(title="Indepth Event View", color=0xFCF4A3)
                if len(results) > 2:
                    embed.add_field(name="NOTICE",
                                    value="*There are more than 2 matches with that event name. Only showing the two closest matching events.*",
                                    inline=False)
                    embed.add_field(name="\u200b", value="``` ```", inline=False)
                i = 1
                MAX_EVENTS = 2  # max amount of events to send per view command
                for e in results:
                    # creates a list of all joined members
                    sql = """   SELECT D.DiscordUserID
                                FROM EventJoinedUsers E 
                                INNER JOIN DiscordMembers D on D.UniqueMemberID = E.UniqueMemberID
                                WHERE E.EventID=?"""
                    c.execute(sql, (e[5],))
                    res = c.fetchall()
                    joined_users_msg = f"Total: {len(res)}"
                    counter = 0
                    for row in res:
                        joined_users_msg += f"\n> <@{row[0]}>"
                        if counter >= 10:
                            break
                        counter += 1

                    embed.add_field(name="Event Name", value=e[0])
                    embed.add_field(name="Host", value=f"<@{e[4]}>")
                    embed.add_field(name="Joined Users", value=joined_users_msg)
                    embed.add_field(name="Date", value=e[2])
                    embed.add_field(name="Starting in", value=starting_in(e[2]))
                    embed.add_field(name="Created on", value=e[1])
                    embed.add_field(name="Event Description", value=e[3])

                    # if not last field, add a spacer
                    if i < MAX_EVENTS and i < len(results):
                        embed.add_field(name="\u200b", value="``` ```", inline=False)
                    i += 1
                    if i > MAX_EVENTS:
                        break
                embed.set_footer(text="Join an event with $event join <event name>")
                await ctx.send(embed=embed)
        elif command.lower() == "delete":
            # delete the entry
            uniqueID = handySQL.get_uniqueMemberID(conn, ctx.message.author.id, guild_id)
            if event_name is None:
                event_name = ""
            c.execute("SELECT EventName FROM Events WHERE UniqueMemberID=? AND EventName LIKE ?", (uniqueID, f"%{event_name}%"))
            result = c.fetchall()
            if len(result) == 0:
                await ctx.send("ERROR! You don't have any active events or you might have misspelled the event name.")
                raise discord.ext.commands.errors.BadArgument
            if len(result) > 1:
                await ctx.send("ERROR! There are multiple events matching that name. Type the whole name to delete the event.\n"
                               f'`$event delete "{result[0][0]}"` or\n'
                               f'`$event delete "{result[1][0]}"`')
                raise discord.ext.commands.errors.BadArgument
            ev_name = result[0][0]
            if event_name is None or event_name.lower() != ev_name.lower():
                await ctx.send("ERROR! You did not specify what event to delete. To delete your event type "
                               f'`$event delete "{ev_name}"`')
                raise discord.ext.commands.errors.BadArgument
            c.execute("DELETE FROM Events WHERE UniqueMemberID=? AND EventName=?", (uniqueID, ev_name))
            conn.commit()
            embed = discord.Embed(title="Deleted Event",
                                  description=f"**Name of deleted event:** {event_name}\n"
                                              f"**Event host:** {ctx.message.author.mention}",
                                  color=0xFCF4A3)
            await ctx.send(embed=embed)
        elif command.lower() in ["join", "leave"]:
            if event_name is None:
                await ctx.send(f"ERROR! {ctx.message.author.mention}, you did not specify what event to {command.lower()}. Check `$help event` to get more "
                               f"info about the event command.", delete_after=10)
                raise discord.ext.commands.errors.BadArgument
            sql = """   SELECT E.EventID, E.EventName
                        FROM Events E
                        INNER JOIN DiscordMembers D on D.UniqueMemberID = E.UniqueMemberID
                        WHERE E.EventName LIKE ? AND D.DiscordGuildID=?"""
            c.execute(sql, (event_name, guild_id))
            event_result = c.fetchone()
            if event_result is None:
                await ctx.send(f"ERROR! {ctx.message.author.mention}, could not find an event with that name.", delete_after=10)
                raise discord.ext.commands.errors.BadArgument

            # Checks if the user already joined the event
            uniqueID = handySQL.get_uniqueMemberID(conn, ctx.message.author.id, guild_id)
            c.execute("SELECT IsHost FROM EventJoinedUsers WHERE EventID=? AND UniqueMemberID=?", (event_result[0], uniqueID))
            res = c.fetchone()

            if command.lower() == "join":
                if res is not None:
                    if res[0] == 1:
                        await ctx.send(f"ERROR! {ctx.message.author.mention}, you are the host of the event `{event_result[1]}`. "
                                       f"You don't need to join.", delete_after=10)
                    else:
                        await ctx.send(f"ERROR! {ctx.message.author.mention}, you already joined the event `{event_result[1]}`.", delete_after=10)
                    raise discord.ext.commands.errors.BadArgument

                # Joins the user to the event
                c.execute("INSERT INTO EventJoinedUsers(EventID, UniqueMemberID) VALUES (?,?)", (event_result[0], uniqueID))
                conn.commit()
                embed = discord.Embed(
                    title="Joined Event",
                    description=f"Added {ctx.message.author.mention} to event `{event_result[1]}`."
                                f"You can leave the event with `$event leave \"{event_result[1]}\"`",
                    color=0xFCF4A3)
                await ctx.send(embed=embed)
            elif command.lower() == "leave":
                if res is None:
                    await ctx.send(f"ERROR! {ctx.message.author.mention}, you can't leave an event you haven't even joined yet. "
                                   f"The event in question: `{event_result[1]}`.", delete_after=10)
                    raise discord.ext.commands.errors.BadArgument
                if res[0] == 1:
                    await ctx.send(f"ERROR! {ctx.message.author.mention}, you are the host of `{event_result[1]}`. "
                                   f"You can't leave events you are the host of.", delete_after=10)
                    raise discord.ext.commands.errors.BadArgument

                # Removes the user from that event
                c.execute("DELETE FROM EventJoinedUsers WHERE EventID=? AND UniqueMemberID=?", (event_result[0], uniqueID))
                conn.commit()

                embed = discord.Embed(
                    title="Left Event",
                    description=f"Removed {ctx.message.author.mention} from event `{event_result[1]}`."
                                f"You can rejoin the event with `$event join \"{event_result[1]}\"`",
                    color=0xffa500)
                await ctx.send(embed=embed)

        else:
            await ctx.send(f"ERROR! {ctx.message.author.mention}, the command you used is not recognized. Check `$help event` to get more "
                           f"info about the event command.", delete_after=10)
            raise discord.ext.commands.errors.BadArgument
예제 #7
0
    async def quote(self, ctx, name=None, *quote):
        """
        Sends a completely random quote from the server if all parameters are empty. \
        If only a name is given, it sends a random quote from that user.
        By using `-name` for any name that has quotes you can display a random quote from that person \
        directly.

        Some examples:
        `$quote`   - sends a random quote from any user
        `$quote ueli`   - sends a random quote from the user ueli
        `$quote ueli haHaa`   - adds "haHaa" as a quote to the user ueli
        `$quote ueli all`   - displays all quotes from the user ueli
        `$quote ueli 23`   - displays the 23rd indexed quote from the user ueli
        `$quote names`   - displays all names that have a quote
        `-ueli`   - displays a random quote from the one and only ueli
        """

        # Get the guild ID or returns an error message
        try:
            guild_id = ctx.message.guild.id
        except AttributeError:
            await ctx.send(
                "Quotes are currently not supported in private messages")
            raise discord.ext.commands.BadArgument

        # creates the db connection
        conn = self.get_connection()
        c = conn.cursor()
        if name is not None:
            if name.lower() in ["del", "all"]:
                embed = discord.Embed(
                    title="Quote Error",
                    description=
                    f"Can't use `all` or `del` as names. Did you mean to do `$quote <user> {name.lower()}`?",
                    color=0xFF0000)
                await ctx.send(embed=embed)
                raise discord.ext.commands.errors.BadArgument
            if name == "names":
                # lists all names/discord id's of users with quotes
                sql = """   SELECT Q.Name, Q.UniqueMemberID
                            FROM Quotes Q
                            WHERE Q.DiscordGuildID=?
                            GROUP BY Q.Name
                            ORDER BY COUNT(*) DESC"""
                c.execute(sql, (guild_id, ))
                res = c.fetchall()

                embed = discord.Embed(title="Quote Names")
                # If there are no quotes on the server
                if len(res) == 0:
                    embed = discord.Embed(
                        title="Quote Error",
                        description="There are no quotes on this server yet.",
                        color=0xFF0000)
                    await ctx.send(embed=embed)
                    raise discord.ext.commands.errors.BadArgument
                else:
                    embed.description = "Everybody with a quote as of now:"
                    MAX_FIELDS = 21
                    per_field = math.ceil(
                        len(res) / MAX_FIELDS
                    )  # the amount of names per field to have a max of 21 fields
                    index = 0

                    # splits the names into the given amount of MAX_FIELDS
                    msg_number = 1
                    while len(res[index:]) > 0:
                        field_msg = ""
                        for row in res[index:index + per_field]:
                            if row[1] is None:
                                quoted_name = row[0]
                            else:
                                quoted_name = f"<@{handySQL.get_DiscordUserID(conn, row[1])}>"
                            field_msg += f"- {quoted_name}\n"
                        embed.add_field(name=f"Field #{msg_number}",
                                        value=field_msg)
                        index += per_field
                        msg_number += 1
                    await ctx.send(embed=embed)
            else:
                # first checks if its a valid discord user ID. If not, sets member to None
                try:
                    user_id = name.replace("<@",
                                           "").replace(">",
                                                       "").replace("!", "")
                    member = ctx.message.guild.get_member(int(user_id))
                    uniqueID = handySQL.get_uniqueMemberID(
                        conn, user_id, guild_id)
                except ValueError:
                    print("Not a discord member ID")
                    member = None
                    uniqueID = -1

                # if there is only a name/ID given, send a random quote from that user
                if len(quote) == 0:
                    if name.lower() in ["del", "all"]:
                        embed = discord.Embed(
                            title="Quotes Error",
                            description=
                            f"Incorrect arguments for delete/add command.",
                            color=0xFF0000)
                        await ctx.send(embed=embed)
                        raise discord.ext.commands.BadArgument

                    # tries to first query if its a quote ID
                    c.execute(
                        "SELECT Quote, QuoteID, Name, CreatedAt FROM Quotes WHERE QuoteID=? AND DiscordGuildID=?",
                        (name, ctx.message.guild.id))
                    res = c.fetchone()
                    if res is None:
                        # if its a user ID, gets all quotes from the user with that ID
                        if member is not None:
                            c.execute(
                                "SELECT Quote, QuoteID, Name, CreatedAt FROM Quotes WHERE UniqueMemberID=? AND DiscordGuildID=? ORDER BY RANDOM() LIMIT 1",
                                (uniqueID, ctx.message.guild.id))
                        else:
                            c.execute(
                                "SELECT Quote, QuoteID, Name, CreatedAt FROM Quotes WHERE Name LIKE ? AND DiscordGuildID=? ORDER BY RANDOM() LIMIT 1",
                                (name, ctx.message.guild.id))
                        res = c.fetchone()

                    if res is None:
                        # userID has no quote on this server
                        embed = discord.Embed(
                            title="Quotes",
                            description=
                            f"No quote found from user or with ID `{name}`")
                        await ctx.send(embed=embed)
                        raise discord.ext.commands.errors.BadArgument

                    await send_quote(ctx, res[0], res[3], res[2], res[1])
                    return

                else:
                    # if theres something behind the name
                    # this makes the array of parameters into a string
                    quote = " ".join(quote)

                    try:
                        # Checks if the quote is a quote index
                        index = int(quote)
                        # checks if the user even has any quotes
                        if member is not None:
                            c.execute(
                                "SELECT * FROM Quotes WHERE UniqueMemberID=? AND DiscordGuildID=?",
                                (uniqueID, guild_id))
                        else:
                            c.execute(
                                "SELECT * FROM Quotes WHERE Name LIKE ? AND DiscordGuildID=?",
                                (name, guild_id))
                        res = c.fetchall()
                        amt = len(res)
                        if amt == 0:
                            embed = discord.Embed(
                                title="Quotes Error",
                                description=
                                f"There does not exist any quote for the user \"{name}\"",
                                color=0xFF0000)
                            await ctx.send(embed=embed)
                            raise discord.ext.commands.errors.BadArgument

                        # checks if the index exists
                        if member is not None:
                            c.execute(
                                "SELECT Quote, Name, CreatedAt, QuoteID FROM Quotes WHERE UniqueMemberID=? AND DiscordGuildID=? ORDER BY QuoteID LIMIT 1 OFFSET ?",
                                (uniqueID, guild_id, index))
                        else:
                            c.execute(
                                "SELECT Quote, Name, CreatedAt, QuoteID FROM Quotes WHERE Name LIKE ? AND DiscordGuildID=? ORDER BY QuoteID LIMIT 1 OFFSET ?",
                                (name, guild_id, index))
                        res = c.fetchone()
                        if res is None:
                            embed = discord.Embed(
                                title="Quotes Error",
                                description=
                                f"There does not exist a quote with that index for the user \"{name}\". "
                                f"Keep index between `0` and `{amt}`",
                                color=0xFF0000)
                            await ctx.send(embed=embed)
                            raise discord.ext.commands.errors.BadArgument
                        await send_quote(ctx, res[0], res[2], res[1], res[3])

                    except ValueError:
                        # Is the quote a command or a new quote to add
                        if quote.lower().split(" ")[0] == "all":
                            # show all quotes from name
                            quote_list = ""

                            # executes query to get all quotes
                            if member is not None:
                                c.execute(
                                    "SELECT Quote, Name, CreatedAt, QuoteID FROM Quotes WHERE UniqueMemberID=? AND DiscordGuildID=? ORDER BY QuoteID",
                                    (uniqueID, guild_id))
                            else:
                                c.execute(
                                    "SELECT Quote, Name, CreatedAt, QuoteID FROM Quotes WHERE Name LIKE ? AND DiscordGuildID=? ORDER BY QuoteID",
                                    (name, guild_id))
                            res = c.fetchall()

                            # If there are no quotes for the given person;
                            if len(res) == 0:
                                embed = discord.Embed(
                                    title="Quotes Error",
                                    description=
                                    f"{name} doesn't have any quotes yet.",
                                    color=0xFF0000)
                                await ctx.send(embed=embed)
                                raise discord.ext.commands.errors.BadArgument

                            i = 0
                            for row in res:
                                quote_to_add = row[0].replace("*", "").replace(
                                    "_", "").replace("~", "").replace(
                                        "\\", "").replace("`", "")
                                if len(quote_to_add) > 150:
                                    quote_to_add = quote_to_add[:150] + "**[...]**"
                                quote_list += f"\n**#{i}:** {quote_to_add} `[ID: {row[3]}]`"
                                i += 1

                            # better splitting method
                            remaining_quotes = quote_list
                            embeds_to_send = []
                            message_count = 1
                            page_count = 1

                            quoted_name = name
                            if member is not None:
                                quoted_name = member.name
                            while len(remaining_quotes) > 0:
                                # split quotes into multiple chunks of max 6000 chars
                                if len(remaining_quotes) >= 5900:
                                    rind = remaining_quotes.rindex(
                                        "\n", 0, 5900)
                                else:
                                    rind = len(remaining_quotes)
                                single_msg = remaining_quotes[0:rind]
                                remaining_quotes = remaining_quotes[rind:]
                                embed = discord.Embed(
                                    title=f"All quotes from {quoted_name}",
                                    description=f"`Message {message_count}`",
                                    color=0x404648)
                                message_count += 1
                                embeds_to_send.append(embed)
                                while len(single_msg) > 0:
                                    # split quotes into multiple fields of max 1000 chars
                                    if len(single_msg) >= 1000:
                                        rind2 = single_msg.rindex(
                                            "\n", 0, 1000)
                                        if rind2 == 0:
                                            # one quote is more than 1000 chars
                                            rind2 = single_msg.rindex(
                                                " ", 0, 1000)
                                    else:
                                        rind2 = len(single_msg)
                                    embed.add_field(name=f"Page {page_count}",
                                                    value=single_msg[0:rind2])
                                    single_msg = single_msg[rind2:]
                                    page_count += 1

                            for e in embeds_to_send:
                                # sends all embeds messages
                                await ctx.send(embed=e)

                        elif quote.lower().split(
                                " ")[0] == "del":  # Command to delete quotes
                            if not await self.bot.is_owner(ctx.author):
                                raise discord.ext.commands.errors.NotOwner
                            try:
                                quote_id = int(quote.lower().split(" ")[1])
                                try:
                                    c.execute(
                                        "DELETE FROM Quotes WHERE QuoteID=?",
                                        (quote_id, ))
                                    conn.commit()

                                    await ctx.send(
                                        f"Deleted quote with quote ID {quote_id}."
                                    )
                                except IndexError:
                                    await ctx.send("No name with that index.")
                            except (IndexError, ValueError):
                                await ctx.send("You forgot to add an index.")
                        else:  # If the quote is a new quote to add
                            if len(quote
                                   ) > 500 and not await self.bot.is_owner(
                                       ctx.author):
                                embed = discord.Embed(
                                    title="Quote Error",
                                    description=
                                    "This quote exceeds the max_length length of 500 chars. Ping Mark if you want the quote added.",
                                    color=0xFF0000)
                                await ctx.send(embed=embed)
                                raise discord.ext.commands.errors.NotOwner

                            if not isascii(
                                    quote) and not await self.bot.is_owner(
                                        ctx.author):
                                embed = discord.Embed(
                                    title="Quote Error",
                                    description=
                                    "This quote contains too many non-ascii characters. Ping Mark if you want the quote added.",
                                    color=0xFF0000)
                                await ctx.send(embed=embed)
                                raise discord.ext.commands.errors.BadArgument

                            # corrects some values
                            if uniqueID == -1:
                                uniqueID = None
                                quoted_name = name
                            else:
                                quoted_name = member.name
                            addedByUniqueID = handySQL.get_uniqueMemberID(
                                conn, ctx.message.author.id, guild_id)

                            sql = """   INSERT INTO Quotes(Quote, Name, UniqueMemberID, AddedByUniqueMemberID, DiscordGuildID)
                                        VALUES (?,?,?,?,?)"""
                            c.execute(sql, (quote, quoted_name, uniqueID,
                                            addedByUniqueID, guild_id))
                            conn.commit()

                            embed = discord.Embed(
                                title="Added Quote",
                                description=f"Added quote for {name}",
                                color=0x00FF00)
                            await ctx.send(embed=embed)
        else:
            # If $quote is written on its own, send a random quote from any user
            c.execute(
                "SELECT Quote, QuoteID, Name, CreatedAt FROM Quotes WHERE DiscordGuildID=? ORDER BY RANDOM() LIMIT 1",
                (ctx.message.guild.id, ))
            res = c.fetchone()
            if res is None:
                embed = discord.Embed(
                    title="Quote Error",
                    description="There are no quotes on this server yet.",
                    color=0xFF0000)
                await ctx.send(embed=embed)
                raise discord.ext.commands.errors.BadArgument
            await send_quote(ctx, res[0], res[3], res[2], res[1])
예제 #8
0
    async def rep(self, message):
        """
        Used to add positive reputation to a user
        :param message: The message content including the +rep
        :return: None
        """
        if message.author.id in self.ignored_users:
            await message.channel.send(
                f"{message.author.mention} this discord account is blocked from using +rep."
            )

        args = message.content.split(" ")
        try:
            if len(args) == 1:  # If there's only the command:
                await self.send_reputations(message, message.author)

            elif len(args) == 2:  # If there's only the command a mention
                u_id = args[1].replace("<@", "").replace(">",
                                                         "").replace("!", "")
                member = message.guild.get_member(int(u_id))
                await self.send_reputations(message, member)

            else:  # If the message is long enough, add it as a reputation
                # check if it is a mention
                u_id = args[1].replace("<@", "").replace(">",
                                                         "").replace("!", "")
                member = message.guild.get_member(int(u_id))

                if member.id == message.author.id:
                    raise ValueError

                # checks if the message chars are valid
                if not await valid_chars_checker(message.content):
                    raise ValueError

                # Add reputation to user
                time_valid = await self.add_rep(message, member,
                                                message.author)

                # Send return message
                if time_valid:
                    display_name = member.display_name.replace(
                        "*", "").replace("_", "").replace("~", "").replace(
                            "\\", "").replace("`",
                                              "").replace("||",
                                                          "").replace("@", "")
                    embed = discord.Embed(
                        title="Added +rep",
                        description=f"Added +rep to {display_name}",
                        color=discord.Color.green())
                    if len(args) > 2:
                        embed.add_field(name="Comment:",
                                        value=f"```{' '.join(args[2:])}```")
                    embed.set_author(name=str(message.author))
                    await message.channel.send(embed=embed)
                    await message.delete()

                else:
                    conn = self.get_connection()
                    guild_id = get_valid_guild_id(message)
                    uniqueID = handySQL.get_uniqueMemberID(
                        conn, message.author.id, guild_id)
                    last_sent_time = get_most_recent_time(conn, uniqueID)
                    if last_sent_time is not None:
                        seconds = datetime.datetime.strptime(
                            last_sent_time, '%Y-%m-%d %H:%M:%S.%f').timestamp(
                            ) + self.time_to_wait
                        next_time = datetime.datetime.fromtimestamp(
                            seconds).strftime("%A at %H:%M")
                        embed = discord.Embed(
                            title="Error",
                            description=
                            f"You've repped too recently. You can rep again on {next_time}.",
                            color=discord.Color.red())
                        await message.channel.send(embed=embed,
                                                   delete_after=10)
                    else:
                        embed = discord.Embed(
                            title="Error",
                            description=
                            "Had problems parsing something. Tbh this error shouldn't show up...",
                            color=discord.Color.red())
                        await message.channel.send(embed=embed,
                                                   delete_after=10)

        except ValueError:
            embed = discord.Embed(
                title="Error",
                description=
                "Only mention one user, don't mention yourself, only use printable ascii characters, and keep it under 40 characters.",
                color=discord.Color.red())
            embed.add_field(
                name="Example",
                value="+rep <@755781649643470868> helped with Eprog")
            await message.channel.send(embed=embed, delete_after=10)