-
Notifications
You must be signed in to change notification settings - Fork 1
✨ feat: Add /recent command for viewing user submissions #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- New slash command to display recent accepted submissions for any LeetCode user - Paginated interface showing one problem per page with navigation buttons - Lazy loading implementation to fetch problem details only when needed - 5-minute cache for submissions to improve performance - Navigation buttons placed at edges without text labels for clean UI - English language for timestamps and page indicators - Supports up to 50 recent submissions with customizable limit 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Wrap tags with || spoiler markers to hide potential hints - Consistent with tag display in other commands 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Fix typo in daily_cn command description (remove trailing '1') - Move time import to module level to avoid repeated imports - Store original limit in cache to maintain consistent pagination when re-fetching - Update docstring to accurately reflect basic submission info return - Remove test_recent function from production code 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a new /recent slash command to fetch and display a LeetCode user's recent accepted submissions with pagination, lazy loading of problem details, and a short-term cache.
- Converted
fetch_recent_ac_submissionsto async and return only basic info for lazy loading. - Introduced
/recentcommand inSlashCommandsCogwith paginated embeds and caching. - Added navigation handlers and a TTL-based submissions cache in
InteractionHandlerCog.
Reviewed Changes
Copilot reviewed 3 out of 13 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| leetcode.py | Made fetch_recent_ac_submissions async, added domain check, and built basic submission info |
| cogs/slash_commands_cog.py | Added /recent command, helper methods for embeds/views, and caching logic |
| cogs/interaction_handler_cog.py | Implemented prev/next button handlers, cache lookup/refresh, and page navigation |
Comments suppressed due to low confidence (4)
leetcode.py:621
- The method now returns early for non-
.comdomains but this limitation is not documented in the docstring; consider updating the docstring to mention domain restriction.
if self.domain != "com":
cogs/slash_commands_cog.py:345
- New pagination and caching behaviors were added but there are no corresponding tests; consider adding unit tests for the
/recentcommand, page navigation, and cache expiration logic.
@app_commands.command(name="recent", description="查看 LeetCode 使用者的近期解題紀錄 (僅限 LCUS)")
cogs/slash_commands_cog.py:392
self.loggeris used here but there's no evidence thatself.loggeris initialized in this cog; you may need to define it in__init__or useself.bot.loggerto avoid anAttributeError.
self.logger.info(f"Sent user submissions for {username} to {interaction.user.name}")
cogs/slash_commands_cog.py:472
- [nitpick] The constant
LEETCODE_DISCRIPTION_BUTTON_PREFIXappears to have a typo ('DISCRIPTION' vs 'DESCRIPTION'); consider renaming for clarity.
custom_id=f"{self.bot.LEETCODE_DISCRIPTION_BUTTON_PREFIX}{submission['id']}_com",
| cached_data = self.submissions_cache.get(cache_key) | ||
|
|
||
| # Check if cache is valid (5 minutes) | ||
| if cached_data and (time.time() - cached_data[1]) < 300: | ||
| submissions = cached_data[0] | ||
| else: | ||
| # Fetch submissions again | ||
| await interaction.response.defer(ephemeral=True) | ||
| # Use the original limit if available, otherwise default to 50 | ||
| original_limit = cached_data[2] if cached_data and len(cached_data) > 2 else 50 | ||
| submissions = await self.bot.lcus.fetch_recent_ac_submissions(username, original_limit) | ||
| if not submissions: | ||
| await interaction.followup.send(f"找不到使用者 **{username}** 的解題紀錄。", ephemeral=True) | ||
| return | ||
| # Update cache with limit | ||
| self.submissions_cache[cache_key] = (submissions, time.time(), original_limit) | ||
|
|
Copilot
AI
Jul 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Accessing cached_data by index makes the code harder to read; consider unpacking the tuple as (submissions, timestamp, original_limit) = cached_data for clarity.
| cached_data = self.submissions_cache.get(cache_key) | |
| # Check if cache is valid (5 minutes) | |
| if cached_data and (time.time() - cached_data[1]) < 300: | |
| submissions = cached_data[0] | |
| else: | |
| # Fetch submissions again | |
| await interaction.response.defer(ephemeral=True) | |
| # Use the original limit if available, otherwise default to 50 | |
| original_limit = cached_data[2] if cached_data and len(cached_data) > 2 else 50 | |
| submissions = await self.bot.lcus.fetch_recent_ac_submissions(username, original_limit) | |
| if not submissions: | |
| await interaction.followup.send(f"找不到使用者 **{username}** 的解題紀錄。", ephemeral=True) | |
| return | |
| # Update cache with limit | |
| self.submissions_cache[cache_key] = (submissions, time.time(), original_limit) | |
| cached_data = self.submissions_cache.get(cache_key) | |
| # Unpack cached data | |
| if cached_data: | |
| submissions, timestamp, original_limit = cached_data | |
| else: | |
| submissions, timestamp, original_limit = None, None, 50 | |
| # Check if cache is valid (5 minutes) | |
| if submissions and (time.time() - timestamp) < 300: | |
| pass # Use cached submissions | |
| else: | |
| # Fetch submissions again | |
| await interaction.response.defer(ephemeral=True) | |
| submissions = await self.bot.lcus.fetch_recent_ac_submissions(username, original_limit) | |
| if not submissions: | |
| await interaction.followup.send(f"找不到使用者 **{username}** 的解題紀錄。", ephemeral=True) | |
| return | |
| # Update cache with limit | |
| self.submissions_cache[cache_key] = (submissions, time.time(), original_limit) | |
| tags_str = ", ".join([f"||`{tag}`||" for tag in submission['tags'][:5]]) # Limit tags to avoid too long | ||
| embed.add_field(name="🏷️ Tags", value=tags_str, inline=False) | ||
|
|
||
| embed.set_author(name=f"{username}'s Recent Submissions", icon_url="https://leetcode.com/static/images/LeetCode_logo.png") |
Copilot
AI
Jul 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The author name is in English while command messages are in Chinese; consider localizing all UI strings consistently based on user language.
| embed.set_author(name=f"{username}'s Recent Submissions", icon_url="https://leetcode.com/static/images/LeetCode_logo.png") | |
| localized_author_name = self._translate("Recent Submissions", username) | |
| embed.set_author(name=localized_author_name, icon_url="https://leetcode.com/static/images/LeetCode_logo.png") |
Summary
/recentslash command to view any LeetCode user's recent accepted submissionsFeatures
Changes
leetcode.py:fetch_recent_ac_submissionsasync with aiohttpcogs/slash_commands_cog.py:/recentcommand with username and limit parameters_get_submission_detailsfor lazy loading problem informationcogs/interaction_handler_cog.py:Test Plan
/recentcommand with valid username🤖 Generated with Claude Code