From 41f3e7c5cb9953db0c9b6fa73f685786c097e881 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Thu, 1 Apr 2021 23:37:14 +0300 Subject: [PATCH 01/20] Removed emojis that didn't work --- modules/emoji_list.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/modules/emoji_list.py b/modules/emoji_list.py index 3ff2693..b0a8b41 100644 --- a/modules/emoji_list.py +++ b/modules/emoji_list.py @@ -14,7 +14,6 @@ '\N{bell}', '\N{bikini}', '\N{blue heart}', -'\N{blueberries}', '\N{bookmark}', '\N{books}', '\N{bowling}', @@ -32,7 +31,6 @@ '\N{clipboard}', '\N{cloud}', '\N{coconut}', -'\N{coin}', '\N{comet}', '\N{compass}', '\N{cow}', @@ -66,13 +64,11 @@ '\N{green heart}', '\N{guitar}', '\N{honey pot}', -'\N{hook}', '\N{horse}', '\N{hospital}', '\N{ice cream}', '\N{key}', '\N{keyboard}', -'\N{knot}', '\N{label}', '\N{leg}', '\N{lemon}', @@ -84,7 +80,6 @@ '\N{magnet}', '\N{maple leaf}', '\N{merperson}', -'\N{mirror}', '\N{monkey}', '\N{mouse}', '\N{mushroom}', @@ -100,9 +95,7 @@ '\N{pie}', '\N{pig}', '\N{pill}', -'\N{pinched fingers}', '\N{pineapple}', -'\N{placard}', '\N{police car}', '\N{poodle}', '\N{popcorn}', @@ -120,7 +113,6 @@ '\N{revolving hearts}', '\N{ribbon}', '\N{ring}', -'\N{rock}', '\N{satellite}', '\N{scarf}', '\N{seat}', @@ -160,7 +152,6 @@ '\N{wedding}', '\N{whale}', '\N{white heart}', -'\N{wood}', '\N{wrench}', '\N{yellow heart}', '\N{zombie}', From 8676fc773cebee941adeff6f965a2520429b3bfa Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Fri, 2 Apr 2021 02:28:13 +0300 Subject: [PATCH 02/20] Add setroles option to polls --- modules/poll.py | 85 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/modules/poll.py b/modules/poll.py index d3a337f..5499ac4 100644 --- a/modules/poll.py +++ b/modules/poll.py @@ -1,6 +1,7 @@ import discord import logging import sqlite3 +import re from discord import embeds from discord import channel @@ -12,12 +13,27 @@ async def Poll(message): content = message.content.split(" ")[2] + try: + arg = message.content.split(" ")[3] + except IndexError: + arg = "" + if content == "help": await sendHelp(message) - elif content == "new": + elif content == "new" and arg != "-r": await startBasicPoll(message) elif content == "end": await endBasicPoll(message) + elif content == "new" and arg == "-r": + await startRolePoll(message) + elif content == "setrole": + if message.author.guild_permissions.administrator: + await recordRoles(message) + else: + emb = discord.Embed() + emb.description = "You do not have the permissions to use this." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) else: await sendHelp(message) #elif content == "edit": #TODO add an edit command? @@ -203,4 +219,69 @@ async def endBasicPoll(message): logging.info(f"Poll by {message.author.name} succesfully ended in {message.channel.name}") await message.delete() conn.close() - \ No newline at end of file + +# ######################################################################################################## # + +async def recordRoles(message): + # Command format + # !c poll setroles [role]:[voteamount],[role]:[voteamount] : ... + prefix = _POLL_PREFIX + "setroles " + emb = discord.Embed() + args = message.content[len(prefix):].split(",") + + if args == 0: + emb.description = "You did not give any arguments. Use '!c poll help' for the correct syntax." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + return + + db_file = CURR_DIR + "\\databases.db" + conn = sqlite3.connect(db_file) + c = conn.cursor() + reg = re.compile(r"^.*<@!(\d+)>") + results = {} + + for arg in args: + try: + role = arg.split(":")[0].strip() + amount = int(arg.split(":")[1]) + except ValueError: + emb.description = "Invalid arguments, role must be an ID or a mention and amount must be an integer. \nAlso make sure you have commas and colons in the right place." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + conn.close() + return + + # parse mention + match = reg.match(role) + if match: + role_id = match.group(1) + else: + emb.description = "Invalid arguments, role must be an ID or a mention and amount must be an integer. \nAlso make sure you have commas and colons in the right place." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + conn.close() + return + c.execute("INSERT INTO RolesMaxVotes VALUES (?,?,?)", (role_id, message.guild.id, amount)) + results[role_id] = amount + txt = "Following roles & vote amounts were set:\n" + roles = await message.guild.fetch_roles() + for role in roles: + if role.id in results: + txt += f"{role.name} : {results[role.id]}" + + emb.description = txt + emb.colour = get_hex_colour() + await message.channel.send(embed=emb) + conn.commit() + conn.close() + + +async def startRolePoll(message): + pass + +async def rolePollEndHelper(): + pass + +async def endRolePoll(message): + pass \ No newline at end of file From 3e47b07f291bd6e5e74a53ceb55bc260921c3284 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Tue, 6 Apr 2021 01:13:53 +0300 Subject: [PATCH 03/20] Start new RolePolls, add vote help - Update poll help, now goes to DMs and is split to two messages. - Add admin permission check to starting RolePolls - Fix typos - Add duplicate role error handling to database query - Add new RolePoll command --- modules/poll.py | 183 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 162 insertions(+), 21 deletions(-) diff --git a/modules/poll.py b/modules/poll.py index 5499ac4..2bffec8 100644 --- a/modules/poll.py +++ b/modules/poll.py @@ -3,9 +3,6 @@ import sqlite3 import re -from discord import embeds -from discord import channel -from discord import emoji from modules.common import get_hex_colour, selectReactionEmoji, CURR_DIR from modules.emoji_list import _EMOJIS @@ -25,7 +22,13 @@ async def Poll(message): elif content == "end": await endBasicPoll(message) elif content == "new" and arg == "-r": - await startRolePoll(message) + if message.author.guild_permissions.administrator: + await startRolePoll(message) + else: + emb = discord.Embed() + emb.description = "You do not have the permissions to use this." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) elif content == "setrole": if message.author.guild_permissions.administrator: await recordRoles(message) @@ -42,7 +45,7 @@ async def sendHelp(message): emb = discord.Embed() emb.title = "How to use polls" emb.color = get_hex_colour() - emb.description = "Command usage: ```!c poll [new|end|help]```\n\ + txt1 = "Command usage: ```!c poll [new|end|help]```\n\ **Adding a new basic poll:**\n\ ```!c poll new [title]; [option1]; [option2]; ... [option20]```\n\ The command will select random emotes for reactions. You can leave the title empty, but in that case remember to put a ';' before the first option.\n\ @@ -50,9 +53,37 @@ async def sendHelp(message): \n\ **Ending a poll:**\n\ ```!c poll end [Poll ID]```\n\ - _NOTE!_ If you have multiple polls running, you can end them all by leaving out the ID.\n\ - The command will only end polls that have been iniated by you." - await message.channel.send(embed=emb) + _NOTE!_ If you have multiple polls running (basic or advanced), you can end them all by leaving out the ID.\n\ + The command will only end polls that have been iniated by you.\n" + txt2 = "_**Advanced polls**_\n\ + Please note that advanced polls require administrator permissions to use.\ + With advanced polls you can set different maximum vote amounts for different roles. Voting will be done via a command as opposed to reactions in the basic polls. You can end advanced polls the same command as basic polls.\n\ + To add roles into the bot's database, use \n```!c poll setroles [role]:[voteamount],[role]:[voteamount], ...```\n\ + You can add as many roles as you need. Input the role as a mention (@role) or a role ID (you can get a role ID by enabling Discord's Developer mode. Then go to 'Server Settings' -> 'Roles' and copy the ID by right clicking on the role and selecting 'Copy ID'. To enable Developer mode, see https://support.discord.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID-).\ + 'voteamount' should be an integer.\n\ + \n\ + **Adding a new advanced poll:**\ + ```!c poll new -r [title]; [option1]; [option2]; ... [option20]```\n\ + Please note that the poll has a character limit of about ~1800 to ~1950 characters depending on how many options you have. Title is not counted into this amount.\n\ + \n**For voting help, type:**\n\ + ```!c vote help```\n\ + \n\ + **Editing or deleting roles from the database:**\n\ + If you want to change how many votes a role has use:\n\ + ```!c poll editrole [role]:[voteamount],[role]:[voteamount], ...```\n\ + Note, that if you change anything in the role you do not need to add or edit the role in the bot's database unless you delete and create a new role in the server settings.\ + If you wish to delete a role, use\n\ + ```!c poll delrole [role], [role], ...```\n\ + Note that you can delete all roles with the keyword 'all', as in\n\ + ```!c poll delrole all```" + dm_channel = message.author.dm_channel + if dm_channel == None: + dm_channel = await message.author.create_dm() + + emb.description = txt1 + await dm_channel.send(embed=emb) + emb.description = txt2 + await dm_channel.send(embed=emb) async def startBasicPoll(message): # Command structure: @@ -171,7 +202,9 @@ async def pollEndHelper(poll, message): async def endBasicPoll(message): # Command structure: - # !c vote end [poll_ID] + # !c poll end [poll_ID] + + #TODO Consolidate RolePoll and BasicPoll ending under this function db_file = CURR_DIR + "\\databases.db" conn = sqlite3.connect(db_file) @@ -199,7 +232,7 @@ async def endBasicPoll(message): try: arg = int(message.content.split(" ")[3]) except Exception: - logging.exception("Something wnet wrong when trying to convert poll ID to int") + logging.exception("Something went wrong when trying to convert poll ID to int") txt = "\N{no entry} Invalid poll ID!" await message.channel.send(txt) conn.close() @@ -225,7 +258,7 @@ async def endBasicPoll(message): async def recordRoles(message): # Command format # !c poll setroles [role]:[voteamount],[role]:[voteamount] : ... - prefix = _POLL_PREFIX + "setroles " + prefix = _POLL_PREFIX + "setrole " emb = discord.Embed() args = message.content[len(prefix):].split(",") @@ -238,7 +271,7 @@ async def recordRoles(message): db_file = CURR_DIR + "\\databases.db" conn = sqlite3.connect(db_file) c = conn.cursor() - reg = re.compile(r"^.*<@!(\d+)>") + reg = re.compile(r"^.*<@&(\d+)>") results = {} for arg in args: @@ -255,20 +288,33 @@ async def recordRoles(message): # parse mention match = reg.match(role) if match: - role_id = match.group(1) + role_id = match.group(1).strip() else: - emb.description = "Invalid arguments, role must be an ID or a mention and amount must be an integer. \nAlso make sure you have commas and colons in the right place." + role_id = role.strip() + try: + role_int = int(role_id) + except ValueError: + emb.description = "Invalid arguments, role must be an ID integer or a mention and amount must be an integer. \nAlso make sure you have commas and colons in the right place." emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) conn.close() return - c.execute("INSERT INTO RolesMaxVotes VALUES (?,?,?)", (role_id, message.guild.id, amount)) - results[role_id] = amount - txt = "Following roles & vote amounts were set:\n" + + try: + c.execute("INSERT INTO RolesMaxVotes VALUES (?,?,?)", (role_int, message.guild.id, amount)) + except sqlite3.IntegrityError: + emb.description = "One or more roles are already in the database. To edit roles use '!c poll editrole'." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + return + results[role_int] = amount + txt = "**Following roles & vote amounts were set:**\n" roles = await message.guild.fetch_roles() + for role in roles: if role.id in results: - txt += f"{role.name} : {results[role.id]}" + # TODO Add SyntaxError check for illegal Unicode emojis + txt += f"'{role.name}' : {results[role.id]}" emb.description = txt emb.colour = get_hex_colour() @@ -278,10 +324,105 @@ async def recordRoles(message): async def startRolePoll(message): - pass + # Command structure: + # !c poll new -r [title]; [option1]; [option2]; ... ; [option20] + + db_file = CURR_DIR + "\\databases.db" + conn = sqlite3.connect(db_file) + c = conn.cursor() + g_id = message.guild.id + print(type(g_id)) + c.execute(f"SELECT * FROM RolesMaxVotes WHERE Guild_ID={g_id}") + roles = c.fetchall() + + emb = discord.Embed() + if len(roles) < 1: + emb.description = "You have not set the maximum vote amounts for roles. See '!c poll help' for more." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + return + + prefix = _POLL_PREFIX + "new -r " + + args = message.content[len(prefix):].split(";") + title = args[0] + titleStatus = 0 + del args[0] + if title.strip() == "": + title = f"A poll by {message.author.name}" + titleStatus = 1 + + if len(args) <= 1 or message.content.find(";") == -1: + #help command + emb.description = "You gave less than 2 options or you are missing separators. For correct use of the command, use ```!c poll help```" + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + elif len(args) <=20: + poll_txt = "Use '!c vote' -command to vote in this poll! See '!c vote help' for more.\n\n**Options:**\n" + option_str = "" + i = 0 + for option in args: + option_str += option.strip() + ";" + poll_txt += f"**{str(i+1)}**: {option.strip()}\n" + i += 1 + + if len(poll_txt) >= 2048: + emb.description = "Poll character limit exceeded! Try reducing some characters." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + conn.close() + return + + emb.description = poll_txt + emb.color = get_hex_colour() + emb.title = title + msg = await message.channel.send(embed=emb) + footer = "Poll ID: " + str(msg.id) + emb.set_footer(text=footer) + + await msg.edit(embed=emb) + + dm_channel = message.author.dm_channel + if dm_channel == None: + dm_channel = await message.author.create_dm() + txt = "Your poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format(message.channel.name, message.guild.name, str(msg.id)) + txt2 = "```{}```".format(message.content) + + if titleStatus == 1: + title = None + + c.execute("INSERT INTO RolePolls VALUES (?,?,?,?,?,?)", (msg.id, message.channel.id, message.guild.id, message.author.id, option_str, title)) + conn.commit() + logging.info("Added poll {} into RolePolls database table.".format(msg.id)) + await dm_channel.send(txt) + await dm_channel.send(txt2) + await message.delete() + + else: + emb.description = "Exceeded maximum option amount of 20 options for polls!" + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + conn.close() async def rolePollEndHelper(): pass -async def endRolePoll(message): - pass \ No newline at end of file +async def vote(message): + pass + +async def voteHelp(message): + emb = discord.Embed() + emb.color = get_hex_colour() + emb.title = "Voting in polls" + emb.description = "You can vote in the _basic polls_ by reacting to the corresponding emote.\n\ + The vote command can be used in _advanced polls_ (indicated by the poll having numbers before the options instead of emotes).\ + **Vote command usage:**\n\ + ```!c vote [Poll ID] [option number]:[amount of votes], [option number]:[amount of votes], ...```\n\ + _NOTE!_ Poll ID can be found in the footer under the poll. You do not need to type the brackets." + + dm_channel = message.author.dm_channel + if dm_channel == None: + dm_channel = await message.author.create_dm() + + await dm_channel.send(embed=emb) + await message.delete() \ No newline at end of file From 461be1ae57d3ed56b74bf18f692831a5f7d4e56a Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Tue, 6 Apr 2021 01:24:37 +0300 Subject: [PATCH 04/20] Add new commands --- modules/commands.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/commands.py b/modules/commands.py index f3b8157..237ae43 100644 --- a/modules/commands.py +++ b/modules/commands.py @@ -12,9 +12,13 @@ async def cmds(message): choose [option1 | option2 | ...] vacc [Area code (or empty for all areas) | help] poll [new|end|help] +vote help Admin commands: giveaway -endgiveaway [GiveawayID]""" +endgiveaway [GiveawayID] +poll [set|edit|del]role +poll new -r +""" emb = discord.Embed(title="List of available commands:", description=cmd_list, colour=common.get_hex_colour(cora_blonde=True)) await message.channel.send(embed=emb) \ No newline at end of file From d34fc6068c7a3ac39e68c17975bbd83447b87666 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Tue, 6 Apr 2021 01:26:28 +0300 Subject: [PATCH 05/20] Differ the two different poll success messages --- modules/poll.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/poll.py b/modules/poll.py index 2bffec8..c9e5259 100644 --- a/modules/poll.py +++ b/modules/poll.py @@ -139,7 +139,7 @@ async def startBasicPoll(message): dm_channel = message.author.dm_channel if dm_channel == None: dm_channel = await message.author.create_dm() - txt = "Your poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format(message.channel.name, message.guild.name, str(msg.id)) + txt = "Your basic poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format(message.channel.name, message.guild.name, str(msg.id)) txt2 = "```{}```".format(message.content) emoji_str = "" @@ -331,7 +331,6 @@ async def startRolePoll(message): conn = sqlite3.connect(db_file) c = conn.cursor() g_id = message.guild.id - print(type(g_id)) c.execute(f"SELECT * FROM RolesMaxVotes WHERE Guild_ID={g_id}") roles = c.fetchall() @@ -385,7 +384,7 @@ async def startRolePoll(message): dm_channel = message.author.dm_channel if dm_channel == None: dm_channel = await message.author.create_dm() - txt = "Your poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format(message.channel.name, message.guild.name, str(msg.id)) + txt = "Your advanced poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format(message.channel.name, message.guild.name, str(msg.id)) txt2 = "```{}```".format(message.content) if titleStatus == 1: From 8eda51625287b9f00263761d4092be24ea314946 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Wed, 7 Apr 2021 20:10:27 +0300 Subject: [PATCH 06/20] Move regex compiles outside the functions This is a performance increase measure for possible higher volume --- modules/poll.py | 7 ++++--- modules/tirsk.py | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/poll.py b/modules/poll.py index c9e5259..0636898 100644 --- a/modules/poll.py +++ b/modules/poll.py @@ -8,6 +8,8 @@ _POLL_PREFIX = "!c poll " +RoleRE = re.compile(r"^.*<@&(\d+)>") + async def Poll(message): content = message.content.split(" ")[2] try: @@ -271,7 +273,7 @@ async def recordRoles(message): db_file = CURR_DIR + "\\databases.db" conn = sqlite3.connect(db_file) c = conn.cursor() - reg = re.compile(r"^.*<@&(\d+)>") + results = {} for arg in args: @@ -286,7 +288,7 @@ async def recordRoles(message): return # parse mention - match = reg.match(role) + match = RoleRE.match(role) if match: role_id = match.group(1).strip() else: @@ -322,7 +324,6 @@ async def recordRoles(message): conn.commit() conn.close() - async def startRolePoll(message): # Command structure: # !c poll new -r [title]; [option1]; [option2]; ... ; [option20] diff --git a/modules/tirsk.py b/modules/tirsk.py index 5edd97f..bd64160 100644 --- a/modules/tirsk.py +++ b/modules/tirsk.py @@ -4,12 +4,14 @@ from datetime import datetime import re +MentionRE = re.compile(r"^.*<@!(\d+)>") + async def tirskCount(message): logging.info("Started quote counting in {}".format(message.channel.name)) emb = discord.Embed(description="_Counting quotes... (this could take a while)_", color=get_hex_colour()) msgID = await message.channel.send(embed=emb) counter = {} - reg = re.compile(r"^.*<@!(\d+)>") + async for msg in message.channel.history(limit=None): mentions = msg.mentions if len(mentions) == 0: @@ -23,7 +25,7 @@ async def tirskCount(message): elif len(mentions) >= 2: # pos = msg.content.rfind("<") # user_id = msg.content[pos:].strip()[3:][:-1] - match = reg.match(msg.content) + match = MentionRE.match(msg.content) if match: user_id = match.group(1) user = await message.guild.fetch_member(int(user_id)) From 1b75cf4fd3a72ef9470b3b3009bdd0191a06472a Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Wed, 7 Apr 2021 21:11:32 +0300 Subject: [PATCH 07/20] Fix typos & implement max vote editing Implement role max vote editing to setrole command. --- modules/poll.py | 82 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/modules/poll.py b/modules/poll.py index 0636898..200b155 100644 --- a/modules/poll.py +++ b/modules/poll.py @@ -31,7 +31,7 @@ async def Poll(message): emb.description = "You do not have the permissions to use this." emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) - elif content == "setrole": + elif content == "setroles": if message.author.guild_permissions.administrator: await recordRoles(message) else: @@ -60,8 +60,8 @@ async def sendHelp(message): txt2 = "_**Advanced polls**_\n\ Please note that advanced polls require administrator permissions to use.\ With advanced polls you can set different maximum vote amounts for different roles. Voting will be done via a command as opposed to reactions in the basic polls. You can end advanced polls the same command as basic polls.\n\ - To add roles into the bot's database, use \n```!c poll setroles [role]:[voteamount],[role]:[voteamount], ...```\n\ - You can add as many roles as you need. Input the role as a mention (@role) or a role ID (you can get a role ID by enabling Discord's Developer mode. Then go to 'Server Settings' -> 'Roles' and copy the ID by right clicking on the role and selecting 'Copy ID'. To enable Developer mode, see https://support.discord.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID-).\ + To add or edit roles in(to) the bot's database, use \n```!c poll setroles [role]:[voteamount],[role]:[voteamount], ...```\n\ + You can add as many roles as you need. Input the role as a mention (@role) or a role ID if you don't want to mention the role (you can get a role ID by enabling Discord's Developer mode. Then go to 'Server Settings' -> 'Roles' and copy the ID by right clicking on the role and selecting 'Copy ID'. To enable Developer mode, see https://support.discord.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID-).\ 'voteamount' should be an integer.\n\ \n\ **Adding a new advanced poll:**\ @@ -260,7 +260,7 @@ async def endBasicPoll(message): async def recordRoles(message): # Command format # !c poll setroles [role]:[voteamount],[role]:[voteamount] : ... - prefix = _POLL_PREFIX + "setrole " + prefix = _POLL_PREFIX + "setroles " emb = discord.Embed() args = message.content[len(prefix):].split(",") @@ -273,13 +273,19 @@ async def recordRoles(message): db_file = CURR_DIR + "\\databases.db" conn = sqlite3.connect(db_file) c = conn.cursor() - - results = {} + + c.execute(f"SELECT Role_ID FROM RolesMaxVotes WHERE Guild_ID={message.guild.id}") + RolesInDB = c.fetchall() + + added = {} + updated = {} for arg in args: try: role = arg.split(":")[0].strip() amount = int(arg.split(":")[1]) + if len(role) == 0: + continue except ValueError: emb.description = "Invalid arguments, role must be an ID or a mention and amount must be an integer. \nAlso make sure you have commas and colons in the right place." emb.color = get_hex_colour(error=True) @@ -302,28 +308,64 @@ async def recordRoles(message): conn.close() return - try: - c.execute("INSERT INTO RolesMaxVotes VALUES (?,?,?)", (role_int, message.guild.id, amount)) - except sqlite3.IntegrityError: - emb.description = "One or more roles are already in the database. To edit roles use '!c poll editrole'." - emb.color = get_hex_colour(error=True) - await message.channel.send(embed=emb) - return - results[role_int] = amount - txt = "**Following roles & vote amounts were set:**\n" + roleT = (role_int,) + if roleT in RolesInDB: + c.execute("UPDATE RolesMaxVotes SET MaxVotes=? WHERE Role_ID=?", (amount, role_int)) + updated[role_int] = amount + else: + try: + c.execute("INSERT INTO RolesMaxVotes VALUES (?,?,?)", (role_int, message.guild.id, amount)) + except sqlite3.IntegrityError: + emb.description = "Error adding roles to database. Aborting." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + return + added[role_int] = amount + txt1 = "**Following roles & vote amounts were set:**\n" + txt2 = "**Following roles & vote amounts were updated:**\n" + comb = "" roles = await message.guild.fetch_roles() - for role in roles: - if role.id in results: - # TODO Add SyntaxError check for illegal Unicode emojis - txt += f"'{role.name}' : {results[role.id]}" + if len(added) > 0: + for role in roles: + if role.id in added: + # TODO Add SyntaxError check for illegal Unicode emojis + txt1 += f"'{role.name}' : {added[role.id]}\n" + comb += txt1 + + if len(updated) > 0: + for role in roles: + if role.id in updated: + txt2 += f"'{role.name}' : {updated[role.id]}\n" + if len(comb) > 0: + comb += f"\n{txt2}" + else: + comb += txt2 - emb.description = txt + # TODO Add checks for message length + emb.description = comb emb.colour = get_hex_colour() await message.channel.send(embed=emb) conn.commit() conn.close() +async def delRoles(message): + # Command format + # !c poll setroles [role],[role], ... + prefix = _POLL_PREFIX + "setroles " + emb = discord.Embed() + args = message.content[len(prefix):].split(",") + + if args == 0: + emb.description = "You did not give any arguments. Use '!c poll help' for the correct syntax." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + return + + db_file = CURR_DIR + "\\databases.db" + conn = sqlite3.connect(db_file) + c = conn.cursor() + async def startRolePoll(message): # Command structure: # !c poll new -r [title]; [option1]; [option2]; ... ; [option20] From 94ff3e8134d0387b9dfe1dc4abb5b5a4da9a5ffd Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Wed, 7 Apr 2021 21:17:59 +0300 Subject: [PATCH 08/20] Format files with Black Format files for better readability --- main.py | 34 +++-- modules/choose.py | 17 ++- modules/commands.py | 7 +- modules/common.py | 57 +++++--- modules/emoji_list.py | 312 +++++++++++++++++++++--------------------- modules/giveaway.py | 36 +++-- modules/insult.py | 13 +- modules/poll.py | 146 +++++++++++++++----- modules/quote.py | 9 +- modules/tirsk.py | 10 +- modules/vaccine.py | 88 +++++++----- 11 files changed, 441 insertions(+), 288 deletions(-) diff --git a/main.py b/main.py index 542cdd0..b4e964e 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,8 @@ import discord import logging import os -#import tweepy + +# import tweepy # import scripts from modules import common @@ -9,19 +10,28 @@ from modules import insult from modules import commands from modules import choose -#from modules import get_tweet + +# from modules import get_tweet from modules import giveaway from modules import pressF from modules import vaccine from modules import tirsk from modules import poll +# TODO Commit viestin lähetystä ennen +# TODO Sqlite connectit with:in kanssa + PREFIX = "!c " AUTHOR = "This bot is maintained by Appelsiini1" GIT = "Source code for this bot can be found at https://github.com/Appelsiini1/CoraBot" -logging.basicConfig(filename="Coralog.txt", level=logging.INFO, format='%(asctime)s %(levelname)s - %(message)s', datefmt='%d/%m/%Y %H:%M:%S') +logging.basicConfig( + filename="Coralog.txt", + level=logging.INFO, + format="%(asctime)s %(levelname)s - %(message)s", + datefmt="%d/%m/%Y %H:%M:%S", +) client = discord.Client() tokens = common.get_tokens() discordToken = tokens[0].lstrip("TOKEN").strip()[1:] @@ -30,19 +40,24 @@ common.initializeDatabase() -#twitter_auth = tweepy.AppAuthHandler(Twit_API_key, Twit_API_secret) +# twitter_auth = tweepy.AppAuthHandler(Twit_API_key, Twit_API_secret) + @client.event async def on_ready(): - print('{0.user} is online & ready.'.format(client)) - logging.info('{0.user} is online & ready.'.format(client)) + print("{0.user} is online & ready.".format(client)) + logging.info("{0.user} is online & ready.".format(client)) + # main event, parses commands @client.event async def on_message(message): if message.author == client.user: return - elif message.content.find("sairasta") != -1 or message.content.find("ei oo normaalii") != -1: + elif ( + message.content.find("sairasta") != -1 + or message.content.find("ei oo normaalii") != -1 + ): print("sairasta") msg = "https://cdn.discordapp.com/attachments/693166291468681227/823282434203189258/eioonormaalii.gif" await message.channel.send(msg) @@ -53,7 +68,7 @@ async def on_message(message): cmd = message.content.split(" ")[1] if cmd == "hi" or cmd == "hello": - await message.channel.send('Hello!') + await message.channel.send("Hello!") elif cmd == "help": await commands.cmds(message) elif cmd == "author": @@ -69,7 +84,7 @@ async def on_message(message): elif cmd.lower() == "f": await pressF.pressF(message) elif cmd == "tweet": - #await get_tweet.get_tweet(message, twitter_auth) + # await get_tweet.get_tweet(message, twitter_auth) await message.channel.send("This feature is not yet implemented! Sorry!") elif cmd == "giveaway": await giveaway.initiate_giveaway(message) @@ -85,4 +100,5 @@ async def on_message(message): else: await message.channel.send("What was that?") + client.run(discordToken) diff --git a/modules/choose.py b/modules/choose.py index 9080c79..8e27724 100644 --- a/modules/choose.py +++ b/modules/choose.py @@ -1,18 +1,25 @@ import random import discord -from modules.common import get_hex_colour #pylint: disable=import-error +from modules.common import get_hex_colour # pylint: disable=import-error + async def choose(message): repl = message.content[9:] args = repl.strip().split("|") - valid = [x for x in args if x.strip() != ''] + valid = [x for x in args if x.strip() != ""] if len(valid) < 2: msg = "**I need at least 2 options! Syntax: [option1] | [option2] ...**" else: - random_n = random.randint(0, len(valid)-1) + random_n = random.randint(0, len(valid) - 1) chosen = valid[random_n] - msg = "**"+ message.author.display_name + ", I choose '" + chosen.strip()+"'!**" - + msg = ( + "**" + + message.author.display_name + + ", I choose '" + + chosen.strip() + + "'!**" + ) + emb = discord.Embed(title=msg, color=get_hex_colour(cora_eye=True)) await message.channel.send(embed=emb) \ No newline at end of file diff --git a/modules/commands.py b/modules/commands.py index 237ae43..d963f1e 100644 --- a/modules/commands.py +++ b/modules/commands.py @@ -1,6 +1,7 @@ import discord from modules import common + async def cmds(message): cmd_list = """hi (alias: hello) help @@ -20,5 +21,9 @@ async def cmds(message): poll [set|edit|del]role poll new -r """ - emb = discord.Embed(title="List of available commands:", description=cmd_list, colour=common.get_hex_colour(cora_blonde=True)) + emb = discord.Embed( + title="List of available commands:", + description=cmd_list, + colour=common.get_hex_colour(cora_blonde=True), + ) await message.channel.send(embed=emb) \ No newline at end of file diff --git a/modules/common.py b/modules/common.py index 0b34645..7693d05 100644 --- a/modules/common.py +++ b/modules/common.py @@ -8,23 +8,25 @@ CURR_DIR = os.path.dirname(os.path.realpath(__file__)) + def get_hex_colour(cora_blonde=False, cora_eye=False, error=False): """Returns a hex colour as a discord.Colour object -Args: cora_blonde = [True|False] Default: False -cora_eye = [True|False] Default: False -error = [True|False] Default: False""" + Args: cora_blonde = [True|False] Default: False + cora_eye = [True|False] Default: False + error = [True|False] Default: False""" if cora_blonde == True: - color = discord.Colour(value=0xffcc99) + color = discord.Colour(value=0xFFCC99) elif cora_eye == True: - color = discord.Colour(value=0x338b41) + color = discord.Colour(value=0x338B41) elif error == True: color = discord.Colour(value=0xFF0000) else: - random_n = random.randint(0,16777215) + random_n = random.randint(0, 16777215) color = discord.Colour(value=random_n) - + return color + def get_tokens(): """Gets environment variables. Returns a list.""" try: @@ -35,12 +37,13 @@ def get_tokens(): sys.exit(1) return tokens + def selectReactionEmoji(n, indexes=False): selected = [] r_ns = [] i = 0 - while(i" - w_msg = "**Gongratulations " + mention_str + " you are the winner of the giveaway!** " + EMOJI + EMOJI + random_n = random.randint(0, len(list_user) - 1) + mention_str = "<@" + str(winner_id) + ">" + w_msg = ( + "**Gongratulations " + + mention_str + + " you are the winner of the giveaway!** " + + EMOJI + + EMOJI + ) await message.channel.send(w_msg) else: - await message.channel.send("Sorry, you do not have permissions to end a giveaway on this server.") \ No newline at end of file + await message.channel.send( + "Sorry, you do not have permissions to end a giveaway on this server." + ) diff --git a/modules/insult.py b/modules/insult.py index a8f60c4..e403e52 100644 --- a/modules/insult.py +++ b/modules/insult.py @@ -3,22 +3,27 @@ import discord import logging + async def insult(message): prefix = "!c insult " - response = requests.get("https://evilinsult.com/generate_insult.php?lang=en&type=json") + response = requests.get( + "https://evilinsult.com/generate_insult.php?lang=en&type=json" + ) if response.status_code == 200: json_data = json.loads(response.text) if len(message.content.split(" ")) > 2: try: mentioned_user = message.mentions[0].mention except IndexError: - mentioned_user = message.content[len(prefix):] - quote = "Hey "+mentioned_user+"! " + json_data["insult"] + mentioned_user = message.content[len(prefix) :] + quote = "Hey " + mentioned_user + "! " + json_data["insult"] else: quote = json_data["insult"] await message.channel.send(quote) else: - msg = "Could not fetch insult, server responded with code {}".format(response.status_code) + msg = "Could not fetch insult, server responded with code {}".format( + response.status_code + ) logging.error(msg) await message.channel.send(msg) \ No newline at end of file diff --git a/modules/poll.py b/modules/poll.py index 200b155..b0312b0 100644 --- a/modules/poll.py +++ b/modules/poll.py @@ -10,6 +10,7 @@ RoleRE = re.compile(r"^.*<@&(\d+)>") + async def Poll(message): content = message.content.split(" ")[2] try: @@ -41,7 +42,8 @@ async def Poll(message): await message.channel.send(embed=emb) else: await sendHelp(message) - #elif content == "edit": #TODO add an edit command? + # elif content == "edit": #TODO add an edit command? + async def sendHelp(message): emb = discord.Embed() @@ -81,12 +83,13 @@ async def sendHelp(message): dm_channel = message.author.dm_channel if dm_channel == None: dm_channel = await message.author.create_dm() - + emb.description = txt1 await dm_channel.send(embed=emb) emb.description = txt2 await dm_channel.send(embed=emb) + async def startBasicPoll(message): # Command structure: # !c poll new [title]; [option1]; [option2]; ... ; [option20] @@ -97,7 +100,7 @@ async def startBasicPoll(message): prefix = _POLL_PREFIX + "new " emb = discord.Embed() - args = message.content[len(prefix):].split(";") + args = message.content[len(prefix) :].split(";") title = args[0] titleStatus = 0 del args[0] @@ -106,21 +109,25 @@ async def startBasicPoll(message): titleStatus = 1 if len(args) <= 1 or message.content.find(";") == -1: - #help command + # help command emb.description = "You gave less than 2 options or you are missing separators. For correct use of the command, use ```!c poll help```" emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) - elif len(args) <=20: - poll_txt = "React with the emojis listed below to vote on this poll!\n\n**Options:**\n" + elif len(args) <= 20: + poll_txt = ( + "React with the emojis listed below to vote on this poll!\n\n**Options:**\n" + ) emoji_list = selectReactionEmoji(len(args), indexes=True) i = 0 for option in args: emoji = _EMOJIS[emoji_list[i]] - poll_txt += emoji +": " + option.strip() + "\n" + poll_txt += emoji + ": " + option.strip() + "\n" i += 1 if len(poll_txt) >= 2048: - emb.description = "Poll character limit exceeded! Try reducing some characters." + emb.description = ( + "Poll character limit exceeded! Try reducing some characters." + ) emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) conn.close() @@ -141,7 +148,9 @@ async def startBasicPoll(message): dm_channel = message.author.dm_channel if dm_channel == None: dm_channel = await message.author.create_dm() - txt = "Your basic poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format(message.channel.name, message.guild.name, str(msg.id)) + txt = "Your basic poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format( + message.channel.name, message.guild.name, str(msg.id) + ) txt2 = "```{}```".format(message.content) emoji_str = "" @@ -149,8 +158,18 @@ async def startBasicPoll(message): emoji_str += str(i) + "," if titleStatus == 1: title = None - - c.execute("INSERT INTO BasicPolls VALUES (?,?,?,?,?,?)", (msg.id, message.channel.id, message.guild.id, message.author.id, emoji_str, title)) + + c.execute( + "INSERT INTO BasicPolls VALUES (?,?,?,?,?,?)", + ( + msg.id, + message.channel.id, + message.guild.id, + message.author.id, + emoji_str, + title, + ), + ) conn.commit() logging.info("Added poll {} into BasicPolls database table.".format(msg.id)) await dm_channel.send(txt) @@ -162,6 +181,7 @@ async def startBasicPoll(message): await message.channel.send(embed=emb) conn.close() + async def pollEndHelper(poll, message): emb = discord.Embed() emb.color = get_hex_colour() @@ -176,7 +196,7 @@ async def pollEndHelper(poll, message): originalEmojis = poll[4][:-1].split(",") emojis = [] - for i in originalEmojis: + for i in originalEmojis: emojis.append(_EMOJIS[int(i)]) pollName = poll[5] @@ -192,7 +212,7 @@ async def pollEndHelper(poll, message): txt = "" i = 0 - for keypair in sorted(results.items(),key=lambda x:x[1], reverse=True): + for keypair in sorted(results.items(), key=lambda x: x[1], reverse=True): if i == 0: txt += f"{keypair[0]}** : _{keypair[1]-1}_**\n" else: @@ -202,11 +222,12 @@ async def pollEndHelper(poll, message): emb.description = txt return emb + async def endBasicPoll(message): # Command structure: # !c poll end [poll_ID] - #TODO Consolidate RolePoll and BasicPoll ending under this function + # TODO Consolidate RolePoll and BasicPoll ending under this function db_file = CURR_DIR + "\\databases.db" conn = sqlite3.connect(db_file) @@ -216,7 +237,10 @@ async def endBasicPoll(message): emb = discord.Embed() if len(message.content.split(" ")) == 3: - c.execute("SELECT * FROM BasicPolls WHERE Author_ID=? AND Ch_ID=?", (message.author.id, message.channel.id)) + c.execute( + "SELECT * FROM BasicPolls WHERE Author_ID=? AND Ch_ID=?", + (message.author.id, message.channel.id), + ) polls = c.fetchall() if len(polls) == 0: emb.description = "There are no polls running that have been initiated by you on this channel." @@ -227,45 +251,64 @@ async def endBasicPoll(message): for poll in polls: emb = await pollEndHelper(poll, message) await message.channel.send(embed=emb) - c.execute("DELETE FROM BasicPolls WHERE Author_ID=? AND Ch_ID=?", (message.author.id, message.channel.id)) + c.execute( + "DELETE FROM BasicPolls WHERE Author_ID=? AND Ch_ID=?", + (message.author.id, message.channel.id), + ) conn.commit() - logging.info(f"{len(polls)} poll(s) by {message.author.name} succesfully ended in {message.channel.name}") + logging.info( + f"{len(polls)} poll(s) by {message.author.name} succesfully ended in {message.channel.name}" + ) else: try: arg = int(message.content.split(" ")[3]) except Exception: - logging.exception("Something went wrong when trying to convert poll ID to int") + logging.exception( + "Something went wrong when trying to convert poll ID to int" + ) txt = "\N{no entry} Invalid poll ID!" await message.channel.send(txt) conn.close() return - - c.execute("SELECT * FROM BasicPolls WHERE Author_ID=? AND Ch_ID=? AND Poll_ID=?", (message.author.id, message.channel.id, arg)) + + c.execute( + "SELECT * FROM BasicPolls WHERE Author_ID=? AND Ch_ID=? AND Poll_ID=?", + (message.author.id, message.channel.id, arg), + ) poll = c.fetchall() if len(poll) == 0: - emb.color= get_hex_colour(error=True) + emb.color = get_hex_colour(error=True) emb.description = f"Unable to find poll with ID '{arg}'" await message.channel.send(embed=emb) else: emb = await pollEndHelper(poll[0], message) await message.channel.send(embed=emb) - c.execute("DELETE FROM BasicPolls WHERE Author_ID=? AND Ch_ID=? AND Poll_ID=?", (message.author.id, message.channel.id, arg)) + c.execute( + "DELETE FROM BasicPolls WHERE Author_ID=? AND Ch_ID=? AND Poll_ID=?", + (message.author.id, message.channel.id, arg), + ) conn.commit() - logging.info(f"Poll by {message.author.name} succesfully ended in {message.channel.name}") + logging.info( + f"Poll by {message.author.name} succesfully ended in {message.channel.name}" + ) await message.delete() conn.close() -# ######################################################################################################## # + +# ######################################################################################################## # + async def recordRoles(message): # Command format # !c poll setroles [role]:[voteamount],[role]:[voteamount] : ... prefix = _POLL_PREFIX + "setroles " emb = discord.Embed() - args = message.content[len(prefix):].split(",") + args = message.content[len(prefix) :].split(",") if args == 0: - emb.description = "You did not give any arguments. Use '!c poll help' for the correct syntax." + emb.description = ( + "You did not give any arguments. Use '!c poll help' for the correct syntax." + ) emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) return @@ -310,11 +353,17 @@ async def recordRoles(message): roleT = (role_int,) if roleT in RolesInDB: - c.execute("UPDATE RolesMaxVotes SET MaxVotes=? WHERE Role_ID=?", (amount, role_int)) + c.execute( + "UPDATE RolesMaxVotes SET MaxVotes=? WHERE Role_ID=?", + (amount, role_int), + ) updated[role_int] = amount else: try: - c.execute("INSERT INTO RolesMaxVotes VALUES (?,?,?)", (role_int, message.guild.id, amount)) + c.execute( + "INSERT INTO RolesMaxVotes VALUES (?,?,?)", + (role_int, message.guild.id, amount), + ) except sqlite3.IntegrityError: emb.description = "Error adding roles to database. Aborting." emb.color = get_hex_colour(error=True) @@ -349,15 +398,18 @@ async def recordRoles(message): conn.commit() conn.close() + async def delRoles(message): # Command format # !c poll setroles [role],[role], ... prefix = _POLL_PREFIX + "setroles " emb = discord.Embed() - args = message.content[len(prefix):].split(",") + args = message.content[len(prefix) :].split(",") if args == 0: - emb.description = "You did not give any arguments. Use '!c poll help' for the correct syntax." + emb.description = ( + "You did not give any arguments. Use '!c poll help' for the correct syntax." + ) emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) return @@ -366,6 +418,7 @@ async def delRoles(message): conn = sqlite3.connect(db_file) c = conn.cursor() + async def startRolePoll(message): # Command structure: # !c poll new -r [title]; [option1]; [option2]; ... ; [option20] @@ -386,7 +439,7 @@ async def startRolePoll(message): prefix = _POLL_PREFIX + "new -r " - args = message.content[len(prefix):].split(";") + args = message.content[len(prefix) :].split(";") title = args[0] titleStatus = 0 del args[0] @@ -395,11 +448,11 @@ async def startRolePoll(message): titleStatus = 1 if len(args) <= 1 or message.content.find(";") == -1: - #help command + # help command emb.description = "You gave less than 2 options or you are missing separators. For correct use of the command, use ```!c poll help```" emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) - elif len(args) <=20: + elif len(args) <= 20: poll_txt = "Use '!c vote' -command to vote in this poll! See '!c vote help' for more.\n\n**Options:**\n" option_str = "" i = 0 @@ -409,7 +462,9 @@ async def startRolePoll(message): i += 1 if len(poll_txt) >= 2048: - emb.description = "Poll character limit exceeded! Try reducing some characters." + emb.description = ( + "Poll character limit exceeded! Try reducing some characters." + ) emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) conn.close() @@ -427,13 +482,25 @@ async def startRolePoll(message): dm_channel = message.author.dm_channel if dm_channel == None: dm_channel = await message.author.create_dm() - txt = "Your advanced poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format(message.channel.name, message.guild.name, str(msg.id)) + txt = "Your advanced poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format( + message.channel.name, message.guild.name, str(msg.id) + ) txt2 = "```{}```".format(message.content) if titleStatus == 1: title = None - - c.execute("INSERT INTO RolePolls VALUES (?,?,?,?,?,?)", (msg.id, message.channel.id, message.guild.id, message.author.id, option_str, title)) + + c.execute( + "INSERT INTO RolePolls VALUES (?,?,?,?,?,?)", + ( + msg.id, + message.channel.id, + message.guild.id, + message.author.id, + option_str, + title, + ), + ) conn.commit() logging.info("Added poll {} into RolePolls database table.".format(msg.id)) await dm_channel.send(txt) @@ -446,12 +513,15 @@ async def startRolePoll(message): await message.channel.send(embed=emb) conn.close() + async def rolePollEndHelper(): pass + async def vote(message): pass + async def voteHelp(message): emb = discord.Embed() emb.color = get_hex_colour() @@ -465,6 +535,6 @@ async def voteHelp(message): dm_channel = message.author.dm_channel if dm_channel == None: dm_channel = await message.author.create_dm() - + await dm_channel.send(embed=emb) await message.delete() \ No newline at end of file diff --git a/modules/quote.py b/modules/quote.py index a004658..bc006be 100644 --- a/modules/quote.py +++ b/modules/quote.py @@ -1,18 +1,21 @@ import requests import json -from modules.common import get_hex_colour #pylint: disable=import-error +from modules.common import get_hex_colour # pylint: disable=import-error import logging import discord + async def get_quote(message): response = requests.get("https://zenquotes.io/api/random") if response.status_code == 200: json_data = json.loads(response.text) - quote = "_"+json_data[0]['q'] + "_ -" + json_data[0]['a'] + quote = "_" + json_data[0]["q"] + "_ -" + json_data[0]["a"] emb = discord.Embed(description=quote, color=get_hex_colour()) else: - msg = "Could not get quote, server responded with code {}".format(response.status_code) + msg = "Could not get quote, server responded with code {}".format( + response.status_code + ) logging.error(msg) emb = discord.Embed(description=msg, color=0xFF0000) diff --git a/modules/tirsk.py b/modules/tirsk.py index bd64160..d416ab3 100644 --- a/modules/tirsk.py +++ b/modules/tirsk.py @@ -6,12 +6,16 @@ MentionRE = re.compile(r"^.*<@!(\d+)>") + async def tirskCount(message): logging.info("Started quote counting in {}".format(message.channel.name)) - emb = discord.Embed(description="_Counting quotes... (this could take a while)_", color=get_hex_colour()) + emb = discord.Embed( + description="_Counting quotes... (this could take a while)_", + color=get_hex_colour(), + ) msgID = await message.channel.send(embed=emb) counter = {} - + async for msg in message.channel.history(limit=None): mentions = msg.mentions if len(mentions) == 0: @@ -37,7 +41,7 @@ async def tirskCount(message): txt = "" time = datetime.today().strftime("%d.%m.%Y") - for keypair in sorted(counter.items(),key=lambda x:x[1], reverse=True): + for keypair in sorted(counter.items(), key=lambda x: x[1], reverse=True): name = await message.guild.fetch_member(keypair[0]) if name: name = name.display_name diff --git a/modules/vaccine.py b/modules/vaccine.py index e6ba872..58e6b08 100644 --- a/modules/vaccine.py +++ b/modules/vaccine.py @@ -5,34 +5,43 @@ from modules.common import get_hex_colour import logging -ALUEET = {"518327": "Ahvenanmaa", -"518294": "Etelä-Karjalan SHP", -"518309": "Etelä-Pohjanmaan SHP", -"518306": "Etelä-Savon SHP", -"518320": "Helsingin ja Uudenmaan SHP", -"518377": "Itä-Savon SHP", -"518303": "Kainuun SHP", -"518340": "Kanta-Hämeen SHP", -"518369": "Keski-Pohjanmaan SHP", -"518295": "Keski-Suomen SHP", -"518335": "Kymenlaakson SHP", -"518322": "Lapin SHP", -"518353": "Länsi-Pohjan SHP", -"518298": "Pirkanmaan SHP", -"518343": "Pohjois-Karjalan SHP", -"518354": "Pohjois-Pohjanmaan SHP", -"518351": "Pohjois-Savon SHP", -"518300": "Päijät-Hämeen SHP", -"518366": "Satakunnan SHP", -"518323": "Vaasan SHP", -"518349": "Varsinais-Suomen SHP", -"518333": "Muut alueet", -"518362": "Kaikki alueet", -"184144": "Lappeenranta"} +ALUEET = { + "518327": "Ahvenanmaa", + "518294": "Etelä-Karjalan SHP", + "518309": "Etelä-Pohjanmaan SHP", + "518306": "Etelä-Savon SHP", + "518320": "Helsingin ja Uudenmaan SHP", + "518377": "Itä-Savon SHP", + "518303": "Kainuun SHP", + "518340": "Kanta-Hämeen SHP", + "518369": "Keski-Pohjanmaan SHP", + "518295": "Keski-Suomen SHP", + "518335": "Kymenlaakson SHP", + "518322": "Lapin SHP", + "518353": "Länsi-Pohjan SHP", + "518298": "Pirkanmaan SHP", + "518343": "Pohjois-Karjalan SHP", + "518354": "Pohjois-Pohjanmaan SHP", + "518351": "Pohjois-Savon SHP", + "518300": "Päijät-Hämeen SHP", + "518366": "Satakunnan SHP", + "518323": "Vaasan SHP", + "518349": "Varsinais-Suomen SHP", + "518333": "Muut alueet", + "518362": "Kaikki alueet", + "184144": "Lappeenranta", +} + def getVaccineInfo(param): - response = requests.get(f"https://sampo.thl.fi/pivot/prod/fi/vaccreg/cov19cov/fact_cov19cov.json?row=cov_vac_dose-533170&row=area-{param}", headers={'User-Agent': "Appelsiini1:n Discord Botti"}) - response2 = requests.get(f"https://sampo.thl.fi/pivot/prod/fi/vaccreg/cov19cov/fact_cov19cov.json?row=cov_vac_dose-533164&row=area-{param}", headers={'User-Agent': "Appelsiini1:n Discord Botti"}) + response = requests.get( + f"https://sampo.thl.fi/pivot/prod/fi/vaccreg/cov19cov/fact_cov19cov.json?row=cov_vac_dose-533170&row=area-{param}", + headers={"User-Agent": "Appelsiini1:n Discord Botti"}, + ) + response2 = requests.get( + f"https://sampo.thl.fi/pivot/prod/fi/vaccreg/cov19cov/fact_cov19cov.json?row=cov_vac_dose-533164&row=area-{param}", + headers={"User-Agent": "Appelsiini1:n Discord Botti"}, + ) if response.status_code == 200 and response2.status_code == 200: json_data = json.loads(response.text) vacc_data = json_data["dataset"]["value"].items() @@ -47,17 +56,20 @@ def getVaccineInfo(param): return one_dose, two_doses else: - msg = "Could not fetch vaccination data, server responded with code {0} and {1}.".format(response.status_code, response2.status_code) + msg = "Could not fetch vaccination data, server responded with code {0} and {1}.".format( + response.status_code, response2.status_code + ) logging.error(msg) - msg2= f"PARAM = {param}" + msg2 = f"PARAM = {param}" logging.error(msg2) logging.error(response.content) return msg, msg2 + def makeEmbed(one_dose, two_doses, emb, areaCode="Finland"): if two_doses.startswith("PARAM"): - emb.description=one_dose - emb.color=get_hex_colour(error=True) + emb.description = one_dose + emb.color = get_hex_colour(error=True) else: if areaCode != "Finland": area = ALUEET[areaCode] @@ -69,8 +81,11 @@ def makeEmbed(one_dose, two_doses, emb, areaCode="Finland"): emb.set_footer(text=f"Source: THL.fi") return emb + async def sendVaccInfo(message): - emb = discord.Embed(description="_Getting latest vaccine data from THL..._", color=get_hex_colour()) + emb = discord.Embed( + description="_Getting latest vaccine data from THL..._", color=get_hex_colour() + ) s_msg = await message.channel.send(embed=emb) if len(message.content.split(" ")) == 2: one_dose, two_doses = getVaccineInfo("518362") @@ -80,24 +95,23 @@ async def sendVaccInfo(message): elif len(message.content.split(" ")) > 2: param = message.content[7:].strip() if param == "help": - emb.title="Available areas:" + emb.title = "Available areas:" txt = "" for keypair in ALUEET.items(): txt = txt + keypair[0] + ": " + keypair[1] + "\n" - emb.description=txt + emb.description = txt await s_msg.edit(embed=emb) return - + else: try: ALUEET[param] except KeyError: - emb.description="Area code does not match any known areas. Please provide a valid code or leave empty for all areas.\ + emb.description = "Area code does not match any known areas. Please provide a valid code or leave empty for all areas.\ \nType '!c vacc help' for all currently available areas." - emb.color=get_hex_colour(error=True) + emb.color = get_hex_colour(error=True) await s_msg.edit(embed=emb) return one_dose, two_doses = getVaccineInfo(param) emb = makeEmbed(one_dose, two_doses, emb, areaCode=param) await s_msg.edit(embed=emb) - From b8fb8f7c1fcb98447c97c869f8f93315055dc6e0 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Wed, 7 Apr 2021 21:38:08 +0300 Subject: [PATCH 09/20] Switch to using with - as in database connections --- modules/common.py | 147 ++++++------ modules/poll.py | 576 +++++++++++++++++++++++----------------------- 2 files changed, 356 insertions(+), 367 deletions(-) diff --git a/modules/common.py b/modules/common.py index 7693d05..b9a2f96 100644 --- a/modules/common.py +++ b/modules/common.py @@ -65,77 +65,76 @@ async def sendEmoji(message): def initializeDatabase(): db_file = CURR_DIR + "\\databases.db" - conn = sqlite3.connect(db_file) - c = conn.cursor() - # BasicPolls Table - c.execute( - """CREATE TABLE IF NOT EXISTS BasicPolls( - Poll_ID INT UNIQUE, - Ch_ID INT, - Guild_ID INT, - Author_ID INT, - Emojis TEXT, - PollName TEXT, - PRIMARY KEY (Poll_ID) - );""" - ) - - # RolePolls Table - c.execute( - """CREATE TABLE IF NOT EXISTS RolePolls( - Poll_ID INT UNIQUE, - Ch_ID INT, - Guild_ID INT, - Author_ID INT, - Options TEXT, - PollName TEXT, - PRIMARY KEY (Poll_ID) - );""" - ) - - # MaxVotes - c.execute( - """CREATE TABLE IF NOT EXISTS RolesMaxVotes( - Role_ID INT UNIQUE, - Guild_ID INT, - MaxVotes INT, - PRIMARY KEY (Role_ID) - );""" - ) - - # Votes for RolePolls Table - c.execute( - """CREATE TABLE IF NOT EXISTS RolePolls_Votes( - Vote_ID INT UNIQUE, - Poll_ID INT, - Voter_ID INT, - option1 INT, - option2 INT, - option3 INT, - option4 INT, - option5 INT, - option6 INT, - option7 INT, - option8 INT, - option9 INT, - option10 INT, - option11 INT, - option12 INT, - option13 INT, - option14 INT, - option15 INT, - option16 INT, - option17 INT, - option18 INT, - option19 INT, - option20 INT, - PRIMARY KEY (Vote_ID) - FOREIGN KEY (Poll_ID) REFERENCES RolePolls(Poll_ID) - ON DELETE CASCADE - );""" - ) - - # other databases here - - conn.commit() - conn.close() \ No newline at end of file + with sqlite3.connect(db_file) as conn: + c = conn.cursor() + # BasicPolls Table + c.execute( + """CREATE TABLE IF NOT EXISTS BasicPolls( + Poll_ID INT UNIQUE, + Ch_ID INT, + Guild_ID INT, + Author_ID INT, + Emojis TEXT, + PollName TEXT, + PRIMARY KEY (Poll_ID) + );""" + ) + + # RolePolls Table + c.execute( + """CREATE TABLE IF NOT EXISTS RolePolls( + Poll_ID INT UNIQUE, + Ch_ID INT, + Guild_ID INT, + Author_ID INT, + Options TEXT, + PollName TEXT, + PRIMARY KEY (Poll_ID) + );""" + ) + + # MaxVotes + c.execute( + """CREATE TABLE IF NOT EXISTS RolesMaxVotes( + Role_ID INT UNIQUE, + Guild_ID INT, + MaxVotes INT, + PRIMARY KEY (Role_ID) + );""" + ) + + # Votes for RolePolls Table + c.execute( + """CREATE TABLE IF NOT EXISTS RolePolls_Votes( + Vote_ID INT UNIQUE, + Poll_ID INT, + Voter_ID INT, + option1 INT, + option2 INT, + option3 INT, + option4 INT, + option5 INT, + option6 INT, + option7 INT, + option8 INT, + option9 INT, + option10 INT, + option11 INT, + option12 INT, + option13 INT, + option14 INT, + option15 INT, + option16 INT, + option17 INT, + option18 INT, + option19 INT, + option20 INT, + PRIMARY KEY (Vote_ID) + FOREIGN KEY (Poll_ID) REFERENCES RolePolls(Poll_ID) + ON DELETE CASCADE + );""" + ) + + # other databases here + + conn.commit() \ No newline at end of file diff --git a/modules/poll.py b/modules/poll.py index b0312b0..be18166 100644 --- a/modules/poll.py +++ b/modules/poll.py @@ -95,91 +95,89 @@ async def startBasicPoll(message): # !c poll new [title]; [option1]; [option2]; ... ; [option20] db_file = CURR_DIR + "\\databases.db" - conn = sqlite3.connect(db_file) - c = conn.cursor() + with sqlite3.connect(db_file) as conn: + c = conn.cursor() + + prefix = _POLL_PREFIX + "new " + emb = discord.Embed() + args = message.content[len(prefix) :].split(";") + title = args[0] + titleStatus = 0 + del args[0] + if title.strip() == "": + title = f"A poll by {message.author.name}" + titleStatus = 1 + + if len(args) <= 1 or message.content.find(";") == -1: + # help command + emb.description = "You gave less than 2 options or you are missing separators. For correct use of the command, use ```!c poll help```" + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + elif len(args) <= 20: + poll_txt = ( + "React with the emojis listed below to vote on this poll!\n\n**Options:**\n" + ) + emoji_list = selectReactionEmoji(len(args), indexes=True) + i = 0 + for option in args: + emoji = _EMOJIS[emoji_list[i]] + poll_txt += emoji + ": " + option.strip() + "\n" + i += 1 + + if len(poll_txt) >= 2048: + emb.description = ( + "Poll character limit exceeded! Try reducing some characters." + ) + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + return - prefix = _POLL_PREFIX + "new " - emb = discord.Embed() - args = message.content[len(prefix) :].split(";") - title = args[0] - titleStatus = 0 - del args[0] - if title.strip() == "": - title = f"A poll by {message.author.name}" - titleStatus = 1 - - if len(args) <= 1 or message.content.find(";") == -1: - # help command - emb.description = "You gave less than 2 options or you are missing separators. For correct use of the command, use ```!c poll help```" - emb.color = get_hex_colour(error=True) - await message.channel.send(embed=emb) - elif len(args) <= 20: - poll_txt = ( - "React with the emojis listed below to vote on this poll!\n\n**Options:**\n" - ) - emoji_list = selectReactionEmoji(len(args), indexes=True) - i = 0 - for option in args: - emoji = _EMOJIS[emoji_list[i]] - poll_txt += emoji + ": " + option.strip() + "\n" - i += 1 - - if len(poll_txt) >= 2048: - emb.description = ( - "Poll character limit exceeded! Try reducing some characters." + emb.description = poll_txt + emb.color = get_hex_colour() + emb.title = title + msg = await message.channel.send(embed=emb) + footer = "Poll ID: " + str(msg.id) + emb.set_footer(text=footer) + + await msg.edit(embed=emb) + for i in emoji_list: + emoji = _EMOJIS[i] + await msg.add_reaction(emoji) + + dm_channel = message.author.dm_channel + if dm_channel == None: + dm_channel = await message.author.create_dm() + txt = "Your basic poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format( + message.channel.name, message.guild.name, str(msg.id) + ) + txt2 = "```{}```".format(message.content) + + emoji_str = "" + for i in emoji_list: + emoji_str += str(i) + "," + if titleStatus == 1: + title = None + + c.execute( + "INSERT INTO BasicPolls VALUES (?,?,?,?,?,?)", + ( + msg.id, + message.channel.id, + message.guild.id, + message.author.id, + emoji_str, + title, + ), ) + conn.commit() + logging.info("Added poll {} into BasicPolls database table.".format(msg.id)) + await dm_channel.send(txt) + await dm_channel.send(txt2) + await message.delete() + else: + emb.description = "Exceeded maximum option amount of 20 options for polls!" emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) - conn.close() - return - - emb.description = poll_txt - emb.color = get_hex_colour() - emb.title = title - msg = await message.channel.send(embed=emb) - footer = "Poll ID: " + str(msg.id) - emb.set_footer(text=footer) - - await msg.edit(embed=emb) - for i in emoji_list: - emoji = _EMOJIS[i] - await msg.add_reaction(emoji) - - dm_channel = message.author.dm_channel - if dm_channel == None: - dm_channel = await message.author.create_dm() - txt = "Your basic poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format( - message.channel.name, message.guild.name, str(msg.id) - ) - txt2 = "```{}```".format(message.content) - - emoji_str = "" - for i in emoji_list: - emoji_str += str(i) + "," - if titleStatus == 1: - title = None - - c.execute( - "INSERT INTO BasicPolls VALUES (?,?,?,?,?,?)", - ( - msg.id, - message.channel.id, - message.guild.id, - message.author.id, - emoji_str, - title, - ), - ) - conn.commit() - logging.info("Added poll {} into BasicPolls database table.".format(msg.id)) - await dm_channel.send(txt) - await dm_channel.send(txt2) - await message.delete() - else: - emb.description = "Exceeded maximum option amount of 20 options for polls!" - emb.color = get_hex_colour(error=True) - await message.channel.send(embed=emb) - conn.close() async def pollEndHelper(poll, message): @@ -230,69 +228,67 @@ async def endBasicPoll(message): # TODO Consolidate RolePoll and BasicPoll ending under this function db_file = CURR_DIR + "\\databases.db" - conn = sqlite3.connect(db_file) - c = conn.cursor() + with sqlite3.connect(db_file) as conn: + c = conn.cursor() - prefix = _POLL_PREFIX + "end " - emb = discord.Embed() + prefix = _POLL_PREFIX + "end " + emb = discord.Embed() - if len(message.content.split(" ")) == 3: - c.execute( - "SELECT * FROM BasicPolls WHERE Author_ID=? AND Ch_ID=?", - (message.author.id, message.channel.id), - ) - polls = c.fetchall() - if len(polls) == 0: - emb.description = "There are no polls running that have been initiated by you on this channel." - emb.color = get_hex_colour(error=True) - await message.channel.send(embed=emb) - - else: - for poll in polls: - emb = await pollEndHelper(poll, message) - await message.channel.send(embed=emb) + if len(message.content.split(" ")) == 3: c.execute( - "DELETE FROM BasicPolls WHERE Author_ID=? AND Ch_ID=?", + "SELECT * FROM BasicPolls WHERE Author_ID=? AND Ch_ID=?", (message.author.id, message.channel.id), ) - conn.commit() - logging.info( - f"{len(polls)} poll(s) by {message.author.name} succesfully ended in {message.channel.name}" - ) - else: - try: - arg = int(message.content.split(" ")[3]) - except Exception: - logging.exception( - "Something went wrong when trying to convert poll ID to int" - ) - txt = "\N{no entry} Invalid poll ID!" - await message.channel.send(txt) - conn.close() - return + polls = c.fetchall() + if len(polls) == 0: + emb.description = "There are no polls running that have been initiated by you on this channel." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) - c.execute( - "SELECT * FROM BasicPolls WHERE Author_ID=? AND Ch_ID=? AND Poll_ID=?", - (message.author.id, message.channel.id, arg), - ) - poll = c.fetchall() - if len(poll) == 0: - emb.color = get_hex_colour(error=True) - emb.description = f"Unable to find poll with ID '{arg}'" - await message.channel.send(embed=emb) + else: + for poll in polls: + emb = await pollEndHelper(poll, message) + await message.channel.send(embed=emb) + c.execute( + "DELETE FROM BasicPolls WHERE Author_ID=? AND Ch_ID=?", + (message.author.id, message.channel.id), + ) + conn.commit() + logging.info( + f"{len(polls)} poll(s) by {message.author.name} succesfully ended in {message.channel.name}" + ) else: - emb = await pollEndHelper(poll[0], message) - await message.channel.send(embed=emb) + try: + arg = int(message.content.split(" ")[3]) + except Exception: + logging.exception( + "Something went wrong when trying to convert poll ID to int" + ) + txt = "\N{no entry} Invalid poll ID!" + await message.channel.send(txt) + return + c.execute( - "DELETE FROM BasicPolls WHERE Author_ID=? AND Ch_ID=? AND Poll_ID=?", + "SELECT * FROM BasicPolls WHERE Author_ID=? AND Ch_ID=? AND Poll_ID=?", (message.author.id, message.channel.id, arg), ) - conn.commit() - logging.info( - f"Poll by {message.author.name} succesfully ended in {message.channel.name}" - ) - await message.delete() - conn.close() + poll = c.fetchall() + if len(poll) == 0: + emb.color = get_hex_colour(error=True) + emb.description = f"Unable to find poll with ID '{arg}'" + await message.channel.send(embed=emb) + else: + emb = await pollEndHelper(poll[0], message) + await message.channel.send(embed=emb) + c.execute( + "DELETE FROM BasicPolls WHERE Author_ID=? AND Ch_ID=? AND Poll_ID=?", + (message.author.id, message.channel.id, arg), + ) + conn.commit() + logging.info( + f"Poll by {message.author.name} succesfully ended in {message.channel.name}" + ) + await message.delete() # ######################################################################################################## # @@ -314,95 +310,91 @@ async def recordRoles(message): return db_file = CURR_DIR + "\\databases.db" - conn = sqlite3.connect(db_file) - c = conn.cursor() - - c.execute(f"SELECT Role_ID FROM RolesMaxVotes WHERE Guild_ID={message.guild.id}") - RolesInDB = c.fetchall() - - added = {} - updated = {} - - for arg in args: - try: - role = arg.split(":")[0].strip() - amount = int(arg.split(":")[1]) - if len(role) == 0: - continue - except ValueError: - emb.description = "Invalid arguments, role must be an ID or a mention and amount must be an integer. \nAlso make sure you have commas and colons in the right place." - emb.color = get_hex_colour(error=True) - await message.channel.send(embed=emb) - conn.close() - return + with sqlite3.connect(db_file) as conn: + c = conn.cursor() - # parse mention - match = RoleRE.match(role) - if match: - role_id = match.group(1).strip() - else: - role_id = role.strip() - try: - role_int = int(role_id) - except ValueError: - emb.description = "Invalid arguments, role must be an ID integer or a mention and amount must be an integer. \nAlso make sure you have commas and colons in the right place." - emb.color = get_hex_colour(error=True) - await message.channel.send(embed=emb) - conn.close() - return + c.execute(f"SELECT Role_ID FROM RolesMaxVotes WHERE Guild_ID={message.guild.id}") + RolesInDB = c.fetchall() - roleT = (role_int,) - if roleT in RolesInDB: - c.execute( - "UPDATE RolesMaxVotes SET MaxVotes=? WHERE Role_ID=?", - (amount, role_int), - ) - updated[role_int] = amount - else: + added = {} + updated = {} + + for arg in args: try: - c.execute( - "INSERT INTO RolesMaxVotes VALUES (?,?,?)", - (role_int, message.guild.id, amount), - ) - except sqlite3.IntegrityError: - emb.description = "Error adding roles to database. Aborting." + role = arg.split(":")[0].strip() + amount = int(arg.split(":")[1]) + if len(role) == 0: + continue + except ValueError: + emb.description = "Invalid arguments, role must be an ID or a mention and amount must be an integer. \nAlso make sure you have commas and colons in the right place." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + return + + # parse mention + match = RoleRE.match(role) + if match: + role_id = match.group(1).strip() + else: + role_id = role.strip() + try: + role_int = int(role_id) + except ValueError: + emb.description = "Invalid arguments, role must be an ID integer or a mention and amount must be an integer. \nAlso make sure you have commas and colons in the right place." emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) return - added[role_int] = amount - txt1 = "**Following roles & vote amounts were set:**\n" - txt2 = "**Following roles & vote amounts were updated:**\n" - comb = "" - roles = await message.guild.fetch_roles() - - if len(added) > 0: - for role in roles: - if role.id in added: - # TODO Add SyntaxError check for illegal Unicode emojis - txt1 += f"'{role.name}' : {added[role.id]}\n" - comb += txt1 - - if len(updated) > 0: - for role in roles: - if role.id in updated: - txt2 += f"'{role.name}' : {updated[role.id]}\n" - if len(comb) > 0: - comb += f"\n{txt2}" - else: - comb += txt2 - # TODO Add checks for message length - emb.description = comb - emb.colour = get_hex_colour() - await message.channel.send(embed=emb) - conn.commit() - conn.close() + roleT = (role_int,) + if roleT in RolesInDB: + c.execute( + "UPDATE RolesMaxVotes SET MaxVotes=? WHERE Role_ID=?", + (amount, role_int), + ) + updated[role_int] = amount + else: + try: + c.execute( + "INSERT INTO RolesMaxVotes VALUES (?,?,?)", + (role_int, message.guild.id, amount), + ) + except sqlite3.IntegrityError: + emb.description = "Error adding roles to database. Aborting." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + return + added[role_int] = amount + txt1 = "**Following roles & vote amounts were set:**\n" + txt2 = "**Following roles & vote amounts were updated:**\n" + comb = "" + roles = await message.guild.fetch_roles() + + if len(added) > 0: + for role in roles: + if role.id in added: + # TODO Add SyntaxError check for illegal Unicode emojis + txt1 += f"'{role.name}' : {added[role.id]}\n" + comb += txt1 + + if len(updated) > 0: + for role in roles: + if role.id in updated: + txt2 += f"'{role.name}' : {updated[role.id]}\n" + if len(comb) > 0: + comb += f"\n{txt2}" + else: + comb += txt2 + + # TODO Add checks for message length + emb.description = comb + emb.colour = get_hex_colour() + await message.channel.send(embed=emb) async def delRoles(message): # Command format - # !c poll setroles [role],[role], ... - prefix = _POLL_PREFIX + "setroles " + # !c poll delroles [role],[role], ... + prefix = _POLL_PREFIX + "delroles " emb = discord.Embed() args = message.content[len(prefix) :].split(",") @@ -415,8 +407,8 @@ async def delRoles(message): return db_file = CURR_DIR + "\\databases.db" - conn = sqlite3.connect(db_file) - c = conn.cursor() + with sqlite3.connect(db_file) as conn: + c = conn.cursor() async def startRolePoll(message): @@ -424,94 +416,92 @@ async def startRolePoll(message): # !c poll new -r [title]; [option1]; [option2]; ... ; [option20] db_file = CURR_DIR + "\\databases.db" - conn = sqlite3.connect(db_file) - c = conn.cursor() - g_id = message.guild.id - c.execute(f"SELECT * FROM RolesMaxVotes WHERE Guild_ID={g_id}") - roles = c.fetchall() - - emb = discord.Embed() - if len(roles) < 1: - emb.description = "You have not set the maximum vote amounts for roles. See '!c poll help' for more." - emb.color = get_hex_colour(error=True) - await message.channel.send(embed=emb) - return + with sqlite3.connect(db_file) as conn: + c = conn.cursor() + g_id = message.guild.id + c.execute(f"SELECT * FROM RolesMaxVotes WHERE Guild_ID={g_id}") + roles = c.fetchall() + + emb = discord.Embed() + if len(roles) < 1: + emb.description = "You have not set the maximum vote amounts for roles. See '!c poll help' for more." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + return - prefix = _POLL_PREFIX + "new -r " + prefix = _POLL_PREFIX + "new -r " - args = message.content[len(prefix) :].split(";") - title = args[0] - titleStatus = 0 - del args[0] - if title.strip() == "": - title = f"A poll by {message.author.name}" - titleStatus = 1 + args = message.content[len(prefix) :].split(";") + title = args[0] + titleStatus = 0 + del args[0] + if title.strip() == "": + title = f"A poll by {message.author.name}" + titleStatus = 1 - if len(args) <= 1 or message.content.find(";") == -1: - # help command - emb.description = "You gave less than 2 options or you are missing separators. For correct use of the command, use ```!c poll help```" - emb.color = get_hex_colour(error=True) - await message.channel.send(embed=emb) - elif len(args) <= 20: - poll_txt = "Use '!c vote' -command to vote in this poll! See '!c vote help' for more.\n\n**Options:**\n" - option_str = "" - i = 0 - for option in args: - option_str += option.strip() + ";" - poll_txt += f"**{str(i+1)}**: {option.strip()}\n" - i += 1 - - if len(poll_txt) >= 2048: - emb.description = ( - "Poll character limit exceeded! Try reducing some characters." - ) + if len(args) <= 1 or message.content.find(";") == -1: + # help command + emb.description = "You gave less than 2 options or you are missing separators. For correct use of the command, use ```!c poll help```" emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) - conn.close() - return + elif len(args) <= 20: + poll_txt = "Use '!c vote' -command to vote in this poll! See '!c vote help' for more.\n\n**Options:**\n" + option_str = "" + i = 0 + for option in args: + option_str += option.strip() + ";" + poll_txt += f"**{str(i+1)}**: {option.strip()}\n" + i += 1 + + if len(poll_txt) >= 2048: + emb.description = ( + "Poll character limit exceeded! Try reducing some characters." + ) + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + return - emb.description = poll_txt - emb.color = get_hex_colour() - emb.title = title - msg = await message.channel.send(embed=emb) - footer = "Poll ID: " + str(msg.id) - emb.set_footer(text=footer) + emb.description = poll_txt + emb.color = get_hex_colour() + emb.title = title + msg = await message.channel.send(embed=emb) + footer = "Poll ID: " + str(msg.id) + emb.set_footer(text=footer) - await msg.edit(embed=emb) + await msg.edit(embed=emb) - dm_channel = message.author.dm_channel - if dm_channel == None: - dm_channel = await message.author.create_dm() - txt = "Your advanced poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format( - message.channel.name, message.guild.name, str(msg.id) - ) - txt2 = "```{}```".format(message.content) - - if titleStatus == 1: - title = None - - c.execute( - "INSERT INTO RolePolls VALUES (?,?,?,?,?,?)", - ( - msg.id, - message.channel.id, - message.guild.id, - message.author.id, - option_str, - title, - ), - ) - conn.commit() - logging.info("Added poll {} into RolePolls database table.".format(msg.id)) - await dm_channel.send(txt) - await dm_channel.send(txt2) - await message.delete() + dm_channel = message.author.dm_channel + if dm_channel == None: + dm_channel = await message.author.create_dm() + txt = "Your advanced poll in channel '{0}' of '{1}' with ID {2} was succesfully created with command:".format( + message.channel.name, message.guild.name, str(msg.id) + ) + txt2 = "```{}```".format(message.content) - else: - emb.description = "Exceeded maximum option amount of 20 options for polls!" - emb.color = get_hex_colour(error=True) - await message.channel.send(embed=emb) - conn.close() + if titleStatus == 1: + title = None + + c.execute( + "INSERT INTO RolePolls VALUES (?,?,?,?,?,?)", + ( + msg.id, + message.channel.id, + message.guild.id, + message.author.id, + option_str, + title, + ), + ) + conn.commit() + logging.info("Added poll {} into RolePolls database table.".format(msg.id)) + await dm_channel.send(txt) + await dm_channel.send(txt2) + await message.delete() + + else: + emb.description = "Exceeded maximum option amount of 20 options for polls!" + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) async def rolePollEndHelper(): From 5a24ddb31a1f9516b689b6dbb92d9d4224735d2c Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Thu, 8 Apr 2021 00:07:41 +0300 Subject: [PATCH 10/20] Easter egg for TinyCactus --- modules/pressF.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/modules/pressF.py b/modules/pressF.py index 61fdb84..0d6c086 100644 --- a/modules/pressF.py +++ b/modules/pressF.py @@ -1,4 +1,19 @@ +import logging + + async def pressF(message): - msg = "{} has paid their respects.".format(message.author.display_name) + if message.guild.id == 181079344611852288: + emote_name = "cacF" + try: + for em in message.guild.emojis: + if em.name == emote_name: + emoji = em + break + msg = str(emoji) + except Exception as e: + logging.exception("Exception in !c f when trying to post 'cacF' emoji.") + msg = "{} has paid their respects.".format(message.author.display_name) + else: + msg = "{} has paid their respects.".format(message.author.display_name) await message.channel.send(msg) \ No newline at end of file From 75a5fca5cf3cbc1c7c1bdb0131610b1972651d92 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Thu, 8 Apr 2021 01:28:15 +0300 Subject: [PATCH 11/20] Change how database file is handled Now in it's own folder. Path fetching is now better too. --- .gitignore | 2 +- modules/common.py | 18 +++--------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 67f50e4..19b5469 100644 --- a/.gitignore +++ b/.gitignore @@ -123,4 +123,4 @@ modules/test_module.py Coralog.txt #Database -databases.db \ No newline at end of file +Databases/ \ No newline at end of file diff --git a/modules/common.py b/modules/common.py index b9a2f96..b24fb4a 100644 --- a/modules/common.py +++ b/modules/common.py @@ -5,8 +5,7 @@ from modules.emoji_list import _EMOJIS import sqlite3 import os - -CURR_DIR = os.path.dirname(os.path.realpath(__file__)) +from constants import DB_F def get_hex_colour(cora_blonde=False, cora_eye=False, error=False): @@ -27,17 +26,6 @@ def get_hex_colour(cora_blonde=False, cora_eye=False, error=False): return color -def get_tokens(): - """Gets environment variables. Returns a list.""" - try: - with open(".env", "r") as f: - tokens = f.readlines() - except Exception: - logging.exception("Could not acquire environment variables. Stopping.") - sys.exit(1) - return tokens - - def selectReactionEmoji(n, indexes=False): selected = [] r_ns = [] @@ -64,8 +52,7 @@ async def sendEmoji(message): def initializeDatabase(): - db_file = CURR_DIR + "\\databases.db" - with sqlite3.connect(db_file) as conn: + with sqlite3.connect(DB_F) as conn: c = conn.cursor() # BasicPolls Table c.execute( @@ -97,6 +84,7 @@ def initializeDatabase(): c.execute( """CREATE TABLE IF NOT EXISTS RolesMaxVotes( Role_ID INT UNIQUE, + Role_name TEXT, Guild_ID INT, MaxVotes INT, PRIMARY KEY (Role_ID) From dc98477046dfa088d4340606d1cc569d433b3d22 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Thu, 8 Apr 2021 01:29:34 +0300 Subject: [PATCH 12/20] Move constants to their own file Move constants and get_tokens()-function to their own file so imports in other files can be handled better. --- constants.py | 24 ++++++++++++++++++++++++ main.py | 17 ++--------------- 2 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 constants.py diff --git a/constants.py b/constants.py new file mode 100644 index 0000000..7161d2f --- /dev/null +++ b/constants.py @@ -0,0 +1,24 @@ +import os +from logging import exception +from sys import exit + + +def get_tokens(): + """Gets environment variables. Returns a list.""" + try: + with open(".env", "r") as f: + tokens = f.readlines() + except Exception: + exception("Could not acquire environment variables. Stopping.") + exit(1) + return tokens + + +PREFIX = "!c " +AUTHOR = "This bot is maintained by Appelsiini1" +GIT = "Source code for this bot can be found at https://github.com/Appelsiini1/CoraBot" +DB_F = os.path.dirname(os.path.realpath(__file__)) + "\\Databases\\database.db" +TOKENS = get_tokens() +DISCORD_TOKEN = TOKENS[0].lstrip("TOKEN").strip()[1:] +TWIT_API_KEY = TOKENS[1].lstrip("API_KEY").strip()[1:] +TWIT_API_SECRET = TOKENS[2].lstrip("API_SECRET").strip()[1:] \ No newline at end of file diff --git a/main.py b/main.py index b4e964e..d349f69 100644 --- a/main.py +++ b/main.py @@ -1,17 +1,15 @@ import discord import logging -import os # import tweepy # import scripts +from constants import * from modules import common from modules import quote from modules import insult from modules import commands from modules import choose - -# from modules import get_tweet from modules import giveaway from modules import pressF from modules import vaccine @@ -19,12 +17,6 @@ from modules import poll # TODO Commit viestin lähetystä ennen -# TODO Sqlite connectit with:in kanssa - -PREFIX = "!c " - -AUTHOR = "This bot is maintained by Appelsiini1" -GIT = "Source code for this bot can be found at https://github.com/Appelsiini1/CoraBot" logging.basicConfig( filename="Coralog.txt", @@ -33,11 +25,6 @@ datefmt="%d/%m/%Y %H:%M:%S", ) client = discord.Client() -tokens = common.get_tokens() -discordToken = tokens[0].lstrip("TOKEN").strip()[1:] -Twit_API_key = tokens[1].lstrip("API_KEY").strip()[1:] -Twit_API_secret = tokens[2].lstrip("API_SECRET").strip()[1:] - common.initializeDatabase() # twitter_auth = tweepy.AppAuthHandler(Twit_API_key, Twit_API_secret) @@ -101,4 +88,4 @@ async def on_message(message): await message.channel.send("What was that?") -client.run(discordToken) +client.run(DISCORD_TOKEN) From 43bcbd258d6abf2411399a6b761b337ab629d71f Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Thu, 8 Apr 2021 01:30:42 +0300 Subject: [PATCH 13/20] Remove unused imports --- modules/common.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/common.py b/modules/common.py index b24fb4a..dd4a3f2 100644 --- a/modules/common.py +++ b/modules/common.py @@ -1,10 +1,7 @@ import random import discord -import sys -import logging from modules.emoji_list import _EMOJIS import sqlite3 -import os from constants import DB_F From 7936d2be8e6e03cfe7303d370c7f7521914c2b9b Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Thu, 8 Apr 2021 02:13:15 +0300 Subject: [PATCH 14/20] Implement poll role modification, deletion & display - Change how database path is handled - Fix typos - Update help text - Add role name to database - Add show roles command --- modules/poll.py | 135 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 102 insertions(+), 33 deletions(-) diff --git a/modules/poll.py b/modules/poll.py index be18166..21db24d 100644 --- a/modules/poll.py +++ b/modules/poll.py @@ -3,8 +3,9 @@ import sqlite3 import re -from modules.common import get_hex_colour, selectReactionEmoji, CURR_DIR +from modules.common import get_hex_colour, selectReactionEmoji from modules.emoji_list import _EMOJIS +from constants import DB_F _POLL_PREFIX = "!c poll " @@ -24,6 +25,14 @@ async def Poll(message): await startBasicPoll(message) elif content == "end": await endBasicPoll(message) + elif content == "roles": + if message.author.guild_permissions.administrator: + await showRoles(message) + else: + emb = discord.Embed() + emb.description = "You do not have the permissions to use this." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) elif content == "new" and arg == "-r": if message.author.guild_permissions.administrator: await startRolePoll(message) @@ -40,6 +49,14 @@ async def Poll(message): emb.description = "You do not have the permissions to use this." emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) + elif content == "delroles": + if message.author.guild_permissions.administrator: + await delRoles(message) + else: + emb = discord.Embed() + emb.description = "You do not have the permissions to use this." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) else: await sendHelp(message) # elif content == "edit": #TODO add an edit command? @@ -47,7 +64,7 @@ async def Poll(message): async def sendHelp(message): emb = discord.Embed() - emb.title = "How to use polls" + emb.title = "How to use polls 1/2" emb.color = get_hex_colour() txt1 = "Command usage: ```!c poll [new|end|help]```\n\ **Adding a new basic poll:**\n\ @@ -78,7 +95,8 @@ async def sendHelp(message): Note, that if you change anything in the role you do not need to add or edit the role in the bot's database unless you delete and create a new role in the server settings.\ If you wish to delete a role, use\n\ ```!c poll delrole [role], [role], ...```\n\ - Note that you can delete all roles with the keyword 'all', as in\n\ + where [role] is a role ID or a role mention.\n\ + Note that you can also delete all roles with the keyword 'all', as in\n\ ```!c poll delrole all```" dm_channel = message.author.dm_channel if dm_channel == None: @@ -87,6 +105,7 @@ async def sendHelp(message): emb.description = txt1 await dm_channel.send(embed=emb) emb.description = txt2 + emb.title = "How to use polls 2/2" await dm_channel.send(embed=emb) @@ -94,8 +113,7 @@ async def startBasicPoll(message): # Command structure: # !c poll new [title]; [option1]; [option2]; ... ; [option20] - db_file = CURR_DIR + "\\databases.db" - with sqlite3.connect(db_file) as conn: + with sqlite3.connect(DB_F) as conn: c = conn.cursor() prefix = _POLL_PREFIX + "new " @@ -114,9 +132,7 @@ async def startBasicPoll(message): emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) elif len(args) <= 20: - poll_txt = ( - "React with the emojis listed below to vote on this poll!\n\n**Options:**\n" - ) + poll_txt = "React with the emojis listed below to vote on this poll!\n\n**Options:**\n" emoji_list = selectReactionEmoji(len(args), indexes=True) i = 0 for option in args: @@ -227,8 +243,7 @@ async def endBasicPoll(message): # TODO Consolidate RolePoll and BasicPoll ending under this function - db_file = CURR_DIR + "\\databases.db" - with sqlite3.connect(db_file) as conn: + with sqlite3.connect(DB_F) as conn: c = conn.cursor() prefix = _POLL_PREFIX + "end " @@ -309,15 +324,20 @@ async def recordRoles(message): await message.channel.send(embed=emb) return - db_file = CURR_DIR + "\\databases.db" - with sqlite3.connect(db_file) as conn: + with sqlite3.connect(DB_F) as conn: c = conn.cursor() - c.execute(f"SELECT Role_ID FROM RolesMaxVotes WHERE Guild_ID={message.guild.id}") + c.execute( + f"SELECT Role_ID FROM RolesMaxVotes WHERE Guild_ID={message.guild.id}" + ) RolesInDB = c.fetchall() added = {} updated = {} + roles = message.guild.roles + roles_dic = {} + for r in roles: + roles_dic[r.id] = r.name for arg in args: try: @@ -348,15 +368,15 @@ async def recordRoles(message): roleT = (role_int,) if roleT in RolesInDB: c.execute( - "UPDATE RolesMaxVotes SET MaxVotes=? WHERE Role_ID=?", - (amount, role_int), + "UPDATE RolesMaxVotes SET MaxVotes=?, Role_name=? WHERE Role_ID=?", + (amount, roles_dic[role_int], role_int), ) updated[role_int] = amount else: try: c.execute( - "INSERT INTO RolesMaxVotes VALUES (?,?,?)", - (role_int, message.guild.id, amount), + "INSERT INTO RolesMaxVotes VALUES (?,?,?,?)", + (role_int, roles_dic[role_int], message.guild.id, amount), ) except sqlite3.IntegrityError: emb.description = "Error adding roles to database. Aborting." @@ -367,30 +387,53 @@ async def recordRoles(message): txt1 = "**Following roles & vote amounts were set:**\n" txt2 = "**Following roles & vote amounts were updated:**\n" comb = "" - roles = await message.guild.fetch_roles() if len(added) > 0: - for role in roles: - if role.id in added: - # TODO Add SyntaxError check for illegal Unicode emojis - txt1 += f"'{role.name}' : {added[role.id]}\n" + for role in added.items(): + txt1 += f"{roles_dic[role[0]]} : {role[1]}\n" comb += txt1 if len(updated) > 0: - for role in roles: - if role.id in updated: - txt2 += f"'{role.name}' : {updated[role.id]}\n" + for role in updated.items(): + txt2 += f"{roles_dic[role[0]]} : {role[1]}\n" if len(comb) > 0: comb += f"\n{txt2}" else: comb += txt2 # TODO Add checks for message length + conn.commit() emb.description = comb emb.colour = get_hex_colour() await message.channel.send(embed=emb) +async def showRoles(message): + # Command format + # !c poll roles + + emb = discord.Embed() + + with sqlite3.connect(DB_F) as conn: + c = conn.cursor() + c.execute( + f"SELECT Role_name, MaxVotes FROM RolesMaxVotes WHERE Guild_ID={message.guild.id}" + ) + onRecord = c.fetchall() + if len(onRecord) == 0: + txt = "You do not have any roles on database for this server." + else: + txt = "" + for role in onRecord: + txt += f"{role[0]} : {role[1]}\n" + + # TODO Add text lenght check + emb.description = txt + emb.title = "Following roles & vote amounts are in the database:" + emb.color = get_hex_colour() + await message.channel.send(embed=emb) + + async def delRoles(message): # Command format # !c poll delroles [role],[role], ... @@ -398,25 +441,51 @@ async def delRoles(message): emb = discord.Embed() args = message.content[len(prefix) :].split(",") - if args == 0: - emb.description = ( - "You did not give any arguments. Use '!c poll help' for the correct syntax." - ) + if args[0].strip() == "": + emb.description = "**You did not give any arguments. Use '!c poll help' for the correct syntax.**" emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) return - db_file = CURR_DIR + "\\databases.db" - with sqlite3.connect(db_file) as conn: + i = 0 + with sqlite3.connect(DB_F) as conn: c = conn.cursor() + if args[0].strip() == "all": + c.execute(f"DELETE FROM RolesMaxVotes WHERE Guild_ID={message.guild.id}") + i = -1 + else: + for arg in args: + match = RoleRE.match(arg) + if match: + role_id = match.group(1).strip() + else: + role_id = arg.strip() + try: + role_int = int(role_id) + except ValueError: + emb.description = "Invalid arguments, role must be an ID integer or a mention. \nAlso make sure you have commas in the right place." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + return + c.execute( + "DELETE FROM RolesMaxVotes WHERE Role_ID=? AND Guild_ID=?", + (role_int, message.guild.id), + ) + i += 1 + conn.commit() + if i == -1: + i = "all" + emb.description = f"Deleted {i} roles from database." + emb.color = get_hex_colour(cora_eye=True) + await message.channel.send(embed=emb) + async def startRolePoll(message): # Command structure: # !c poll new -r [title]; [option1]; [option2]; ... ; [option20] - db_file = CURR_DIR + "\\databases.db" - with sqlite3.connect(db_file) as conn: + with sqlite3.connect(DB_F) as conn: c = conn.cursor() g_id = message.guild.id c.execute(f"SELECT * FROM RolesMaxVotes WHERE Guild_ID={g_id}") From 3aaf21b7f1bc2ae6d29416d1fcbed7fbe6dbe174 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Fri, 9 Apr 2021 01:00:34 +0300 Subject: [PATCH 15/20] Add vote command --- main.py | 5 +- modules/vote.py | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 modules/vote.py diff --git a/main.py b/main.py index d349f69..30a6726 100644 --- a/main.py +++ b/main.py @@ -3,7 +3,7 @@ # import tweepy -# import scripts +# scripts, functions & constants from constants import * from modules import common from modules import quote @@ -15,6 +15,7 @@ from modules import vaccine from modules import tirsk from modules import poll +from modules import vote # TODO Commit viestin lähetystä ennen @@ -83,6 +84,8 @@ async def on_message(message): await tirsk.tirskCount(message) elif cmd == "poll": await poll.Poll(message) + elif cmd == "vote": + await vote.vote(message) else: await message.channel.send("What was that?") diff --git a/modules/vote.py b/modules/vote.py new file mode 100644 index 0000000..4564d30 --- /dev/null +++ b/modules/vote.py @@ -0,0 +1,243 @@ +import discord +import sqlite3 +import logging + +from modules.common import get_hex_colour +from constants import DB_F + + +async def vote(message): + # Command structure + # !c vote [Poll ID] [option number]:[amount of votes], [option number]:[amount of votes], ... + + try: + arg = message.content.split(" ")[2] + except IndexError: + arg = "" + + dm_channel = message.author.dm_channel + if dm_channel == None: + dm_channel = await message.author.create_dm() + emb = discord.Embed() + + if arg == "": + await voteHelp(message) + elif arg.strip() == "help": + await voteHelp(message) + elif arg.strip() == "delete": + await delVotes(message) + else: + try: + poll_id = int(arg.strip().lstrip("[").rstrip("]")) + except ValueError: + voteErrorHandler(message, dm_channel, 1) # invalid Poll ID + return + + with sqlite3.connect(DB_F) as conn: + prefix = "!c vote " + arg + args = message.content[len(prefix) :].split(",") + c = conn.cursor() + + c.execute( + "SELECT * FROM RolePolls WHERE Poll_ID=? AND Guild_ID=?", + (poll_id, message.guild.id), + ) + poll = c.fetchall() + if len(poll) == 0: + voteErrorHandler(message, dm_channel, 2) # no poll exists with poll ID + return + else: + c.execute( + f"SELECT * FROM RolesMaxVotes WHERE Guild_ID={message.guild.id}" + ) + VoteRoles = c.fetchall() + MemberRoles = message.author.roles + + roleIDList = [] + foundRoles = [] + for r in MemberRoles: + roleIDList.append(r.id) + + for role in VoteRoles: + if role[0] in roleIDList: + foundRoles.append(role) + if len(foundRoles) == 0: + voteErrorHandler( + message, dm_channel, 3, poll_id=poll_id + ) # user does not have roles that can vote + return + else: + maxvoteint = 0 + for role in foundRoles: + if role[3] > maxvoteint: + maxvoteint = role[3] + if maxvoteint == 0: + voteErrorHandler(message, dm_channel, 4) # user has zero votes + return + c.execute( + "SELECT * FROM RolePolls_Votes WHERE Voter_ID=? AND Poll_ID=?", + (message.author.id, poll_id), + ) + previousVotes = c.fetchall() + if len(previousVotes) > 0: + prevVotesInt = 0 + for vote in previousVotes: + vote_amount = sum(vote[3][:-1].split(";")) + prevVotesInt += vote_amount + if prevVotesInt == maxvoteint: + voteErrorHandler( + message, dm_channel, 8, poll_id=poll_id + ) # user has already voted maximum amount + return + else: + maxvoteint = prevVotesInt + + optionsCount = len(poll.split(";")) + votes = [] + totalVotes = 0 + for i in range(optionsCount - 1): + votes.append(0) + for arg in args: + if arg.strip() == "": + continue + options = arg.split(":") + try: + option_no = int(options[0].strip().lstrip("[").rstrip("]")) + vote_amount = int(options[1].strip().lstrip("[").rstrip("]")) + except ValueError: + voteErrorHandler(message, dm_channel, 6) + return + if option_no == 0 or option_no < 0: + voteErrorHandler(message, dm_channel, 6) + return + elif option_no > optionsCount: + voteErrorHandler(message, dm_channel, 6) + return + votes[option_no - 1] = vote_amount + totalVotes += 1 + + if totalVotes > maxvoteint: + voteErrorHandler(message, dm_channel, 5, maxvotes=maxvoteint) + vote_str = "" + for vote in votes: + vote_str += f"{vote};" + + c.execute("SELECT Vote_ID FROM RolePolls_Votes ORDER BY Vote_ID DESC") + maxid = c.fetchone() + i = 0 + success = 0 + while i < 5: + try: + c.execute( + "INSER INTO RolePolls_Votes VALUES (?,?,?,?)", + (maxid + 1, poll_id, message.author.id, vote_str), + ) + success = 1 + break + except sqlite3.IntegrityError: + maxid += 1 + i += 1 + continue + if success != 1: + voteErrorHandler( + message, dm_channel, 7 + ) # unable to record the vote to database + logging.error( + "Sqlite IntegrityError during voting. Vote recording was not succesful after 5 attempts." + ) + return + conn.commit() + pollOptions = poll[4][:-1].split(";") + txt = "" + i = 0 + for v in votes: + txt += f"{pollOptions[i]}: {v}" + i += 1 + emb.description = txt + emb.title = "Your votes were:" + emb.set_footer( + text=f"If these are incorrect, you can use '!c vote delete {poll_id}' to delete your vote(s) and try again." + ) + + +async def voteErrorHandler(message, dm_channel, err_type, poll_id=0, maxvotes=0): + emb = discord.Embed() + if err_type == 1: + emb.description = f"**Invalid poll ID. Please give the ID as an integer.**\ + Your command was: ```{message.content}```" + elif err_type == 2: + emb.description = f"**No poll found with given poll ID on '{message.guild.name}'**\ + Your command was: ```{message.content}```" + elif err_type == 3: + emb.description = f"**You do not have a role that can vote in the poll with ID {poll_id} in '{message.guild.name}'**" + elif err_type == 4: + emb.description = f"**You cannot vote in the poll with ID {poll_id} in '{message.guild.name}'**" + elif err_type == 5: + emb.description = f"**You gave too many votes. You can still give a maximum of {maxvotes}.\n\ + Your command was:** ```{message.content}```" + elif err_type == 6: + emb.description = f"**Invalid option number or vote amount. Please give them as an integer and make sure they are within the poll options.**" + elif err_type == 7: + emb.description = f"**Unable to record the vote. Please try again.**\n\ + Your command was: ```{message.content}```" + elif err_type == 8: + emb.description = f"**You have already given maximum amount of votes into the poll {poll_id}.**" + else: + emb.description = "Something went wrong in voting." + + emb.color = get_hex_colour(error=True) + await dm_channel.send(embed=emb) + await message.delete() + + +async def voteHelp(message): + emb = discord.Embed() + emb.color = get_hex_colour() + emb.title = "Voting in polls" + emb.description = "You can vote in the _basic polls_ by reacting to the corresponding emote.\n\ + The vote command can be used in _advanced polls_ (indicated by the poll having numbers before the options instead of emotes).\ + **Vote command usage:**\n\ + ```!c vote [Poll ID] [option number]:[amount of votes], [option number]:[amount of votes], ...```\n\ + _NOTE!_ Poll ID can be found in the footer under the poll. You do not need to type the brackets.\n\ + You also do not need to type the options that you are not voting for, only those you _are_ voting for.\n\ + \n\ + **Deleting your votes**\n\ + If your votes were incorrect or you want to change them, you can use \n\ + ```!c vote delete [Poll ID]```\n\ + to delete all your votes from that poll and try again." + + dm_channel = message.author.dm_channel + if dm_channel == None: + dm_channel = await message.author.create_dm() + + await dm_channel.send(embed=emb) + await message.delete() + + +async def delVotes(message): + # Command structure + # !c vote delete [Poll ID] + + emb = discord.Embed() + dm_channel = message.author.dm_channel + if dm_channel == None: + dm_channel = await message.author.create_dm() + arg = message.content.split(" ")[3] + try: + poll_id = int(arg.strip().lstrip("[").rstrip("]")) + except ValueError: + voteErrorHandler(message, dm_channel, 1) # invalid Poll ID + return + + with sqlite3.connect(DB_F) as conn: + c = conn.cursor() + + c.execute( + "DELETE FROM RolePolls_Votes WHERE Poll_ID=? AND Voter_ID=?", + (poll_id, message.author.id), + ) + conn.commit() + emb.title = f"Your votes were deleted from poll with ID {poll_id}" + emb.color = get_hex_colour() + await dm_channel.send(embed=emb) + await message.delete() From e7fb6ad021eb00c7279b86d2a1e1b60023e37479 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Fri, 9 Apr 2021 01:01:13 +0300 Subject: [PATCH 16/20] Move MAX_OPTIONS to a constant, move vote command to another file --- modules/poll.py | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/modules/poll.py b/modules/poll.py index 21db24d..a19f8ed 100644 --- a/modules/poll.py +++ b/modules/poll.py @@ -8,6 +8,7 @@ from constants import DB_F _POLL_PREFIX = "!c poll " +MAX_OPTIONS = 20 RoleRE = re.compile(r"^.*<@&(\d+)>") @@ -513,13 +514,13 @@ async def startRolePoll(message): emb.description = "You gave less than 2 options or you are missing separators. For correct use of the command, use ```!c poll help```" emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) - elif len(args) <= 20: + elif len(args) <= MAX_OPTIONS: poll_txt = "Use '!c vote' -command to vote in this poll! See '!c vote help' for more.\n\n**Options:**\n" option_str = "" - i = 0 + i = 1 for option in args: option_str += option.strip() + ";" - poll_txt += f"**{str(i+1)}**: {option.strip()}\n" + poll_txt += f"**{str(i)}**: {option.strip()}\n" i += 1 if len(poll_txt) >= 2048: @@ -562,38 +563,18 @@ async def startRolePoll(message): ), ) conn.commit() - logging.info("Added poll {} into RolePolls database table.".format(msg.id)) + logging.info(f"Added poll {msg.id} into RolePolls database table.") await dm_channel.send(txt) await dm_channel.send(txt2) await message.delete() else: - emb.description = "Exceeded maximum option amount of 20 options for polls!" + emb.description = ( + f"Exceeded maximum option amount of {MAX_OPTIONS} options for polls!" + ) emb.color = get_hex_colour(error=True) await message.channel.send(embed=emb) async def rolePollEndHelper(): pass - - -async def vote(message): - pass - - -async def voteHelp(message): - emb = discord.Embed() - emb.color = get_hex_colour() - emb.title = "Voting in polls" - emb.description = "You can vote in the _basic polls_ by reacting to the corresponding emote.\n\ - The vote command can be used in _advanced polls_ (indicated by the poll having numbers before the options instead of emotes).\ - **Vote command usage:**\n\ - ```!c vote [Poll ID] [option number]:[amount of votes], [option number]:[amount of votes], ...```\n\ - _NOTE!_ Poll ID can be found in the footer under the poll. You do not need to type the brackets." - - dm_channel = message.author.dm_channel - if dm_channel == None: - dm_channel = await message.author.create_dm() - - await dm_channel.send(embed=emb) - await message.delete() \ No newline at end of file From c67fb00fa55070ad49422fcec8cd8deefcf5a855 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Fri, 9 Apr 2021 01:01:34 +0300 Subject: [PATCH 17/20] Change table structure for vote table --- modules/common.py | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/modules/common.py b/modules/common.py index dd4a3f2..b7490ed 100644 --- a/modules/common.py +++ b/modules/common.py @@ -94,26 +94,7 @@ def initializeDatabase(): Vote_ID INT UNIQUE, Poll_ID INT, Voter_ID INT, - option1 INT, - option2 INT, - option3 INT, - option4 INT, - option5 INT, - option6 INT, - option7 INT, - option8 INT, - option9 INT, - option10 INT, - option11 INT, - option12 INT, - option13 INT, - option14 INT, - option15 INT, - option16 INT, - option17 INT, - option18 INT, - option19 INT, - option20 INT, + Votes TXT, PRIMARY KEY (Vote_ID) FOREIGN KEY (Poll_ID) REFERENCES RolePolls(Poll_ID) ON DELETE CASCADE From 32543935331afc3c441ad523da19c2c037675c8c Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Fri, 9 Apr 2021 01:39:23 +0300 Subject: [PATCH 18/20] Fix errors in vote command - Also add emoji to error messages --- modules/vote.py | 78 +++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/modules/vote.py b/modules/vote.py index 4564d30..c0b20db 100644 --- a/modules/vote.py +++ b/modules/vote.py @@ -30,7 +30,7 @@ async def vote(message): try: poll_id = int(arg.strip().lstrip("[").rstrip("]")) except ValueError: - voteErrorHandler(message, dm_channel, 1) # invalid Poll ID + await voteErrorHandler(message, dm_channel, 1) # invalid Poll ID return with sqlite3.connect(DB_F) as conn: @@ -44,7 +44,7 @@ async def vote(message): ) poll = c.fetchall() if len(poll) == 0: - voteErrorHandler(message, dm_channel, 2) # no poll exists with poll ID + await voteErrorHandler(message, dm_channel, 2) # no poll exists with poll ID return else: c.execute( @@ -62,8 +62,8 @@ async def vote(message): if role[0] in roleIDList: foundRoles.append(role) if len(foundRoles) == 0: - voteErrorHandler( - message, dm_channel, 3, poll_id=poll_id + await voteErrorHandler( + message, dm_channel, 3, poll_name=poll[0][5] ) # user does not have roles that can vote return else: @@ -72,7 +72,7 @@ async def vote(message): if role[3] > maxvoteint: maxvoteint = role[3] if maxvoteint == 0: - voteErrorHandler(message, dm_channel, 4) # user has zero votes + await voteErrorHandler(message, dm_channel, 4) # user has zero votes return c.execute( "SELECT * FROM RolePolls_Votes WHERE Voter_ID=? AND Poll_ID=?", @@ -82,17 +82,17 @@ async def vote(message): if len(previousVotes) > 0: prevVotesInt = 0 for vote in previousVotes: - vote_amount = sum(vote[3][:-1].split(";")) - prevVotesInt += vote_amount + vote_amount = vote[3][:-1].split(";") + for x in vote_amount: + prevVotesInt += int(x) if prevVotesInt == maxvoteint: - voteErrorHandler( - message, dm_channel, 8, poll_id=poll_id + await voteErrorHandler( + message, dm_channel, 8, poll_name=poll[0][5] ) # user has already voted maximum amount return else: maxvoteint = prevVotesInt - - optionsCount = len(poll.split(";")) + optionsCount = len(poll[0][4].split(";")) votes = [] totalVotes = 0 for i in range(optionsCount - 1): @@ -104,32 +104,37 @@ async def vote(message): try: option_no = int(options[0].strip().lstrip("[").rstrip("]")) vote_amount = int(options[1].strip().lstrip("[").rstrip("]")) - except ValueError: - voteErrorHandler(message, dm_channel, 6) + except Exception: + await voteErrorHandler(message, dm_channel, 6) return if option_no == 0 or option_no < 0: - voteErrorHandler(message, dm_channel, 6) + await voteErrorHandler(message, dm_channel, 6) return elif option_no > optionsCount: - voteErrorHandler(message, dm_channel, 6) + await voteErrorHandler(message, dm_channel, 6) return votes[option_no - 1] = vote_amount - totalVotes += 1 - + totalVotes += vote_amount + if totalVotes > maxvoteint: - voteErrorHandler(message, dm_channel, 5, maxvotes=maxvoteint) + await voteErrorHandler(message, dm_channel, 5, maxvotes=maxvoteint) + return vote_str = "" for vote in votes: vote_str += f"{vote};" c.execute("SELECT Vote_ID FROM RolePolls_Votes ORDER BY Vote_ID DESC") maxid = c.fetchone() + if maxid == None: + maxid = 1 + else: + maxid = maxid[0] i = 0 success = 0 while i < 5: try: c.execute( - "INSER INTO RolePolls_Votes VALUES (?,?,?,?)", + "INSERT INTO RolePolls_Votes VALUES (?,?,?,?)", (maxid + 1, poll_id, message.author.id, vote_str), ) success = 1 @@ -139,7 +144,7 @@ async def vote(message): i += 1 continue if success != 1: - voteErrorHandler( + await voteErrorHandler( message, dm_channel, 7 ) # unable to record the vote to database logging.error( @@ -147,41 +152,44 @@ async def vote(message): ) return conn.commit() - pollOptions = poll[4][:-1].split(";") + pollOptions = poll[0][4][:-1].split(";") txt = "" i = 0 for v in votes: - txt += f"{pollOptions[i]}: {v}" + txt += f"**{pollOptions[i]}**: {v}\n" i += 1 emb.description = txt - emb.title = "Your votes were:" + emb.title = f"Your votes for '{poll[0][5]}' were:" emb.set_footer( text=f"If these are incorrect, you can use '!c vote delete {poll_id}' to delete your vote(s) and try again." ) + emb.color = get_hex_colour(cora_eye=True) + await dm_channel.send(embed=emb) + await message.delete() -async def voteErrorHandler(message, dm_channel, err_type, poll_id=0, maxvotes=0): +async def voteErrorHandler(message, dm_channel, err_type, poll_name="", maxvotes=0): emb = discord.Embed() if err_type == 1: - emb.description = f"**Invalid poll ID. Please give the ID as an integer.**\ + emb.description = f"\N{no entry} **Invalid poll ID. Please give the ID as an integer.**\ Your command was: ```{message.content}```" elif err_type == 2: - emb.description = f"**No poll found with given poll ID on '{message.guild.name}'**\ + emb.description = f"\N{no entry} **No poll found with given poll ID on '{message.guild.name}'**\ Your command was: ```{message.content}```" elif err_type == 3: - emb.description = f"**You do not have a role that can vote in the poll with ID {poll_id} in '{message.guild.name}'**" + emb.description = f"\N{no entry} **You do not have a role that can vote in the poll '{poll_name}' in '{message.guild.name}'**" elif err_type == 4: - emb.description = f"**You cannot vote in the poll with ID {poll_id} in '{message.guild.name}'**" + emb.description = f"\N{no entry} **You cannot vote in the poll with ID '{poll_name}' in '{message.guild.name}'**" elif err_type == 5: - emb.description = f"**You gave too many votes. You can still give a maximum of {maxvotes}.\n\ + emb.description = f"\N{no entry} **You gave too many votes for poll '{poll_name}'. You can still give a maximum of {maxvotes}.\n\ Your command was:** ```{message.content}```" elif err_type == 6: - emb.description = f"**Invalid option number or vote amount. Please give them as an integer and make sure they are within the poll options.**" + emb.description = f"\N{no entry} **Invalid option number or vote amount. Please give them as an integer and make sure they are within the poll options.**" elif err_type == 7: - emb.description = f"**Unable to record the vote. Please try again.**\n\ + emb.description = f"\N{no entry} **Unable to record the vote. Please try again.**\n\ Your command was: ```{message.content}```" elif err_type == 8: - emb.description = f"**You have already given maximum amount of votes into the poll {poll_id}.**" + emb.description = f"\N{no entry} **You have already given maximum amount of votes into the poll '{poll_name}'.**" else: emb.description = "Something went wrong in voting." @@ -224,9 +232,9 @@ async def delVotes(message): dm_channel = await message.author.create_dm() arg = message.content.split(" ")[3] try: - poll_id = int(arg.strip().lstrip("[").rstrip("]")) + poll_id = int(arg.strip().lstrip("[").rstrip("'").rstrip("]")) except ValueError: - voteErrorHandler(message, dm_channel, 1) # invalid Poll ID + await voteErrorHandler(message, dm_channel, 1) # invalid Poll ID return with sqlite3.connect(DB_F) as conn: @@ -238,6 +246,6 @@ async def delVotes(message): ) conn.commit() emb.title = f"Your votes were deleted from poll with ID {poll_id}" - emb.color = get_hex_colour() + emb.color = get_hex_colour(cora_eye=True) await dm_channel.send(embed=emb) await message.delete() From ec80887360ecc5f72107f74dfa61f20ff9ff96a6 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Fri, 9 Apr 2021 02:18:21 +0300 Subject: [PATCH 19/20] Implement role poll ending --- modules/poll.py | 130 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 116 insertions(+), 14 deletions(-) diff --git a/modules/poll.py b/modules/poll.py index a19f8ed..2bab9e2 100644 --- a/modules/poll.py +++ b/modules/poll.py @@ -25,7 +25,7 @@ async def Poll(message): elif content == "new" and arg != "-r": await startBasicPoll(message) elif content == "end": - await endBasicPoll(message) + await endPolls(message) elif content == "roles": if message.author.guild_permissions.administrator: await showRoles(message) @@ -197,7 +197,7 @@ async def startBasicPoll(message): await message.channel.send(embed=emb) -async def pollEndHelper(poll, message): +async def BasicPollEndHelper(poll, message): emb = discord.Embed() emb.color = get_hex_colour() # Poll_ID INT UNIQUE, 0 @@ -238,7 +238,10 @@ async def pollEndHelper(poll, message): return emb -async def endBasicPoll(message): +# ######################################################################################################## # + + +async def endPolls(message): # Command structure: # !c poll end [poll_ID] @@ -249,6 +252,7 @@ async def endBasicPoll(message): prefix = _POLL_PREFIX + "end " emb = discord.Embed() + success = 0 if len(message.content.split(" ")) == 3: c.execute( @@ -257,22 +261,33 @@ async def endBasicPoll(message): ) polls = c.fetchall() if len(polls) == 0: - emb.description = "There are no polls running that have been initiated by you on this channel." - emb.color = get_hex_colour(error=True) - await message.channel.send(embed=emb) + c.execute("SELECT * FROM RolePolls WHERE Author_ID=? AND Ch_ID=?", (message.author.id, message.channel.id)) + poll = c.fetchall() + if len(poll) == 0: + emb.description = "There are no polls running that have been initiated by you on this channel." + emb.color = get_hex_colour(error=True) + await message.channel.send(embed=emb) + else: + success = await rolePollEndHelper(message, c, conn, polls=poll) else: for poll in polls: - emb = await pollEndHelper(poll, message) + emb = await BasicPollEndHelper(poll, message) await message.channel.send(embed=emb) c.execute( "DELETE FROM BasicPolls WHERE Author_ID=? AND Ch_ID=?", (message.author.id, message.channel.id), ) + # TODO Error handling for basic poll end helper conn.commit() logging.info( f"{len(polls)} poll(s) by {message.author.name} succesfully ended in {message.channel.name}" ) + success = 1 + c.execute("SELECT * FROM RolePolls WHERE Author_ID=? AND Ch_ID=?", (message.author.id, message.channel.id)) + poll = c.fetchall() + if len(poll) != 0: + success = await rolePollEndHelper(message, c, conn, polls=poll) else: try: arg = int(message.content.split(" ")[3]) @@ -290,11 +305,16 @@ async def endBasicPoll(message): ) poll = c.fetchall() if len(poll) == 0: - emb.color = get_hex_colour(error=True) - emb.description = f"Unable to find poll with ID '{arg}'" - await message.channel.send(embed=emb) + c.execute("SELECT * FROM RolePolls WHERE Author_ID=? AND Ch_ID=? AND Poll_ID=?") + poll = c.fetchall() + if len(poll) == 0: + emb.color = get_hex_colour(error=True) + emb.description = f"Unable to find poll with ID '{arg}'.\nPlease check that you gave the right ID and you are on the same channel as the poll." + await message.channel.send(embed=emb) + else: + success = await rolePollEndHelper(message, c, conn, poll=poll) else: - emb = await pollEndHelper(poll[0], message) + emb = await BasicPollEndHelper(poll[0], message) await message.channel.send(embed=emb) c.execute( "DELETE FROM BasicPolls WHERE Author_ID=? AND Ch_ID=? AND Poll_ID=?", @@ -304,7 +324,16 @@ async def endBasicPoll(message): logging.info( f"Poll by {message.author.name} succesfully ended in {message.channel.name}" ) - await message.delete() + success = 1 + c.execute("SELECT * FROM RolePolls WHERE Author_ID=? AND Ch_ID=?", (message.author.id, message.channel.id)) + poll = c.fetchall() + if len(poll) != 0: + success = await rolePollEndHelper(message, c, conn, polls=poll) + if success == 1: + try: + await message.delete() + except Exception as e: + logging.exception("Poll ending command message deletion failed.") # ######################################################################################################## # @@ -576,5 +605,78 @@ async def startRolePoll(message): await message.channel.send(embed=emb) -async def rolePollEndHelper(): - pass +async def rolePollEndHelper(message, c, conn, poll=None, polls=None): + emb = discord.Embed() + if poll != None: + poll_id = poll[0][0] + poll_options = poll[0][4][:-1].split(";") + option_amount = len(poll_options) + poll_name = poll[0][5] + + c.execute(f"SELECT * FROM RolePolls_Votes WHERE Poll_ID={poll_id}") + votes = c.fetchall() + if len(votes) == 0: + emb.title = f"No votes for '{poll_name}'." + emb.color = get_hex_colour(cora_blonde=True) + await message.channel.send(embed=emb) + return 1 + vote_sums = [] + for i in range(option_amount): + vote_sums.append(0) + for vote in votes: + vote_str = vote[3][:-1].split(";") + i = 0 + for option in vote_str: + vote_sums[i] += int(option) + i += 1 + + i = 0 + txt = "" + for option in vote_sums: + txt += f"**{poll_options[i]}**: {option}\n" + i += 1 + c.execute(f"DELETE FROM RolePolls WHERE Poll_ID={poll_id}") + conn.commit() + emb.description = txt + emb.title = f"Results for '{poll_name}'" + emb.color = get_hex_colour(cora_eye=True) + await message.channel.send(embed=emb) + return 1 + + elif polls != None: + for poll in polls: + poll_id = poll[0] + poll_options = poll[4][:-1].split(";") + option_amount = len(poll_options) + poll_name = poll[5] + + c.execute(f"SELECT * FROM RolePolls_Votes WHERE Poll_ID={poll_id}") + votes = c.fetchall() + if len(votes) == 0: + emb.title = f"No votes for '{poll_name}'." + emb.color = get_hex_colour(cora_blonde=True) + await message.channel.send(embed=emb) + return 1 + vote_sums = [] + for i in range(option_amount): + vote_sums.append(0) + for vote in votes: + vote_str = vote[3][:-1].split(";") + i = 0 + for option in vote_str: + vote_sums[i] += int(option) + i += 1 + + i = 0 + txt = "" + for option in vote_sums: + txt += f"**{poll_options[i]}**: {option}\n" + i += 1 + c.execute(f"DELETE FROM RolePolls WHERE Poll_ID={poll_id}") + conn.commit() + emb.description = txt + emb.title = f"Results for '{poll_name}'" + emb.color = get_hex_colour(cora_eye=True) + await message.channel.send(embed=emb) + return 1 + return 0 From 9e8d00e58b2d675b244eead062eb3709eba62271 Mon Sep 17 00:00:00 2001 From: Appelsiini1 <37345715+Appelsiini1@users.noreply.github.com> Date: Fri, 9 Apr 2021 02:23:13 +0300 Subject: [PATCH 20/20] Add version --- main.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.py b/main.py index 30a6726..f25a3de 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,8 @@ +# CoraBot +# V1.10.0 +# Copyright 2021 (c) Appelsiini1 + + import discord import logging