-
Notifications
You must be signed in to change notification settings - Fork 68
implement support for Forgejo comments and reactions #906
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,193 @@ | ||
| # Copyright Contributors to the Packit project. | ||
| # SPDX-License-Identifier: MIT | ||
|
|
||
| import datetime | ||
| from typing import Any | ||
|
|
||
| from ogr.abstract import Comment, CommitComment, IssueComment, PRComment, Reaction | ||
|
|
||
|
|
||
| class ForgejoReaction(Reaction): | ||
| _raw_reaction: dict | ||
|
|
||
| def __init__( | ||
| self, | ||
| raw_reaction: dict, | ||
| forgejo_client: Any, | ||
| repository: str, | ||
| issue_number: int, | ||
| ) -> None: | ||
| """ | ||
| Initializes a ForgejoReaction. | ||
| Args: | ||
| raw_reaction (dict): The raw reaction data from the API. | ||
| forgejo_client (Any): The Forgejo client instance. | ||
| repository (str): Repository identifier (e.g., "owner/repo"). | ||
| issue_number (int): The issue number associated with the comment. | ||
| """ | ||
| self._raw_reaction = raw_reaction | ||
| self._forgejo_client = forgejo_client | ||
| self._repository = repository | ||
| self._issue_number = issue_number | ||
| self._id = raw_reaction.get("id") | ||
| self._content = raw_reaction.get("content") | ||
| self._user_login = raw_reaction.get("user", {}).get("login") | ||
|
|
||
| def __str__(self) -> str: | ||
| return "Forgejo" + super().__str__() | ||
|
|
||
| def delete(self) -> None: | ||
| """ | ||
| Deletes the reaction from Forgejo using the stored client context. | ||
| """ | ||
| url = ( | ||
| f"{self._forgejo_client.forgejo_url}/api/v1/repos/" | ||
| f"{self._repository}/issues/{self._issue_number}/reactions/{self._id}" | ||
| ) | ||
| self._forgejo_client._make_request("DELETE", url) | ||
|
Comment on lines
+44
to
+48
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we are using the client library methods, see examples here, that file can be an inspiration on how to implement the methods. So for this particular case, you would use this method. And similarly, for other methods where you currently construct the URL manually.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you so much for this clarity
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am working on implementing
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you @mynk8 will you have time today?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes 👍
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's kind of true, I need
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh yeah, I missed that this PR is now implementing comments in general. Up to you how it is easier to coordinate. You could also make it a |
||
|
|
||
| @property | ||
| def content(self) -> str: | ||
| return self._content | ||
|
|
||
| @property | ||
| def user_login(self) -> str: | ||
| return self._user_login | ||
|
|
||
| @property | ||
| def id(self) -> int: | ||
| return self._id | ||
|
|
||
|
|
||
| class ForgejoComment(Comment): | ||
| def __init__( | ||
| self, | ||
| raw_comment: dict, | ||
| forgejo_client: Any, | ||
| repository: str, | ||
| issue_number: int, | ||
| ) -> None: | ||
| """ | ||
| Initializes a ForgejoComment. | ||
| Args: | ||
| raw_comment (dict): The raw comment data. | ||
| forgejo_client (Any): The Forgejo client instance. | ||
| repository (str): Repository identifier (e.g., "owner/repo"). | ||
| issue_number (int): The issue number associated with the comment. | ||
| """ | ||
| self._forgejo_client = forgejo_client | ||
| self._repository = repository | ||
| self._issue_number = issue_number | ||
| self._from_raw_comment(raw_comment) | ||
|
|
||
| def _from_raw_comment(self, raw_comment: dict) -> None: | ||
| """ | ||
| Initializes comment attributes from the raw API data. | ||
| """ | ||
| self._raw_comment = raw_comment | ||
| self._id = raw_comment.get("id") | ||
| self._author = raw_comment.get("user", {}).get("login") | ||
| created_at = raw_comment.get("created_at") | ||
| self._created = ( | ||
| datetime.datetime.fromisoformat(created_at.replace("Z", "+00:00")) | ||
| if created_at | ||
| else None | ||
| ) | ||
| updated_at = raw_comment.get("updated_at") | ||
| self._edited = ( | ||
| datetime.datetime.fromisoformat(updated_at.replace("Z", "+00:00")) | ||
| if updated_at | ||
| else None | ||
| ) | ||
|
|
||
| @property | ||
| def body(self) -> str: | ||
| return self._raw_comment.get("body") | ||
|
|
||
| @body.setter | ||
| def body(self, new_body: str) -> None: | ||
| """ | ||
| Updates the comment body in Forgejo. | ||
| """ | ||
| url = ( | ||
| f"{self._forgejo_client.forgejo_url}/api/v1/repos/" | ||
| f"{self._repository}/issues/{self._issue_number}/comments/{self._id}" | ||
| ) | ||
| data = {"body": new_body} | ||
| self._forgejo_client._make_request("PATCH", url, data) | ||
| self._raw_comment["body"] = new_body | ||
|
|
||
| @property | ||
| def edited(self) -> datetime.datetime: | ||
| return self._edited | ||
|
|
||
| def get_reactions(self) -> list[Reaction]: | ||
| """ | ||
| Retrieves all reactions for this comment. | ||
| """ | ||
| url = ( | ||
| f"{self._forgejo_client.forgejo_url}/api/v1/repos/" | ||
| f"{self._repository}/issues/{self._issue_number}/comments/{self._id}/reactions" | ||
| ) | ||
| reactions_data = self._forgejo_client._make_request("GET", url) | ||
| return [ | ||
| ForgejoReaction( | ||
| r, | ||
| self._forgejo_client, | ||
| self._repository, | ||
| self._issue_number, | ||
| ) | ||
| for r in reactions_data | ||
| ] | ||
|
|
||
| def add_reaction(self, reaction: str) -> ForgejoReaction: | ||
| """ | ||
| Adds a reaction to the comment. | ||
| Args: | ||
| reaction (str): The reaction content (e.g., "+1", "heart"). | ||
| Returns: | ||
| ForgejoReaction: The created reaction object. | ||
| """ | ||
| url = ( | ||
| f"{self._forgejo_client.forgejo_url}/api/v1/repos/" | ||
| f"{self._repository}/issues/{self._issue_number}/comments/{self._id}/reactions" | ||
| ) | ||
| data = {"content": reaction} | ||
| reaction_data = self._forgejo_client._make_request("POST", url, data) | ||
| return ForgejoReaction( | ||
| reaction_data, | ||
| self._forgejo_client, | ||
| self._repository, | ||
| self._issue_number, | ||
| ) | ||
|
|
||
| @property | ||
| def id(self) -> int: | ||
| return self._id | ||
|
|
||
| @property | ||
| def author(self) -> str: | ||
| return self._author | ||
|
|
||
| @property | ||
| def created(self) -> datetime.datetime: | ||
| return self._created | ||
|
|
||
|
|
||
| class ForgejoIssueComment(ForgejoComment, IssueComment): | ||
| def __str__(self) -> str: | ||
| return "Forgejo" + super().__str__() | ||
|
|
||
|
|
||
| class ForgejoPRComment(ForgejoComment, PRComment): | ||
| def __str__(self) -> str: | ||
| return "Forgejo" + super().__str__() | ||
|
|
||
|
|
||
| class ForgejoCommitComment(ForgejoComment, CommitComment): | ||
| def __str__(self) -> str: | ||
| return "Forgejo" + super().__str__() | ||
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.
Where does this
__init__come from. I don't see a reference toforgejo_clientin the current codebase