diff --git a/app.py b/app.py index e089f0a..145a579 100644 --- a/app.py +++ b/app.py @@ -15,6 +15,13 @@ def get_prefix(bot, message): return commands.when_mentioned_or(prefix)(bot, message) async def load(): + """ + Loads all the Python files in the 'cog' directory as extensions for the bot. + + This function iterates over all the files in the 'cog' directory and loads each file + as an extension for the bot if it is a Python file (ends with '.py'). It prints a message + indicating whether each extension was successfully loaded or not. + """ cog_dir = './cog' for filename in os.listdir(cog_dir): file_path = os.path.join(cog_dir, filename) diff --git a/bot_components/bot.py b/bot_components/bot.py index 4e08567..066a18f 100644 --- a/bot_components/bot.py +++ b/bot_components/bot.py @@ -10,20 +10,50 @@ import asyncio class Nanéu(commands.Bot): + """ + A custom bot class for Nanéu. + + This class extends the `commands.Bot` class and provides additional functionality for the Nanéu bot. + + Attributes: + config (dict): The configuration settings for the bot. + """ + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.config = None async def on_ready(self): + """ + Event handler for when the bot is ready. + + This method is called when the bot has successfully logged in and is ready to start processing events. + It prints the bot's user information and the number of guilds it is a member of, and starts the `scrape_and_post` task. + """ print(f'scrapper is logged in as {self.user}') print(f'Bot is a member of {len(self.guilds)} guilds') self.scrape_and_post.start() async def close(self): + """ + Closes the bot. + + This method cancels the `scrape_and_post` task and then calls the `close` method of the base class. + """ self.scrape_and_post.cancel() await super().close() async def on_guild_join(self, guild): + """ + Event handler for when the bot joins a guild. + + This method is called when the bot joins a new guild. + It sends a welcome message to the system channel of the guild (if the bot has permission to send messages), + and sends a notification message to the bot admin user. + + Args: + guild (discord.Guild): The guild that the bot joined. + """ system_channel = guild.system_channel if system_channel is not None and system_channel.permissions_for(guild.me).send_messages: await system_channel.send("Thanks for invite!\nPlease run/type `@nanéu setup` command on the channel you wish me to post, to configure me to your liking.") @@ -36,6 +66,14 @@ async def on_guild_join(self, guild): @tasks.loop(seconds=60) async def scrape_and_post(self): + """ + Task that periodically scrapes job listings and posts them to Discord. + + This task is scheduled to run every 60 seconds. + It iterates over all the guilds that the bot is a member of, and for each guild, + it iterates over the text channels and checks if there is a configuration for the channel. + If a configuration is found, it scrapes job listings and posts them to the channel. + """ print('Entered scrape_and_post loop') for guild in self.guilds: print(f'Checking guild {guild.id}') @@ -51,6 +89,15 @@ async def scrape_and_post(self): print("Configuration not found. Please run the !setup command.") async def scrape_and_post_to_discord(self, channel): + """ + Scrapes job listings and posts them to a Discord channel. + + This method scrapes job listings based on the configuration settings for the given channel, + and then creates embeds for each job listing and sends them to the channel. + + Args: + channel (discord.TextChannel): The channel to post the job listings to. + """ print(f"2.Entered scrape_and_post_to_discord for channel {channel.id}") # make scraping run on a separate thread in the background to avoid blocking the event loop loop = asyncio.get_event_loop() diff --git a/cog/setup.py b/cog/setup.py index 3ab7c0c..d54e731 100644 --- a/cog/setup.py +++ b/cog/setup.py @@ -4,6 +4,15 @@ import yaml class Setup(commands.Cog): + """ + A class representing the setup functionality of Nanéu bot. + + This class provides methods to configure Nanéu to user preferences, such as job search settings. + + Attributes: + bot (discord.ext.commands.Bot): The instance of the bot. + setup_processes (dict): A dictionary to store setup processes for each user. + """ def __init__(self, bot): self.bot = bot self.setup_processes = {} @@ -67,7 +76,7 @@ async def ask_question(self, ctx, question, check, conversion=str): while True: # Keep asking the question until a non-empty answer is received await ctx.send(question) try: - answer = await self.bot.wait_for('message', check=check, timeout=60) # Wait for 60 seconds + answer = await self.bot.wait_for('message', check=check, timeout=120) except asyncio.TimeoutError: print(f"No answer received for question: {question}") return None