diff --git a/examples/get_test_entities.py b/examples/get_test_entities.py index fc50a84..72f34f1 100644 --- a/examples/get_test_entities.py +++ b/examples/get_test_entities.py @@ -31,6 +31,7 @@ async def main() -> None: await client.get_worklog("TRACKER-1") await client.get_worklog_records_by_parameters(me.login) await client.get_attachments_list('TRACKER-1') + await client.get_issue_comments('TRACKER-1') await client.stop() diff --git a/ya_tracker_client/domain/entities/comment.py b/ya_tracker_client/domain/entities/comment.py new file mode 100644 index 0000000..b86a8c9 --- /dev/null +++ b/ya_tracker_client/domain/entities/comment.py @@ -0,0 +1,35 @@ +from datetime import datetime + +from pydantic import Field + +from ya_tracker_client.domain.entities.base import AbstractEntity +from ya_tracker_client.domain.entities.mailing_list import MailingList +from ya_tracker_client.domain.entities.user import UserShort + + +class Comment(AbstractEntity): + url: str + id: int + long_id: str + text: str + created_by: UserShort + created_at: datetime + updated_by: UserShort + updated_at: datetime + summonees: list[UserShort] = Field(default_factory=list) + maillistsummonees: list[MailingList] = Field(default_factory=list) + version: int + type: str = Field(examples=["standard", "incoming", "outcoming"]) + transport: str = Field(examples=["internal", "email"]) + + +class CommentCreate(AbstractEntity): + text: str + attachment_ids: list[str] | None = None + summonees: list[UserShort | str] | None = None + maillistsummonees: list[str] | None = None + + +class CommentEdit(AbstractEntity): + text: str + attachment_ids: list[str] | None = None diff --git a/ya_tracker_client/domain/entities/mailing_list.py b/ya_tracker_client/domain/entities/mailing_list.py new file mode 100644 index 0000000..518bd15 --- /dev/null +++ b/ya_tracker_client/domain/entities/mailing_list.py @@ -0,0 +1,7 @@ +from ya_tracker_client.domain.entities.base import AbstractEntity + + +class MailingList(AbstractEntity): + url: str + id: str + display: str diff --git a/ya_tracker_client/domain/repositories/__init__.py b/ya_tracker_client/domain/repositories/__init__.py index 0b1f15d..163b661 100644 --- a/ya_tracker_client/domain/repositories/__init__.py +++ b/ya_tracker_client/domain/repositories/__init__.py @@ -1,5 +1,6 @@ from ya_tracker_client.domain.repositories.attachment import AttachmentRepository from ya_tracker_client.domain.repositories.checklist import ChecklistRepository +from ya_tracker_client.domain.repositories.comment import CommentRepository from ya_tracker_client.domain.repositories.component import ComponentRepository from ya_tracker_client.domain.repositories.issue import IssueRepository from ya_tracker_client.domain.repositories.issue_relationship import IssueRelationshipRepository @@ -11,10 +12,11 @@ __all__ = [ "AttachmentRepository", "ChecklistRepository", + "CommentRepository", "ComponentRepository", "IssueRelationshipRepository", "IssueRepository", "QueueRepository", - "WorklogRepository", "UserRepository", + "WorklogRepository", ] diff --git a/ya_tracker_client/domain/repositories/attachment.py b/ya_tracker_client/domain/repositories/attachment.py index 48e21b7..7497412 100644 --- a/ya_tracker_client/domain/repositories/attachment.py +++ b/ya_tracker_client/domain/repositories/attachment.py @@ -9,7 +9,7 @@ class AttachmentRepository(EntityRepository): async def get_attachments_list(self, issue_id: str) -> list[Attachment]: """ - Use this request to get a list of files attached to an issue and to comments below it. + Use this method to get a list of files attached to an issue and to comments below it. YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/get-attachments-list """ @@ -26,7 +26,7 @@ async def download_attachment( filename: str, ) -> bytes: """ - Use this request to download files attached to issues. + Use this method to download files attached to issues. YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/get-attachment """ @@ -78,7 +78,7 @@ async def upload_temp_file( """ Upload temporary file. - Use this request to upload a file to Tracker first, and then + Use this method to upload a file to Tracker first, and then attach it when creating an issue or adding a comment. YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/temp-attachment diff --git a/ya_tracker_client/domain/repositories/comment.py b/ya_tracker_client/domain/repositories/comment.py new file mode 100644 index 0000000..0feda15 --- /dev/null +++ b/ya_tracker_client/domain/repositories/comment.py @@ -0,0 +1,81 @@ +from ya_tracker_client.domain.entities.comment import Comment, CommentCreate, CommentEdit +from ya_tracker_client.domain.entities.user import UserShort +from ya_tracker_client.domain.repositories.base import EntityRepository + + +class CommentRepository(EntityRepository): + async def add_comment( + self, + issue_id: str, + text: str, + attachment_ids: list[str] | None = None, + summonees: list[str | UserShort] | None = None, + maillist_summonees: list[str] | None = None, + is_add_to_followers: bool | None = None, + ) -> Comment: + """ + Use this method to add a comment to an issue. + + YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/add-comment + """ + raw_response = await self._client.request( + method="POST", + uri=f"/issues/{issue_id}/comments", + payload=CommentCreate( + text=text, + attachment_ids=attachment_ids, + summonees=summonees, + maillist_summonees=maillist_summonees, + ).model_dump(exclude_none=True, by_alias=True), + params={"is_add_to_followers": is_add_to_followers} if is_add_to_followers is not None else None, + ) + return self._decode(raw_response, Comment) + + async def get_issue_comments(self, issue_id: str) -> list[Comment]: + """ + Use this method to get a list of comments on an issue. + + YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/get-comments + """ + raw_response = await self._client.request( + method="GET", + uri=f"/issues/{issue_id}/comments", + ) + return self._decode(raw_response, Comment, plural=True) + + async def edit_comment( + self, + issue_id: str, + comment_id: str | int, + text: str, + attachment_ids: list[str] | None = None, + ) -> Comment: + """ + Use this method to edit comments. + + YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/edit-comment + """ + raw_response = await self._client.request( + method="PATCH", + uri=f"/issues/{issue_id}/comments/{comment_id}", + payload=CommentEdit( + text=text, + attachment_ids=attachment_ids, + ).model_dump(exclude_none=True, by_alias=True), + ) + return self._decode(raw_response, Comment) + + async def delete_comment( + self, + issue_id: str, + comment_id: str | int, + ) -> None: + """ + Use this method to delete issue comments. + + YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/delete-comment + """ + await self._client.request( + method="DELETE", + uri=f"/issues/{issue_id}/comments/{comment_id}", + ) diff --git a/ya_tracker_client/service/api.py b/ya_tracker_client/service/api.py index 73f12ec..e8cb6ba 100644 --- a/ya_tracker_client/service/api.py +++ b/ya_tracker_client/service/api.py @@ -1,6 +1,7 @@ from ya_tracker_client.domain.repositories import ( AttachmentRepository, ChecklistRepository, + CommentRepository, ComponentRepository, IssueRelationshipRepository, IssueRepository, @@ -13,6 +14,7 @@ class YaTrackerClient( AttachmentRepository, + CommentRepository, ChecklistRepository, ComponentRepository, IssueRelationshipRepository,