-
-
Notifications
You must be signed in to change notification settings - Fork 41
REFACTOR: bookmark service #918
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
…and channel fetching
…and channel fetching
…andling and support for attachments Refactor the bookmarks cog to improve the handling of bookmark reactions. Introduce aiohttp for asynchronous HTTP requests and manage session lifecycle. Add support for handling attachments, stickers, and embeds in bookmarked messages, ensuring that up to 10 files are attached to the bookmark message. Improve error handling and logging for better traceability of issues. These changes enhance the user experience by providing more comprehensive bookmarking capabilities and ensuring robustness in various scenarios.
Reviewer's GuideThis refactor restructures the bookmark service by centralizing reaction handling, extracting bookmark operations into dedicated methods, introducing session management and robust error handling, and enhancing embed creation and file attachment logic. Class diagram for refactored Bookmarks serviceclassDiagram
class Bookmarks {
- bot: Tux
- add_bookmark_emojis
- remove_bookmark_emojis
- valid_emojis
- session: aiohttp.ClientSession
+ __init__(bot: Tux)
+ cog_unload()
+ on_raw_reaction_add(payload: discord.RawReactionActionEvent)
+ add_bookmark(user: discord.User, message: discord.Message)
+ remove_bookmark(message: discord.Message)
+ _get_files_from_attachments(message: discord.Message, files: list[discord.File])
+ _get_files_from_stickers(message: discord.Message, files: list[discord.File])
+ _get_files_from_embeds(message: discord.Message, files: list[discord.File])
+ _get_files_from_message(message: discord.Message) -> list[discord.File]
+ _create_bookmark_embed(message: discord.Message) -> discord.Embed
}
Bookmarks --> "1" Tux
Bookmarks --> "1" aiohttp.ClientSession
Bookmarks --> "1" discord.RawReactionActionEvent
Bookmarks --> "1" discord.User
Bookmarks --> "1" discord.Message
Bookmarks --> "*" discord.File
Bookmarks --> "1" discord.Embed
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
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.
Hey @kzndotsh - I've reviewed your changes - here's some feedback:
- There’s duplicated channel/user fetching and validation logic in both the bookmark and poll listeners—consider extracting that into a shared helper to reduce repetition.
- In
add_bookmark, you calldm_message.add_reaction(self.remove_bookmark_emojis)butremove_bookmark_emojisis a string of emojis—if you only want to add one emoji this is fine, otherwise iterate over the collection or clarify your intent.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- There’s duplicated channel/user fetching and validation logic in both the bookmark and poll listeners—consider extracting that into a shared helper to reduce repetition.
- In `add_bookmark`, you call `dm_message.add_reaction(self.remove_bookmark_emojis)` but `remove_bookmark_emojis` is a string of emojis—if you only want to add one emoji this is fine, otherwise iterate over the collection or clarify your intent.
## Individual Comments
### Comment 1
<location> `tux/cogs/services/bookmarks.py:22` </location>
<code_context>
+ self.add_bookmark_emojis = CONST.ADD_BOOKMARK
+ self.remove_bookmark_emojis = CONST.REMOVE_BOOKMARK
+ self.valid_emojis = self.add_bookmark_emojis + self.remove_bookmark_emojis
+ self.session = aiohttp.ClientSession()
+
+ async def cog_unload(self) -> None:
</code_context>
<issue_to_address>
Instantiating aiohttp.ClientSession in __init__ may cause warnings.
Move ClientSession creation to an async initialization method to prevent deprecation warnings and ensure compatibility with future aiohttp versions.
Suggested implementation:
```python
self.session = None
```
```python
async def cog_load(self) -> None:
"""Initializes resources for the cog, including the aiohttp session."""
self.session = aiohttp.ClientSession()
async def cog_unload(self) -> None:
"""Cleans up the cog, closing the aiohttp session."""
if self.session:
await self.session.close()
```
</issue_to_address>
### Comment 2
<location> `tux/cogs/utility/poll.py:79` </location>
<code_context>
if channel is None:
- logger.error(f"Channel with ID {payload.channel_id} not found.")
- return
- if isinstance(channel, discord.ForumChannel | discord.CategoryChannel | discord.abc.PrivateChannel):
- logger.error(
- f"Channel with ID {payload.channel_id} is not a compatible channel type. How the fuck did you get here?",
- )
- return
+ try:
+ channel = await self.bot.fetch_channel(payload.channel_id)
</code_context>
<issue_to_address>
Type check for channel is removed, which may allow unsupported channel types.
Without the type check, casting to TextChannel or Thread may be unsafe and could result in runtime errors if the channel is not of the expected type.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| self.add_bookmark_emojis = CONST.ADD_BOOKMARK | ||
| self.remove_bookmark_emojis = CONST.REMOVE_BOOKMARK | ||
| self.valid_emojis = self.add_bookmark_emojis + self.remove_bookmark_emojis | ||
| self.session = aiohttp.ClientSession() |
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.
suggestion (bug_risk): Instantiating aiohttp.ClientSession in init may cause warnings.
Move ClientSession creation to an async initialization method to prevent deprecation warnings and ensure compatibility with future aiohttp versions.
Suggested implementation:
self.session = None async def cog_load(self) -> None:
"""Initializes resources for the cog, including the aiohttp session."""
self.session = aiohttp.ClientSession()
async def cog_unload(self) -> None:
"""Cleans up the cog, closing the aiohttp session."""
if self.session:
await self.session.close()| channel = self.bot.get_channel(payload.channel_id) | ||
| if channel is None: | ||
| logger.error(f"Channel with ID {payload.channel_id} not found.") | ||
| return |
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.
issue (bug_risk): Type check for channel is removed, which may allow unsupported channel types.
Without the type check, casting to TextChannel or Thread may be unsafe and could result in runtime errors if the channel is not of the expected type.
Codecov ReportAttention: Patch coverage is
✅ All tests successful. No failed tests found.
Additional details and impacted files@@ Coverage Diff @@
## main #918 +/- ##
========================================
+ Coverage 8.91% 8.92% +0.01%
========================================
Files 121 121
Lines 10189 10269 +80
Branches 1236 1255 +19
========================================
+ Hits 908 917 +9
- Misses 9213 9278 +65
- Partials 68 74 +6
*This pull request uses carry forward flags. Click here to find out more.
☔ View full report in Codecov by Sentry. |
Suspect IssuesThis pull request was deployed and Sentry observed the following issues:
Did you find this useful? React with a 👍 or 👎 |
Description
Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change. If this change fixes any issues please put "Fixes #XX" in the description. Please also ensure to add the appropriate labels to the PR.
Guidelines
My code follows the style guidelines of this project (formatted with Ruff)
I have performed a self-review of my own code
I have commented my code, particularly in hard-to-understand areas
I have made corresponding changes to the documentation if needed
My changes generate no new warnings
I have tested this change
Any dependent changes have been merged and published in downstream modules
I have added all appropriate labels to this PR
[X ] I have followed all of these guidelines.
How Has This Been Tested? (if applicable)
Please describe how you tested your code. e.g describe what commands you ran, what arguments, and any config stuff (if applicable)
Screenshots (if applicable)
Please add screenshots to help explain your changes.
Additional Information
Please add any other information that is important to this PR.
Summary by Sourcery
Refactor the bookmark cog to support configurable add/remove reactions, streamline file attachments and embed composition, manage HTTP sessions, and improve error handling; update poll cog to handle channel fetch failures gracefully; and add bookmark emoji constants.
New Features:
Bug Fixes:
Enhancements: