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")
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
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
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
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
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
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])
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)