From e3b489633feec04f1deef5765fb5ab0832cb49d0 Mon Sep 17 00:00:00 2001 From: Jason <34526187+GuyWhoCode@users.noreply.github.com> Date: Thu, 7 Jul 2022 19:54:54 -0700 Subject: [PATCH 01/10] Small fixes to help debug Selenium issue --- command_handling/submission_handler.py | 2 +- main.py | 32 +++++++++++--------------- messages/channel_config_view.py | 14 ----------- submission_handling/selenium.py | 29 +++++++++++------------ 4 files changed, 28 insertions(+), 49 deletions(-) diff --git a/command_handling/submission_handler.py b/command_handling/submission_handler.py index e4223b1..b362b59 100644 --- a/command_handling/submission_handler.py +++ b/command_handling/submission_handler.py @@ -28,7 +28,7 @@ async def handle_submission( response_message = f"Thanks for uploading, {interaction.user.display_name}! Recieved {language} file: {attachment.filename}." response_message += "\n\nPlease wait while we check your submission..." - await interaction.followup.send(response_message) + await interaction.response.send_message(response_message) return await submitAttachmentToLeetcode(attachment, language) """ diff --git a/main.py b/main.py index 51debf0..9c0a945 100644 --- a/main.py +++ b/main.py @@ -180,7 +180,7 @@ async def on_guild_join(guild: Guild): @tree.command(description="Say hello.") @app_commands.checks.cooldown(1, 1) async def hello(interaction: discord.Interaction): - check_submission_channel() + await check_submission_channel() entry = random.randrange(0, len(greeting) - 1) await interaction.response.send_message( f"{greeting[entry]} {interaction.user.mention}" @@ -193,7 +193,7 @@ async def hello(interaction: discord.Interaction): @tree.command(description="See today's problem.") @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) async def current_challenge(interaction: discord.Interaction): - check_submission_channel() + await check_submission_channel() embeds = getProblemEmbeds(store["cotd"]) await interaction.response.send_message( @@ -230,8 +230,7 @@ async def submit( "Elixir", ], ): - check_submission_channel() - await interaction.response.defer() + await check_submission_channel() submission = await handle_submission(interaction, attachment, language) response_message = f"Thanks for uploading, {interaction.user.display_name}! Received {language} file: {attachment.filename}." @@ -291,7 +290,7 @@ async def submit( @tree.command(description="Provides the Top given value members.") @app_commands.describe(value="What number of the top members you want to see") async def top(interaction: discord.Interaction, value: int): - check_submission_channel() + await check_submission_channel() await interaction.response.send_message( await format_rank_list( interaction, ParticipantData.get_instance().get_top(value), value @@ -302,7 +301,7 @@ async def top(interaction: discord.Interaction, value: int): @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="provides the Top 10 members.") async def top10(interaction: discord.Interaction): - check_submission_channel() + await check_submission_channel() await interaction.response.send_message( await format_rank_list( interaction, ParticipantData.get_instance().get_top(10), 10 @@ -313,7 +312,7 @@ async def top10(interaction: discord.Interaction): @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="Provides how many points you have.") async def mypoints(interaction: discord.Interaction): - check_submission_channel() + await check_submission_channel() await interaction.response.send_message( f"You currently have {ParticipantData.get_instance().get_points(interaction.user.id)} point(s)." ) @@ -322,15 +321,13 @@ async def mypoints(interaction: discord.Interaction): @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="Compares you with the first place member.") async def first(interaction: discord.Interaction): - check_submission_channel() - await interaction.response.defer() + await check_submission_channel() await interaction.followup.send(get_first_stats(interaction)) @tree.command(description="Display your personal stats.") async def get_stats(interaction: discord.Interaction): - check_submission_channel() - await interaction.response.defer() + await check_submission_channel() ParticipantData.get_instance().add_participant(interaction.user.id) participant_stats_embed = discord.Embed( @@ -373,7 +370,7 @@ async def supported_commands(interaction: discord.Interaction): @tree.command(description="Enroll yourself in competition reminders.") @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) async def remindme(interaction: discord.Interaction): - check_submission_channel() + await check_submission_channel() if "Broncoder" in [u.name for u in interaction.user.roles]: # Add file? await interaction.response.send_message( @@ -392,7 +389,7 @@ async def remindme(interaction: discord.Interaction): @app_commands.checks.has_role("Broncoder") # add error catch to not crash async def stopreminders(interaction: discord.Interaction): - check_submission_channel() + await check_submission_channel() comp_role = discord.utils.get(interaction.guild.roles, name="Broncoder") await interaction.user.remove_roles(comp_role) await interaction.response.send_message( @@ -547,11 +544,10 @@ async def givepoints(interaction: discord.Interaction, setting:str, point_value: ******************************************************""" -def check_submission_channel(): +async def check_submission_channel(): assert ( - store.__getitem__("submission_channel_id") != 0 - ), "Code submission channel not set" - + store.__getitem__("submission_channel_id") != 0 + ), "Code submission channel not set" @tree.error async def tree_errors( @@ -574,7 +570,7 @@ async def tree_errors( "No code submission channel set. Please notify an admin to fix this." ) - await interaction.followup.send( + await interaction.response.send_message( content=error_message, ephemeral=True, ) diff --git a/messages/channel_config_view.py b/messages/channel_config_view.py index 229fe5c..fa86fdf 100644 --- a/messages/channel_config_view.py +++ b/messages/channel_config_view.py @@ -4,17 +4,6 @@ store = PersistentStore.get_instance() -class InfoButton(discord.ui.Button["ChannelConfigView"]): - def __init__(self): - super().__init__( - style=discord.ButtonStyle.secondary, label="Info", disabled=True - ) - - async def callback(self, interaction: discord.Interaction): - view: ChannelConfigView = self.view - await interaction.response.edit_message(content="Info", view=view) - - class AnnounceButton(discord.ui.Button["ChannelConfigView"]): def __init__(self, channel_id): self.channel_id = channel_id @@ -54,9 +43,6 @@ def __init__(self, channel_id): self.buttons = {} - self.buttons["info"] = InfoButton() - self.add_item(self.buttons["info"]) - self.buttons["announce"] = AnnounceButton(channel_id) self.add_item(self.buttons["announce"]) diff --git a/submission_handling/selenium.py b/submission_handling/selenium.py index 67f9545..8f0a947 100644 --- a/submission_handling/selenium.py +++ b/submission_handling/selenium.py @@ -1,5 +1,5 @@ -from operator import truediv from selenium import webdriver +from selenium.webdriver.chrome.service import Service from selenium.common.exceptions import TimeoutException from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC @@ -32,7 +32,7 @@ options.add_argument("--disable-dev-shm-usage") options.add_argument("--no-sandbox") driver = webdriver.Chrome( - executable_path=os.environ.get("CHROMEDRIVER_PATH"), options=options + service=Service(executable_path=os.environ.get("CHROMEDRIVER_PATH")), options=options ) @@ -65,12 +65,6 @@ async def setup(question): driver.find_element(By.ID, "signin_btn").click() - try: - element_present = EC.presence_of_element_located((By.ID, "profile-app")) - WebDriverWait(driver, timeout).until(element_present) - except TimeoutException: - exit() - driver.get("https://leetcode.com/problems/{}".format(question["titleSlug"])) try: @@ -172,16 +166,19 @@ async def submitCode(code, language="Python3"): await typeCode(code) - driver.find_element(By.XPATH, '//button[@data-cy="submit-code-btn"]').click() + # driver.find_element(By.XPATH, '//button[@data-cy="submit-code-btn"]').click() + driver.find_element(By.XPATH, '//*[@id="app"]/div/div[2]/div[1]/div/div[3]/div/div[3]/div[2]/div/button/span').click() + # Attempt at finding an alternate path to click the button by clicking the inner span within the button + + ''' + BUG: Error seems to be around this region. My assumption is that the submit button is somehow not being clicked. + Commenting out the code segment below containing 'status_present' will throw a TimeoutException-related error saying that a timeout occurred in trying to find the element of 'detail_present' + Commenting out both code segments of 'status_present' and 'detail_present' will causes 'result_url' to throw an error of being unable to find the element in question. + ''' try: - pending_present = EC.presence_of_element_located( - (By.XPATH, "//*[contains(text(), 'Pending')]") - ) + status_present = EC.presence_of_element_located((By.CLASS_NAME, "status__1eAa")) - judging_present = EC.presence_of_element_located( - (By.XPATH, "//*[contains(text(), 'Judging')]") - ) - WebDriverWait(driver, timeout).until(pending_present or judging_present) + WebDriverWait(driver, timeout).until(status_present) except TimeoutException: exit() From f1b14b8a0e4fd3c955d450abeb877b5473e5b0c2 Mon Sep 17 00:00:00 2001 From: Lint Action Date: Fri, 8 Jul 2022 02:55:09 +0000 Subject: [PATCH 02/10] Fix code style issues with Black --- main.py | 5 +++-- submission_handling/selenium.py | 14 +++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index 9c0a945..45e01e5 100644 --- a/main.py +++ b/main.py @@ -546,8 +546,9 @@ async def givepoints(interaction: discord.Interaction, setting:str, point_value: async def check_submission_channel(): assert ( - store.__getitem__("submission_channel_id") != 0 - ), "Code submission channel not set" + store.__getitem__("submission_channel_id") != 0 + ), "Code submission channel not set" + @tree.error async def tree_errors( diff --git a/submission_handling/selenium.py b/submission_handling/selenium.py index 8f0a947..3dc96e6 100644 --- a/submission_handling/selenium.py +++ b/submission_handling/selenium.py @@ -32,7 +32,8 @@ options.add_argument("--disable-dev-shm-usage") options.add_argument("--no-sandbox") driver = webdriver.Chrome( - service=Service(executable_path=os.environ.get("CHROMEDRIVER_PATH")), options=options + service=Service(executable_path=os.environ.get("CHROMEDRIVER_PATH")), + options=options, ) @@ -167,14 +168,17 @@ async def submitCode(code, language="Python3"): await typeCode(code) # driver.find_element(By.XPATH, '//button[@data-cy="submit-code-btn"]').click() - driver.find_element(By.XPATH, '//*[@id="app"]/div/div[2]/div[1]/div/div[3]/div/div[3]/div[2]/div/button/span').click() + driver.find_element( + By.XPATH, + '//*[@id="app"]/div/div[2]/div[1]/div/div[3]/div/div[3]/div[2]/div/button/span', + ).click() # Attempt at finding an alternate path to click the button by clicking the inner span within the button - - ''' + + """ BUG: Error seems to be around this region. My assumption is that the submit button is somehow not being clicked. Commenting out the code segment below containing 'status_present' will throw a TimeoutException-related error saying that a timeout occurred in trying to find the element of 'detail_present' Commenting out both code segments of 'status_present' and 'detail_present' will causes 'result_url' to throw an error of being unable to find the element in question. - ''' + """ try: status_present = EC.presence_of_element_located((By.CLASS_NAME, "status__1eAa")) From af22dfb2cd4753fe814f20de133caa6721eff7ae Mon Sep 17 00:00:00 2001 From: GuyWhoCode Date: Fri, 8 Jul 2022 21:23:06 -0700 Subject: [PATCH 03/10] Functional Code Submission Channel GH-37 --- main.py | 32 ++++++++++++++++++++------------ submission_handling/selenium.py | 4 +++- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/main.py b/main.py index 45e01e5..cab2d93 100644 --- a/main.py +++ b/main.py @@ -180,7 +180,7 @@ async def on_guild_join(guild: Guild): @tree.command(description="Say hello.") @app_commands.checks.cooldown(1, 1) async def hello(interaction: discord.Interaction): - await check_submission_channel() + await check_submission_channel(interaction, interaction.channel_id) entry = random.randrange(0, len(greeting) - 1) await interaction.response.send_message( f"{greeting[entry]} {interaction.user.mention}" @@ -193,7 +193,7 @@ async def hello(interaction: discord.Interaction): @tree.command(description="See today's problem.") @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) async def current_challenge(interaction: discord.Interaction): - await check_submission_channel() + await check_submission_channel(interaction, interaction.channel_id) embeds = getProblemEmbeds(store["cotd"]) await interaction.response.send_message( @@ -230,7 +230,7 @@ async def submit( "Elixir", ], ): - await check_submission_channel() + await check_submission_channel(interaction, interaction.channel_id) submission = await handle_submission(interaction, attachment, language) response_message = f"Thanks for uploading, {interaction.user.display_name}! Received {language} file: {attachment.filename}." @@ -290,7 +290,7 @@ async def submit( @tree.command(description="Provides the Top given value members.") @app_commands.describe(value="What number of the top members you want to see") async def top(interaction: discord.Interaction, value: int): - await check_submission_channel() + await check_submission_channel(interaction, interaction.channel_id) await interaction.response.send_message( await format_rank_list( interaction, ParticipantData.get_instance().get_top(value), value @@ -301,7 +301,7 @@ async def top(interaction: discord.Interaction, value: int): @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="provides the Top 10 members.") async def top10(interaction: discord.Interaction): - await check_submission_channel() + await check_submission_channel(interaction, interaction.channel_id) await interaction.response.send_message( await format_rank_list( interaction, ParticipantData.get_instance().get_top(10), 10 @@ -312,7 +312,7 @@ async def top10(interaction: discord.Interaction): @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="Provides how many points you have.") async def mypoints(interaction: discord.Interaction): - await check_submission_channel() + await check_submission_channel(interaction, interaction.channel_id) await interaction.response.send_message( f"You currently have {ParticipantData.get_instance().get_points(interaction.user.id)} point(s)." ) @@ -321,13 +321,13 @@ async def mypoints(interaction: discord.Interaction): @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="Compares you with the first place member.") async def first(interaction: discord.Interaction): - await check_submission_channel() + await check_submission_channel(interaction, interaction.channel_id) await interaction.followup.send(get_first_stats(interaction)) @tree.command(description="Display your personal stats.") async def get_stats(interaction: discord.Interaction): - await check_submission_channel() + await check_submission_channel(interaction, interaction.channel_id) ParticipantData.get_instance().add_participant(interaction.user.id) participant_stats_embed = discord.Embed( @@ -343,7 +343,7 @@ async def get_stats(interaction: discord.Interaction): value=ParticipantData.get_instance().get_badge(interaction.user.id), ) - await interaction.followup.send(embed=participant_stats_embed) + await interaction.response.send_message(embed=participant_stats_embed) """ ---------- UTILITY ---------- """ @@ -354,6 +354,7 @@ async def get_stats(interaction: discord.Interaction): ) @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) async def rules(interaction: discord.Interaction): + await check_submission_channel(interaction, interaction.channel_id) await interaction.response.send_message( f'**Rules**\n---------\n • Please partricipate in good faith. Don\'t cheat! This competition is to help you improve on your leetcode skills and facilitate fun in our server. If you cheat you are defeating the purpose.\n\n • Challenges are posted at {DAILY_ANNOUNCEMENT_TIME.strftime("%I : %M %p")} in the announcement channel.\n\n • Submit solution files either through DM to me or in the submission channel through the /submit command.\n\n • Opt in to reminder pings through the /remindme command and opt out through the /stopreminders command.\n\n\n ***Happy Trotting Broncoder!***' ) @@ -362,6 +363,7 @@ async def rules(interaction: discord.Interaction): @tree.command(description="Provides a list of supported non admin commands.") @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) async def supported_commands(interaction: discord.Interaction): + await check_submission_channel(interaction, interaction.channel_id) await interaction.response.send_message( f"**************************************************\n COMMANDS\n currently supported commands:\n ---------------------------\n FUN\n * hello : Say hello.\n\n ---------------------------\n PROBLEM SUBMISSION\n * current_challenge : See today's problem.\n * submit : Submit your code to be tested and judged.\n\n ---------------------------\n STATS\n * top: Provides the Top given value members.\n * top10: Provides the Top 10 members\n * mypoints: Provides how many points you have.\n * first: Compares you with the first place member.\n * get_stats: Display your personal stats.\n\n ---------------------------\n UTILITY\n * rules: Provides the rules and instructions to use the bot for the competition.\n * supported_commands: Provides a list of supported non admin commands.\n * remindme: Enroll yourself in competition reminders.\n * stopreminders: Remove yourself from the competition reminders.\n\n****************************************************" ) @@ -370,7 +372,7 @@ async def supported_commands(interaction: discord.Interaction): @tree.command(description="Enroll yourself in competition reminders.") @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) async def remindme(interaction: discord.Interaction): - await check_submission_channel() + await check_submission_channel(interaction, interaction.channel_id) if "Broncoder" in [u.name for u in interaction.user.roles]: # Add file? await interaction.response.send_message( @@ -389,7 +391,7 @@ async def remindme(interaction: discord.Interaction): @app_commands.checks.has_role("Broncoder") # add error catch to not crash async def stopreminders(interaction: discord.Interaction): - await check_submission_channel() + await check_submission_channel(interaction, interaction.channel_id) comp_role = discord.utils.get(interaction.guild.roles, name="Broncoder") await interaction.user.remove_roles(comp_role) await interaction.response.send_message( @@ -544,10 +546,16 @@ async def givepoints(interaction: discord.Interaction, setting:str, point_value: ******************************************************""" -async def check_submission_channel(): +async def check_submission_channel(interaction: discord.Interaction, sent_channel: int): assert ( store.__getitem__("submission_channel_id") != 0 ), "Code submission channel not set" + + if sent_channel != store.__getitem__("submission_channel_id"): + await interaction.response.send_message( + content= f"You sent this command in the wrong channel! Please use <#{store.__getitem__('submission_channel_id')}>", + ephemeral=True, + ) @tree.error diff --git a/submission_handling/selenium.py b/submission_handling/selenium.py index 3dc96e6..eca3dc3 100644 --- a/submission_handling/selenium.py +++ b/submission_handling/selenium.py @@ -21,7 +21,8 @@ my_browser_state = BrowserState() options = webdriver.ChromeOptions() -""" + +""" Used for local testing desired_capabilities = DesiredCapabilities.CHROME options.add_experimental_option("excludeSwitches", ["enable-logging"]) driver = webdriver.Chrome(desired_capabilities=desired_capabilities, options=options) @@ -35,6 +36,7 @@ service=Service(executable_path=os.environ.get("CHROMEDRIVER_PATH")), options=options, ) +# Used for Heroku Testing response_dict_base = {"msg": None, "err": False, "details": {}} From 7283463b8cbef71287e88474bdad62931c65b8bc Mon Sep 17 00:00:00 2001 From: Lint Action Date: Sat, 9 Jul 2022 04:23:26 +0000 Subject: [PATCH 04/10] Fix code style issues with Black --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index cab2d93..57dd109 100644 --- a/main.py +++ b/main.py @@ -550,10 +550,10 @@ async def check_submission_channel(interaction: discord.Interaction, sent_channe assert ( store.__getitem__("submission_channel_id") != 0 ), "Code submission channel not set" - + if sent_channel != store.__getitem__("submission_channel_id"): await interaction.response.send_message( - content= f"You sent this command in the wrong channel! Please use <#{store.__getitem__('submission_channel_id')}>", + content=f"You sent this command in the wrong channel! Please use <#{store.__getitem__('submission_channel_id')}>", ephemeral=True, ) From 9c36a13538be2c4ef7eba715a2ac42d4efb22585 Mon Sep 17 00:00:00 2001 From: GuyWhoCode Date: Sun, 10 Jul 2022 15:14:21 -0700 Subject: [PATCH 05/10] Refactored GH-37 --- command_handling/submission_handler.py | 2 +- main.py | 112 +++++++++++++++++-------- submission_handling/selenium.py | 31 ++++--- 3 files changed, 92 insertions(+), 53 deletions(-) diff --git a/command_handling/submission_handler.py b/command_handling/submission_handler.py index b362b59..e4223b1 100644 --- a/command_handling/submission_handler.py +++ b/command_handling/submission_handler.py @@ -28,7 +28,7 @@ async def handle_submission( response_message = f"Thanks for uploading, {interaction.user.display_name}! Recieved {language} file: {attachment.filename}." response_message += "\n\nPlease wait while we check your submission..." - await interaction.response.send_message(response_message) + await interaction.followup.send(response_message) return await submitAttachmentToLeetcode(attachment, language) """ diff --git a/main.py b/main.py index 57dd109..517adff 100644 --- a/main.py +++ b/main.py @@ -180,7 +180,11 @@ async def on_guild_join(guild: Guild): @tree.command(description="Say hello.") @app_commands.checks.cooldown(1, 1) async def hello(interaction: discord.Interaction): - await check_submission_channel(interaction, interaction.channel_id) + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + entry = random.randrange(0, len(greeting) - 1) await interaction.response.send_message( f"{greeting[entry]} {interaction.user.mention}" @@ -193,7 +197,11 @@ async def hello(interaction: discord.Interaction): @tree.command(description="See today's problem.") @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) async def current_challenge(interaction: discord.Interaction): - await check_submission_channel(interaction, interaction.channel_id) + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + embeds = getProblemEmbeds(store["cotd"]) await interaction.response.send_message( @@ -230,7 +238,13 @@ async def submit( "Elixir", ], ): - await check_submission_channel(interaction, interaction.channel_id) + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + + await interaction.response.defer() + submission = await handle_submission(interaction, attachment, language) response_message = f"Thanks for uploading, {interaction.user.display_name}! Received {language} file: {attachment.filename}." @@ -289,8 +303,12 @@ async def submit( @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="Provides the Top given value members.") @app_commands.describe(value="What number of the top members you want to see") -async def top(interaction: discord.Interaction, value: int): - await check_submission_channel(interaction, interaction.channel_id) +async def top(interaction: discord.Interaction, value: int): + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + await interaction.response.send_message( await format_rank_list( interaction, ParticipantData.get_instance().get_top(value), value @@ -301,7 +319,11 @@ async def top(interaction: discord.Interaction, value: int): @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="provides the Top 10 members.") async def top10(interaction: discord.Interaction): - await check_submission_channel(interaction, interaction.channel_id) + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + await interaction.response.send_message( await format_rank_list( interaction, ParticipantData.get_instance().get_top(10), 10 @@ -311,8 +333,12 @@ async def top10(interaction: discord.Interaction): @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="Provides how many points you have.") -async def mypoints(interaction: discord.Interaction): - await check_submission_channel(interaction, interaction.channel_id) +async def mypoints(interaction: discord.Interaction): + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + await interaction.response.send_message( f"You currently have {ParticipantData.get_instance().get_points(interaction.user.id)} point(s)." ) @@ -320,14 +346,24 @@ async def mypoints(interaction: discord.Interaction): @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="Compares you with the first place member.") -async def first(interaction: discord.Interaction): - await check_submission_channel(interaction, interaction.channel_id) +async def first(interaction: discord.Interaction): + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + + await interaction.response.defer() await interaction.followup.send(get_first_stats(interaction)) @tree.command(description="Display your personal stats.") -async def get_stats(interaction: discord.Interaction): - await check_submission_channel(interaction, interaction.channel_id) +async def get_stats(interaction: discord.Interaction): + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + + await interaction.response.defer() ParticipantData.get_instance().add_participant(interaction.user.id) participant_stats_embed = discord.Embed( @@ -343,7 +379,7 @@ async def get_stats(interaction: discord.Interaction): value=ParticipantData.get_instance().get_badge(interaction.user.id), ) - await interaction.response.send_message(embed=participant_stats_embed) + await interaction.followup.send(embed=participant_stats_embed) """ ---------- UTILITY ---------- """ @@ -354,7 +390,11 @@ async def get_stats(interaction: discord.Interaction): ) @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) async def rules(interaction: discord.Interaction): - await check_submission_channel(interaction, interaction.channel_id) + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + await interaction.response.send_message( f'**Rules**\n---------\n • Please partricipate in good faith. Don\'t cheat! This competition is to help you improve on your leetcode skills and facilitate fun in our server. If you cheat you are defeating the purpose.\n\n • Challenges are posted at {DAILY_ANNOUNCEMENT_TIME.strftime("%I : %M %p")} in the announcement channel.\n\n • Submit solution files either through DM to me or in the submission channel through the /submit command.\n\n • Opt in to reminder pings through the /remindme command and opt out through the /stopreminders command.\n\n\n ***Happy Trotting Broncoder!***' ) @@ -363,7 +403,11 @@ async def rules(interaction: discord.Interaction): @tree.command(description="Provides a list of supported non admin commands.") @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) async def supported_commands(interaction: discord.Interaction): - await check_submission_channel(interaction, interaction.channel_id) + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + await interaction.response.send_message( f"**************************************************\n COMMANDS\n currently supported commands:\n ---------------------------\n FUN\n * hello : Say hello.\n\n ---------------------------\n PROBLEM SUBMISSION\n * current_challenge : See today's problem.\n * submit : Submit your code to be tested and judged.\n\n ---------------------------\n STATS\n * top: Provides the Top given value members.\n * top10: Provides the Top 10 members\n * mypoints: Provides how many points you have.\n * first: Compares you with the first place member.\n * get_stats: Display your personal stats.\n\n ---------------------------\n UTILITY\n * rules: Provides the rules and instructions to use the bot for the competition.\n * supported_commands: Provides a list of supported non admin commands.\n * remindme: Enroll yourself in competition reminders.\n * stopreminders: Remove yourself from the competition reminders.\n\n****************************************************" ) @@ -372,7 +416,11 @@ async def supported_commands(interaction: discord.Interaction): @tree.command(description="Enroll yourself in competition reminders.") @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) async def remindme(interaction: discord.Interaction): - await check_submission_channel(interaction, interaction.channel_id) + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + if "Broncoder" in [u.name for u in interaction.user.roles]: # Add file? await interaction.response.send_message( @@ -391,7 +439,11 @@ async def remindme(interaction: discord.Interaction): @app_commands.checks.has_role("Broncoder") # add error catch to not crash async def stopreminders(interaction: discord.Interaction): - await check_submission_channel(interaction, interaction.channel_id) + if store.__getitem__("submission_channel_id") == 0: + return await check_submission_channel(interaction) + elif interaction.channel_id != store.__getitem__("submission_channel_id"): + return await check_submission_channel(interaction, True) + comp_role = discord.utils.get(interaction.guild.roles, name="Broncoder") await interaction.user.remove_roles(comp_role) await interaction.response.send_message( @@ -545,18 +597,17 @@ async def givepoints(interaction: discord.Interaction, setting:str, point_value: ERROR HANDLING ******************************************************""" - -async def check_submission_channel(interaction: discord.Interaction, sent_channel: int): - assert ( - store.__getitem__("submission_channel_id") != 0 - ), "Code submission channel not set" - - if sent_channel != store.__getitem__("submission_channel_id"): +async def check_submission_channel(interaction: discord.Interaction, channel_exists: bool=False): + if channel_exists: await interaction.response.send_message( content=f"You sent this command in the wrong channel! Please use <#{store.__getitem__('submission_channel_id')}>", ephemeral=True, ) - + else: + await interaction.response.send_message( + content="No code submission channel set. Please notify an admin to fix this.", + ephemeral=True, + ) @tree.error async def tree_errors( @@ -572,17 +623,6 @@ async def tree_errors( "You do not have the permission to execute this command!", ephemeral=True, ) - elif isinstance(error, app_commands.CommandInvokeError): - error_message = "An error has occurred. Please contact an admin regarding what steps you took for this error message to occur." - if store.__getitem__("submission_channel_id") == 0: - error_message = ( - "No code submission channel set. Please notify an admin to fix this." - ) - - await interaction.response.send_message( - content=error_message, - ephemeral=True, - ) else: print( "Ignoring exception in command {}:".format(interaction.command), diff --git a/submission_handling/selenium.py b/submission_handling/selenium.py index eca3dc3..c9d6a1c 100644 --- a/submission_handling/selenium.py +++ b/submission_handling/selenium.py @@ -17,27 +17,26 @@ # TODO: Add captcha support to some extent +LOCAL_TESTING = False timeout = 60 my_browser_state = BrowserState() options = webdriver.ChromeOptions() -""" Used for local testing -desired_capabilities = DesiredCapabilities.CHROME -options.add_experimental_option("excludeSwitches", ["enable-logging"]) -driver = webdriver.Chrome(desired_capabilities=desired_capabilities, options=options) -""" - -options.binary_location = os.environ.get("GOOGLE_CHROME_BIN") -options.add_argument("--headless") -options.add_argument("--disable-dev-shm-usage") -options.add_argument("--no-sandbox") -driver = webdriver.Chrome( - service=Service(executable_path=os.environ.get("CHROMEDRIVER_PATH")), - options=options, -) -# Used for Heroku Testing - +if LOCAL_TESTING: + desired_capabilities = DesiredCapabilities.CHROME + options.add_experimental_option("excludeSwitches", ["enable-logging"]) + driver = webdriver.Chrome(desired_capabilities=desired_capabilities, options=options) +else: + options.binary_location = os.environ.get("GOOGLE_CHROME_BIN") + options.add_argument("--headless") + options.add_argument("--disable-dev-shm-usage") + options.add_argument("--no-sandbox") + driver = webdriver.Chrome( + service=Service(executable_path=os.environ.get("CHROMEDRIVER_PATH")), + options=options, + ) + # Used for Heroku Testing response_dict_base = {"msg": None, "err": False, "details": {}} From 55e33a6ce703bd19ccb15d3de1a53a307015266a Mon Sep 17 00:00:00 2001 From: Lint Action Date: Sun, 10 Jul 2022 22:15:31 +0000 Subject: [PATCH 06/10] Fix code style issues with Black --- main.py | 28 ++++++++++++++++------------ submission_handling/selenium.py | 4 +++- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/main.py b/main.py index 517adff..c397ab5 100644 --- a/main.py +++ b/main.py @@ -303,7 +303,7 @@ async def submit( @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="Provides the Top given value members.") @app_commands.describe(value="What number of the top members you want to see") -async def top(interaction: discord.Interaction, value: int): +async def top(interaction: discord.Interaction, value: int): if store.__getitem__("submission_channel_id") == 0: return await check_submission_channel(interaction) elif interaction.channel_id != store.__getitem__("submission_channel_id"): @@ -333,7 +333,7 @@ async def top10(interaction: discord.Interaction): @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="Provides how many points you have.") -async def mypoints(interaction: discord.Interaction): +async def mypoints(interaction: discord.Interaction): if store.__getitem__("submission_channel_id") == 0: return await check_submission_channel(interaction) elif interaction.channel_id != store.__getitem__("submission_channel_id"): @@ -346,7 +346,7 @@ async def mypoints(interaction: discord.Interaction): @app_commands.checks.cooldown(1, COOLDOWN_SECONDS) @tree.command(description="Compares you with the first place member.") -async def first(interaction: discord.Interaction): +async def first(interaction: discord.Interaction): if store.__getitem__("submission_channel_id") == 0: return await check_submission_channel(interaction) elif interaction.channel_id != store.__getitem__("submission_channel_id"): @@ -357,12 +357,12 @@ async def first(interaction: discord.Interaction): @tree.command(description="Display your personal stats.") -async def get_stats(interaction: discord.Interaction): +async def get_stats(interaction: discord.Interaction): if store.__getitem__("submission_channel_id") == 0: return await check_submission_channel(interaction) elif interaction.channel_id != store.__getitem__("submission_channel_id"): return await check_submission_channel(interaction, True) - + await interaction.response.defer() ParticipantData.get_instance().add_participant(interaction.user.id) @@ -407,7 +407,7 @@ async def supported_commands(interaction: discord.Interaction): return await check_submission_channel(interaction) elif interaction.channel_id != store.__getitem__("submission_channel_id"): return await check_submission_channel(interaction, True) - + await interaction.response.send_message( f"**************************************************\n COMMANDS\n currently supported commands:\n ---------------------------\n FUN\n * hello : Say hello.\n\n ---------------------------\n PROBLEM SUBMISSION\n * current_challenge : See today's problem.\n * submit : Submit your code to be tested and judged.\n\n ---------------------------\n STATS\n * top: Provides the Top given value members.\n * top10: Provides the Top 10 members\n * mypoints: Provides how many points you have.\n * first: Compares you with the first place member.\n * get_stats: Display your personal stats.\n\n ---------------------------\n UTILITY\n * rules: Provides the rules and instructions to use the bot for the competition.\n * supported_commands: Provides a list of supported non admin commands.\n * remindme: Enroll yourself in competition reminders.\n * stopreminders: Remove yourself from the competition reminders.\n\n****************************************************" ) @@ -420,7 +420,7 @@ async def remindme(interaction: discord.Interaction): return await check_submission_channel(interaction) elif interaction.channel_id != store.__getitem__("submission_channel_id"): return await check_submission_channel(interaction, True) - + if "Broncoder" in [u.name for u in interaction.user.roles]: # Add file? await interaction.response.send_message( @@ -443,7 +443,7 @@ async def stopreminders(interaction: discord.Interaction): return await check_submission_channel(interaction) elif interaction.channel_id != store.__getitem__("submission_channel_id"): return await check_submission_channel(interaction, True) - + comp_role = discord.utils.get(interaction.guild.roles, name="Broncoder") await interaction.user.remove_roles(comp_role) await interaction.response.send_message( @@ -597,7 +597,10 @@ async def givepoints(interaction: discord.Interaction, setting:str, point_value: ERROR HANDLING ******************************************************""" -async def check_submission_channel(interaction: discord.Interaction, channel_exists: bool=False): + +async def check_submission_channel( + interaction: discord.Interaction, channel_exists: bool = False +): if channel_exists: await interaction.response.send_message( content=f"You sent this command in the wrong channel! Please use <#{store.__getitem__('submission_channel_id')}>", @@ -605,9 +608,10 @@ async def check_submission_channel(interaction: discord.Interaction, channel_exi ) else: await interaction.response.send_message( - content="No code submission channel set. Please notify an admin to fix this.", - ephemeral=True, - ) + content="No code submission channel set. Please notify an admin to fix this.", + ephemeral=True, + ) + @tree.error async def tree_errors( diff --git a/submission_handling/selenium.py b/submission_handling/selenium.py index c9d6a1c..8e45003 100644 --- a/submission_handling/selenium.py +++ b/submission_handling/selenium.py @@ -26,7 +26,9 @@ if LOCAL_TESTING: desired_capabilities = DesiredCapabilities.CHROME options.add_experimental_option("excludeSwitches", ["enable-logging"]) - driver = webdriver.Chrome(desired_capabilities=desired_capabilities, options=options) + driver = webdriver.Chrome( + desired_capabilities=desired_capabilities, options=options + ) else: options.binary_location = os.environ.get("GOOGLE_CHROME_BIN") options.add_argument("--headless") From ae06c0884bb09bb26cdbb0a77dfe384bf58d8a86 Mon Sep 17 00:00:00 2001 From: Luciano Lim Date: Wed, 13 Jul 2022 16:37:31 -0700 Subject: [PATCH 07/10] fixes issue where 2-user ties don't show --- command_handling/first_handler.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/command_handling/first_handler.py b/command_handling/first_handler.py index 5a12abc..5555135 100644 --- a/command_handling/first_handler.py +++ b/command_handling/first_handler.py @@ -8,7 +8,8 @@ def get_first_stats(interaction: discord.Interaction): - days_left = monthrange(date.today().year, date.today().month)[1] - date.today().day + days_left = monthrange(date.today().year, date.today().month)[ + 1] - date.today().day # Check if there are participants: if ( @@ -22,18 +23,20 @@ def get_first_stats(interaction: discord.Interaction): # get list of users in first place first_places = list( map( - lambda id: interaction.guild.get_member(int(id)).display_name, first_ids + lambda id: interaction.guild.get_member( + int(id)).display_name, first_ids ) ) # check if user is in first place - user_is_first = first_places.__contains__(interaction.user.display_name) + user_is_first = first_places.__contains__( + interaction.user.display_name) # remove user from list if first_places.__contains__(interaction.user.display_name): first_places.remove(interaction.user.display_name) # makes string containing list of people in first place (except user) first_place_message = "" - if len(first_places) == 1: + if len(first_places) == 0: first_place_message = f"{first_places[0]}" else: # form list of first place @@ -48,7 +51,7 @@ def get_first_stats(interaction: discord.Interaction): if user_is_first: # first place is triggering command! response_message = f"You are first place! Keep it up, you have {ParticipantData.get_instance().get_points(interaction.user.id)} point(s)!\n" - if not len(first_places) == 1: + if not len(first_places) == 0: response_message = f"You are tied with {first_place_message}\n" else: points_behind = ParticipantData.get_instance().get_points( From 7cedb39ea4add585677706b5ba37e0e8f24a642c Mon Sep 17 00:00:00 2001 From: Lint Action Date: Wed, 13 Jul 2022 23:38:02 +0000 Subject: [PATCH 08/10] Fix code style issues with Black --- command_handling/first_handler.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/command_handling/first_handler.py b/command_handling/first_handler.py index 5555135..4fad549 100644 --- a/command_handling/first_handler.py +++ b/command_handling/first_handler.py @@ -8,8 +8,7 @@ def get_first_stats(interaction: discord.Interaction): - days_left = monthrange(date.today().year, date.today().month)[ - 1] - date.today().day + days_left = monthrange(date.today().year, date.today().month)[1] - date.today().day # Check if there are participants: if ( @@ -23,13 +22,11 @@ def get_first_stats(interaction: discord.Interaction): # get list of users in first place first_places = list( map( - lambda id: interaction.guild.get_member( - int(id)).display_name, first_ids + lambda id: interaction.guild.get_member(int(id)).display_name, first_ids ) ) # check if user is in first place - user_is_first = first_places.__contains__( - interaction.user.display_name) + user_is_first = first_places.__contains__(interaction.user.display_name) # remove user from list if first_places.__contains__(interaction.user.display_name): first_places.remove(interaction.user.display_name) From 767e8ee4789005aa4fceb1d6137d0b3c90682f53 Mon Sep 17 00:00:00 2001 From: peppacaiou <109382836+peppacaiou@users.noreply.github.com> Date: Fri, 15 Jul 2022 18:41:16 -0700 Subject: [PATCH 09/10] testing out the waters --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index c397ab5..4311fc8 100644 --- a/main.py +++ b/main.py @@ -45,7 +45,7 @@ intenderinos = discord.Intents.default() intenderinos.members = True - +# I was here activity = discord.activity.Activity( type=discord.ActivityType.competing, name="Leetcode" ) From 16066c53670af339f2164898cf73eceb7658346b Mon Sep 17 00:00:00 2001 From: Lint Action Date: Sat, 16 Jul 2022 01:43:54 +0000 Subject: [PATCH 10/10] Fix code style issues with Black --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 4311fc8..572217a 100644 --- a/main.py +++ b/main.py @@ -45,7 +45,7 @@ intenderinos = discord.Intents.default() intenderinos.members = True -# I was here +# I was here activity = discord.activity.Activity( type=discord.ActivityType.competing, name="Leetcode" )