from asyncio import create_task, shield, to_thread, wait_for from sys import argv from discord import Game, Intents, Interaction, app_commands from discord.ext import commands from PICable import PICable if len(argv) != 3: print("Usage:\n\t" + argv[0] + " ") exit(1) discord_token = argv[1] github_token = argv[2] intents = Intents.default() intents.message_content = True client = commands.Bot(command_prefix="/", intents=intents) current_repositories = set() @client.event async def on_ready(): print(f"We have logged in as {client.user}") await client.change_presence(activity=Game("with PIC ideas")) try: synced = await client.tree.sync() print(f"Synced {len(synced)} command(s)") except Exception as e: print(f"Failed to sync commands: {e}") @client.tree.command(name="ping", description="Check the bot's latency.") async def ping(interaction: Interaction): latency = client.latency * 1000 await interaction.response.send_message(f"Pong! Latency: {latency:.2f}ms") @client.tree.command(name="picable", description="Check if a Github repository is eligible for PIC.") @app_commands.describe(owner="The owner of the repository", repository="The name of the repository") async def picable(interaction: Interaction, owner: str, repository: str): await interaction.response.defer(thinking=True) repository_full_name = f"{owner}/{repository}" if repository_full_name in current_repositories: await interaction.followup.send( f"The repository {repository_full_name} is already being analyzed. Please wait for the current analysis to complete. :warning:" ) return current_repositories.add(repository_full_name) try: result_future = create_task(to_thread(PICable, owner, repository, github_token)) try: result = await wait_for(shield(result_future), timeout=600) await interaction.followup.send(result) except TimeoutError: await interaction.followup.send( f"The analysis for {repository_full_name} is still taking place. The results will be posted here once the analysis is complete. :clock4:" ) result = await result_future await interaction.channel.send(result) except Exception as e: print(f"Error processing PICable check: {e}") await interaction.channel.send("An error occurred while processing your request. Please try again later.") finally: current_repositories.remove(repository_full_name) client.run(discord_token)