From 673a518d315fab07c26536cb0597b9dbeebb7328 Mon Sep 17 00:00:00 2001 From: sgoudham Date: Sun, 16 Aug 2020 04:17:38 +0100 Subject: [PATCH] Removed 99% of code from main.py and put it into __init__.py --- main.py | 635 +------------------------------------------------------- 1 file changed, 4 insertions(+), 631 deletions(-) diff --git a/main.py b/main.py index 979f021d..e1560fb0 100644 --- a/main.py +++ b/main.py @@ -11,646 +11,19 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. + # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import datetime -import string - -import aiohttp -import aiomysql import discord -from decouple import config -from discord import Embed, Forbidden -from discord.ext import commands, tasks -from discord.ext.commands import when_mentioned_or, is_owner - -import settings -from settings import blank_space, enso_embedmod_colours, enso_guild_ID, enso_newpeople_ID, get_prefix_for_guild, \ - cache, del_cache, get_roles_persist - -# Global counter for statuses -counter = 0 - -# Get DB information from .env -password = config('DB_PASS') -host = config('DB_HOST') -user = config('DB_USER') -port = config('DB_PORT') -db = config('DB_NAME') -disc_bots_gg_auth = config('DISCORD_BOTS_BOTS_AUTH') - -# Getting the Bot token from Environment Variables -API_TOKEN = config('DISCORD_TOKEN') - - -async def get_prefix(bot, message): - """Allow the commands to be used with mentioning the bot""" - if message.guild is None: - return "~" - return when_mentioned_or(get_prefix_for_guild(str(message.guild.id)))(bot, message) - - -def get_version(): - """Return the current version of the bot""" - return "v1.7.2" - - -# Bot Initiation -client = commands.Bot( # Create a new bot - command_prefix=get_prefix, # Set the prefix - description='All current available commands within Ensō~Chan', # Set a description for the bot - owner_id=154840866496839680, # Your unique User ID - version=get_version, - case_insensitive=True) # Version number of Ensō~Chan -client.remove_command("help") # Remove default help command - - -# Setting up connection using pool/aiomysql -async def create_connection(): - client.db = await aiomysql.create_pool( - host=host, - port=int(port), - user=user, - password=password, - db=db, - loop=client.loop) - - -async def startup_cache_log(): - """Store the modlogs/prefixes in cache from the database on startup""" - - # Setup pool - pool = client.db - - # Setup up pool connection and cursor - async with pool.acquire() as conn: - async with conn.cursor() as cur: - # Grab the prefix of the server from the database - select_query = """SELECT * FROM guilds""" - - # Execute the query - await cur.execute(select_query) - results = await cur.fetchall() - - # Store the guildID's, modlog channels and prefixes within cache - for row in results: - cache(guildid=row[0], prefix=row[1], channel=row[2], rolespersist=row[3]) - - -# Make sure the connection is setup before the bot is ready -client.loop.run_until_complete(create_connection()) -client.loop.run_until_complete(startup_cache_log()) - -if __name__ == '__main__': - for ext in settings.extensions(): - client.load_extension(ext) - - -async def post_bot_stats(): - """Method To Update Guild Count On discord.bots.gg""" - - async with aiohttp.ClientSession() as session: - await session.post(f"https://discord.bots.gg/api/v1/bots/{client.user.id}/stats", - data={"guildCount": {len(client.guilds)}, - "Content-Type": "application/json"}, - headers={'Authorization': disc_bots_gg_auth}) - await session.close() - - -@tasks.loop(minutes=10, reconnect=True) -async def change_status(): - """Creating Custom Statuses as a Background Task""" - - global counter - # Waiting for the bot to ready - await client.wait_until_ready() - - # Update Guild Count on discord.bots.gg - await post_bot_stats() - - # Define array of statuses - looping_statuses = [ - discord.Activity( - type=discord.ActivityType.watching, - name=f"{len(client.users)} Weebs | {get_version()}"), - discord.Activity( - type=discord.ActivityType.watching, - name=f"Hamothy | Real Life | {get_version()}"), - discord.Activity( - type=discord.ActivityType.watching, - name=f"Hamothy Program | {get_version()}"), - discord.Game(name=f"~help | {get_version()}") - ] - - # Check if the counter is at the end of the array - if counter == (len(looping_statuses) - 1): - # Reset the loop - counter = 0 - else: - # Increase the counter - counter += 1 - - # Display the next status in the loop - await client.change_presence(activity=looping_statuses[counter]) - - -# Start the background task(s) -change_status.start() - - -@client.event -async def on_message(message): - """Make sure bot messages are not tracked""" - - if message.author.bot: - return - - # Processing the message - await client.process_commands(message) - - -@client.event -async def on_ready(): - """Displaying if Bot is Ready""" - print("UvU Senpaiii I'm weady") - - -@client.command(name="ping") -async def _ping(ctx): - """Latency of the Bot (ms)""" - - await ctx.send(f"Pong! `{round(client.latency * 1000)}ms`") - - -@client.command(name="leave", hidden=True) -@is_owner() -async def leave(ctx): - """Leaves the guild""" - - await ctx.send("**Leaving the guild... Bye Bye uvu**") - await ctx.guild.leave() - - -@client.command(name="restart", hidden=True) -@is_owner() -async def restart(ctx): - """Restart the Bot""" - - embed = Embed( - description="**Success Senpai! My Reboot Had No Problems** ", - colour=enso_embedmod_colours) - await ctx.send(embed=embed) - - try: - client.db.terminate() - await client.db.wait_closed() - await client.logout() - except Exception as e: - print(e) - - -@client.command(name="reloadusers", hidden=True) -@is_owner() -async def reload_db(ctx): - """Reloads the database by inserting/updating all the records""" - - # Setup pool - pool = client.db - - # Setup up pool connection and cursor - async with pool.acquire() as conn: - async with conn.cursor() as cur: - # Define the insert statement that will insert the user's information - insert = """INSERT INTO members (guildID, discordID) VALUES """ + ", ".join( - map(lambda m: f"({ctx.guild.id}, {m.id})", - ctx.guild.members)) + """ ON DUPLICATE KEY UPDATE guildID = VALUES(guildID), discordID = VALUES(discordID)""" - - # Execute the insert statement - await cur.execute(insert) - await conn.commit() - print(cur.rowcount, f"Record(s) inserted successfully into Members from {ctx.guild.name}") - - # Sending confirmation message - await ctx.send(f"Database Reloaded Successfully for **{ctx.guild.name}**") - - -@client.event -async def on_guild_join(guild): - """ - Store users in a database - Store prefix/modlogs in the cache - """ - - # Store guildID, modlogs channel and prefix to cache - cache(str(guild.id), channel=None, prefix="~", rolespersist=0) - - # Setup pool - pool = client.db - - # Grabbing the values to be inserted - records = ", ".join(map(lambda m: f"({guild.id}, {m.id})", guild.members)) - - # Setup up pool connection and cursor - async with pool.acquire() as conn: - async with conn.cursor() as cur: - # Define the insert statement for inserting the guild into the guilds table - insert_query = """INSERT INTO guilds (guildID) VALUES (%s) ON DUPLICATE KEY UPDATE guildID = VALUES(guildID)""" - val = guild.id, - - # Execute the query - await cur.execute(insert_query, val) - await conn.commit() - print(cur.rowcount, f"Record(s) inserted successfully into Guilds from {guild.name}") - - async with conn.cursor() as cur: - # Define the insert statement that will insert the user's information - insert = """INSERT INTO members (guildID, discordID) VALUES {} - ON DUPLICATE KEY UPDATE guildID = VALUES(guildID), discordID = VALUES(discordID)""".format(records) - - # Execute the query - await cur.execute(insert) - await conn.commit() - print(cur.rowcount, f"Record(s) inserted successfully into Members from {guild.name}") - - -@client.event -async def on_guild_remove(guild): - """ - Remove users in the database for the guild - Remove the modlogs/guild from the cache - """ - # Delete the key - value pairs for the guild - del_cache(str(guild.id)) - - # Setup pool - pool = client.db - - # Setup pool connection and cursor - async with pool.acquire() as conn: - async with conn.cursor() as cur: - # Delete the guild and prefix information as the bot leaves the server - delete_query = """DELETE FROM guilds WHERE guildID = %s""" - val = guild.id, - - # Execute the query - await cur.execute(delete_query, val) - await conn.commit() - print(cur.rowcount, f"Record deleted successfully from Guild {guild.name}") - - async with conn.cursor() as cur: - # Delete the record of the member as the bot leaves the server - delete_query = """DELETE FROM members WHERE guildID = %s""" - vals = guild.id, - - # Execute the query - await cur.execute(delete_query, vals) - await conn.commit() - print(cur.rowcount, f"Record(s) deleted successfully from Members from {guild.name}") - - -@client.event -async def on_member_join(member): - """ - Bot event to insert new members into the database - In the Enso guild, it will send an introduction embed - """ - - # Get the guild - guild = member.guild - - # Setup pool - pool = client.db - - role_persist = get_roles_persist(str(guild.id)) - # Setup pool connection and cursor - async with pool.acquire() as conn: - async with conn.cursor() as cur: - # Define the insert statement that will insert the user's information - insert_query = """INSERT INTO members (guildID, discordID) VALUES (%s, %s) - ON DUPLICATE KEY UPDATE guildID = VALUES(guildID), discordID = VALUES(discordID)""" - vals = member.guild.id, member.id, - - # Execute the SQL Query - await cur.execute(insert_query, vals) - await conn.commit() - print(cur.rowcount, f"{member} Joined {member.guild.name}, Record Inserted Into Members") - - async with conn.cursor() as cur: - # Get the roles of the user from the database - select_query = """SELECT * FROM members WHERE guildID = (%s) AND discordID = (%s)""" - vals = member.guild.id, member.id, - - # Execute the SQL Query - await cur.execute(select_query, vals) - result = await cur.fetchone() - role_ids = result[5] - - if role_persist == 1: - # Get Enso Chan - bot = guild.get_member(client.user.id) - - # Check permissions of Enso - if bot.guild_permissions.manage_roles and role_ids is not None: - # Get all the roles of the user before they were muted from the database - roles = [member.guild.get_role(int(id_)) for id_ in role_ids.split(", ") if len(id_)] - - # Give the member their roles back - await member.edit(roles=roles) - print(f"{member} Had Their Roles Given Back In {member.guild.name}") - - else: - print(f"Insufficient Permissions to Add Roles to {member} in {member.guild.name}") - - # Reset the roles entry for the database - update_query = """UPDATE members SET roles = NULL WHERE guildID = (%s) AND discordID = (%s)""" - update_vals = member.guild.id, member.id, - - # Execute the query - await cur.execute(update_query, update_vals) - await conn.commit() - print(cur.rowcount, f"Roles Cleared For {member} in {member.guild.name}") - - # Make sure the guild is Enso - if guild.id == enso_guild_ID: - # Set the channel id to "newpeople" - new_people = guild.get_channel(enso_newpeople_ID) - - # Set the enso server icon and the welcoming gif - server_icon = guild.icon_url - welcome_gif = "https://cdn.discordapp.com/attachments/669808733337157662/730186321913446521/NewPeople.gif" - - # Set up embed for the #newpeople channel - embed = Embed(title="\n**Welcome To Ensō!**", - colour=enso_embedmod_colours, - timestamp=datetime.datetime.utcnow()) - - embed.set_thumbnail(url=server_icon) - embed.set_image(url=welcome_gif) - embed.add_field( - name=blank_space, - value=f"Hello {member.mention}! We hope you enjoy your stay in this server! ", - inline=False) - embed.add_field( - name=blank_space, - value=f"Be sure to check out our <#669815048658747392> channel to read the rules and <#683490529862090814> channel to get caught up with any changes! ", - inline=False) - embed.add_field( - name=blank_space, - value=f"Last but not least, feel free to go into <#669775971297132556> to introduce yourself!", - inline=False) - - # Send embed to #newpeople - await new_people.send(embed=embed) - - -@client.event -async def on_member_remove(member): - """Storing User Roles within Database When User Leaves Guild""" - role_ids = ", ".join([str(r.id) for r in member.roles if not r.managed]) - - # Setup pool - pool = client.db - - # Setup pool connection and cursor - async with pool.acquire() as conn: - async with conn.cursor() as cur: - # Define the insert statement that will insert the user's information - update_query = """UPDATE members SET roles = (%s) WHERE guildID = (%s) AND discordID = (%s)""" - vals = role_ids, member.guild.id, member.id, - - # Execute the SQL Query - await cur.execute(update_query, vals) - await conn.commit() - print(cur.rowcount, f"{member} Left {member.guild.name}, Roles stored into Members") - - -@client.event -async def on_command_error(ctx, args2): - """Event to detect and handle errors""" - - # Get permissions for the bot within - perms = ctx.guild.me.permissions_in(ctx.message.channel) - - # if the user did not specify an user - if isinstance(args2, commands.MissingRequiredArgument): - await on_command_missing_argument(ctx, perms) - # if the user has spammed a command and invoked a cooldown - elif isinstance(args2, commands.CommandOnCooldown): - await on_command_cooldown(ctx, perms, args2) - # if the user tries to access a command that isn't available - elif isinstance(args2, commands.CommandNotFound): - await on_command_not_found(ctx, perms) - # if the user provides an argument that isn't recognised - elif isinstance(args2, commands.BadArgument): - await on_command_bad_argument(ctx, perms) - # if the user does not the correct permissions to call a command - elif isinstance(args2, commands.MissingPermissions): - await on_command_permission(ctx, perms, args2) - # if the bot is missing permissions needed - elif isinstance(args2, commands.BotMissingPermissions): - await on_bot_forbidden(ctx, perms, args2) - # if the bot is forbidden from performing the command - elif isinstance(args2, Forbidden): - await on_command_forbidden(ctx, perms) - # if the user tries to invoke a command that is only for the owner - elif isinstance(args2, commands.NotOwner): - await on_not_owner(ctx, perms) - - -async def send_error(ctx, perms, embed): - """ - Sending error message to the user - Only send error message if the channel permissions allow it - """ - - if perms.send_messages and perms.embed_links: - await ctx.send(embed=embed) - else: - print("Error: Error Handling Message Could Not Be Sent") - - -async def on_bot_forbidden(ctx, perms, args2): - """Handles Missing Bot Permissions Errors""" - - # Convert list into string of the missing permissions - missing_perms = string.capwords(", ".join(args2.missing_perms).replace("_", " ")) - - embed = Embed(description=f"❌ I Need **{missing_perms}** Permission(s) to Execute This Command! ❌", - colour=enso_embedmod_colours) - - await send_error(ctx, perms, embed) - - -async def on_command_forbidden(ctx, perms): - """Handles Forbidden Error""" - - embed = Embed(description="**❌ I Don't Have Permissions To Execute This Command ❌**", - colour=enso_embedmod_colours) - - await send_error(ctx, perms, embed) - - -async def on_command_bad_argument(ctx, perms): - """Handles Bad Argument Errors (Argument can't be read properly)""" - - embed = Embed(description="**❌ Uh oh! Couldn't find anyone to mention! Try again! ❌**", - colour=enso_embedmod_colours) - - await send_error(ctx, perms, embed) - - -async def on_command_not_found(ctx, perms): - """Handles the command not found error""" - - embed = Embed(description=f"Command Not Found! ❌ Please use **{ctx.prefix}help** to see all commands", - colour=enso_embedmod_colours) - - await send_error(ctx, perms, embed) - - -async def on_command_cooldown(ctx, perms, error): - """Handles Cooldown Errors""" - - embed = Embed(description=f"That command is on cooldown. Try again in **{error.retry_after:,.2f}** seconds", - colour=enso_embedmod_colours) - - await send_error(ctx, perms, embed) - - -async def on_command_permission(ctx, perms, args2): - """Handles User Missing Permissions Errors""" - - # Convert list into string of the missing permissions - missing_perms = string.capwords(", ".join(args2.missing_perms).replace("_", " ")) - - embed = Embed(description=f"❌ Uh oh! You Need **{missing_perms}** Permission(s) To Execute This Command! ❌", - colour=enso_embedmod_colours) - - await send_error(ctx, perms, embed) - - -async def on_command_missing_argument(ctx, perms): - """Handles the missing argument error""" - - embed = Embed(description="Required Argument(s) Missing!" - f"\nUse **{ctx.prefix}help** to find how to use **{ctx.command}**", - colour=enso_embedmod_colours) - - await send_error(ctx, perms, embed) - - -async def on_not_owner(ctx, perms): - """Handles the error when the user is not the owner and tries to invoke owner only command""" - - embed = Embed(description="**❌ Owner Only Command ❌**", - colour=enso_embedmod_colours) - - await send_error(ctx, perms, embed) +from bot import Bot, API_TOKEN +# Initiating Bot Instance +client = Bot() # Run the bot, allowing it to come online try: client.run(API_TOKEN) except discord.errors.LoginFailure as e: print("Login unsuccessful.") - -""" - # Don't count messages that are taken in the dms - if not isinstance(message.channel, DMChannel): - # Using connection to the database - with connection() as conn: - - # Make sure that mariaDB errors are handled properly - try: - msg_name = message.author.name - msg_discrim = message.author.discriminator - time = message.created_at - - # Get: - guild_id = message.guild.id # Guild of the message - msg_time = time.strftime('%Y-%m-%d %H:%M:%S') # Time of the Message - msg_author = f"{msg_name}#{msg_discrim}" # DiscordID - msg_content = message.content # Content of the message - - # Store the variables - val = guild_id, msg_time, msg_author, msg_content, - - # If an attachment (link) has been sent - if message.attachments: - - # Loop through all attachments - for attachment in message.attachments: - # Get the message content and the link that was used - attach = "".join(f"Message: {message.content} Link: {attachment.url}") - - # Define the new variables to send - val = guild_id, msg_time, msg_author, attach, - - # Define the Insert Into Statement inserting into the database - insert_query = """"""INSERT INTO messages (guildID, messageTime, discordID, messageContent) VALUES (?, ?, ?, ?)"""""" - cursor = conn.cursor() - - # Execute the SQL Query - cursor.execute(insert_query, val) - conn.commit() - print(cursor.rowcount, "Record inserted successfully into Logs") - - except mariadb.Error as ex: - print("Parameterized Query Failed: {}"(ex)) - - - - # Using database connection - with connection() as conn: - # Grab the guild and prefix information of the guild that the message was sent in - select_query = """"""SELECT * FROM guilds WHERE guildID = (?)"""""" - select_val = ctx.guild.id, - - # Using connection cursor - with closing(conn.cursor()) as cursor: - - # Execute the query - cursor.execute(select_query, select_val) - result = cursor.fetchone() - - # Grab the guild prefix - curr_prefix = result[1] - - # If no argument has been given, display the current prefix - if not new: - await ctx.send(f"**The current guild prefix is `{curr_prefix}`**") - - # Update the prefix for the guild - else: - -colour_change.start() -@client.command() -@guild_only() -@cooldown(1, 300, BucketType.guild) -async def someone(ctx): - """"""Tags Someone Randomly in the Server"""""" - - await ctx.send(random.choice(tuple(member.mention for member in ctx.guild.members if not member.bot))) - - - if message.guild.id != enso_guild_ID: - return - else: - nicknames = ["Ensō's Face", - "Ensō's Leg", - "Ensō's Thighs", - "Ensō's Hands", - "Ensō's Feet", - "Ensō's Hair", - "Ensō's Backbone", - "Ensō's Knees", - "Ensō's Fingers", - "Ensō's Stomach", - "Ensō's Heart", - "Ensō's Nose", - ] - await message.author.edit(nick=random.choice(nicknames)) - -"""