Coverage for src/mcp_atlassian/confluence/comments.py: 88%

1"""Module for Confluence comment operations."""

2

3 import logging

4

5 import requests

6

7 from ..document_types import Document

8 from .client import ConfluenceClient

9

10 logger = logging.getLogger("mcp-atlassian")

11

12

13 class CommentsMixin(ConfluenceClient):

14 """Mixin for Confluence comment operations."""

15

16 def get_page_comments(

17 self, page_id: str, *, return_markdown: bool = True

18 ) -> list[Document]:

19 """

20 Get all comments for a specific page.

21

22 Args:

23 page_id: The ID of the page to get comments from

24 return_markdown: When True, returns content in markdown format,

25 otherwise returns raw HTML (keyword-only)

26

27 Returns:

28 List of Document objects containing comment content and metadata

29 """

30 try:

31 # Get page info to extract space details

32 page = self.confluence.get_page_by_id(page_id=page_id, expand="space")

33 space_key = page.get("space", {}).get("key", "")

34 space_name = page.get("space", {}).get("name", "")

35

36 # Get comments with expanded content

37 comments = self.confluence.get_page_comments(

38 content_id=page_id, expand="body.view.value,version", depth="all"

39 )["results"]

40

41 comment_documents = []

42 for comment in comments:

43 body = comment["body"]["view"]["value"]

44 processed_html, processed_markdown = self._process_html_content(

45 body, space_key

46 )

47

48 # Get author information from version.by instead of author

49 author = comment.get("version", {}).get("by", {})

50

51 metadata = {

52 "page_id": page_id,

53 "comment_id": comment["id"],

54 "last_modified": comment.get("version", {}).get("when"),

55 "type": "comment",

56 "author_name": author.get("displayName"),

57 "space_key": space_key,

58 "space_name": space_name,

59 }

60

61 comment_documents.append(

62 Document(

63 page_content=processed_markdown

64 if return_markdown

65 else processed_html,

66 metadata=metadata,

67 )

68 )

69

70 return comment_documents

71

72 except KeyError as e:

73 logger.error(f"Missing key in comment data: {str(e)}")

74 return []

75 except requests.RequestException as e:

76 logger.error(f"Network error when fetching comments: {str(e)}")

77 return []

78 except (ValueError, TypeError) as e:

79 logger.error(f"Error processing comment data: {str(e)}")

80 return []

81 except Exception as e: # noqa: BLE001 - Intentional fallback with full logging

82 logger.error(f"Unexpected error fetching comments: {str(e)}")

83 logger.debug("Full exception details for comments:", exc_info=True)

84 return []