Coverage for scripts / get_request_comments.py: 17%

81 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-25 18:08 -0500

1#!/usr/bin/env python3 

2""" 

3Get comments for a JSM request with visibility information. 

4 

5This script retrieves comments from JSM requests, showing public/internal visibility. 

6Public comments are visible to customers in the portal, while internal comments 

7are only visible to agents. 

8""" 

9 

10import sys 

11import argparse 

12import json 

13from pathlib import Path 

14from datetime import datetime 

15 

16# Add shared lib to path 

17sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / 'shared' / 'scripts' / 'lib')) 

18 

19from config_manager import get_jira_client 

20from error_handler import handle_errors 

21 

22 

23def get_jira_client(profile=None): 

24 """Get JIRA client (overridable for testing).""" 

25 from config_manager import get_jira_client as _get_client 

26 return _get_client(profile) 

27 

28 

29def format_visibility(is_public: bool) -> str: 

30 """Format visibility as clear indicator.""" 

31 return "👁️ PUBLIC " if is_public else "🔒 INTERNAL" 

32 

33 

34def format_comments_table(comments: list) -> None: 

35 """Format comments as table with visibility indicators.""" 

36 if not comments: 

37 print("No comments found.") 

38 return 

39 

40 # Count public vs internal 

41 public_count = sum(1 for c in comments if c.get('public', True)) 

42 internal_count = len(comments) - public_count 

43 

44 print(f"\nComments ({len(comments)} total: {public_count} public, {internal_count} internal):\n") 

45 

46 print(f"{'ID':<10} {'Author':<20} {'Date':<20} {'Visibility':<12} {'Body'}") 

47 print("─" * 100) 

48 

49 for comment in comments: 

50 comment_id = comment.get('id', 'unknown') 

51 author = comment.get('author', {}).get('displayName', 'Unknown') 

52 created = comment.get('created', '') 

53 is_public = comment.get('public', True) 

54 body = comment.get('body', '').replace('\n', ' ')[:50] # First 50 chars 

55 

56 # Format date 

57 try: 

58 dt = datetime.fromisoformat(created.replace('Z', '+00:00')) 

59 date_str = dt.strftime('%Y-%m-%d %H:%M') 

60 except: 

61 date_str = created[:16] if created else 'Unknown' 

62 

63 visibility = "PUBLIC " if is_public else "INTERNAL" 

64 

65 print(f"{comment_id:<10} {author:<20} {date_str:<20} {visibility:<12} {body}...") 

66 

67 print("\nLegend:") 

68 print(" PUBLIC - Visible in customer portal") 

69 print(" INTERNAL - Agent-only, not visible to customers") 

70 

71 

72@handle_errors 

73def main(args=None): 

74 """Main function.""" 

75 parser = argparse.ArgumentParser( 

76 description='Get JSM request comments with visibility info', 

77 formatter_class=argparse.RawDescriptionHelpFormatter, 

78 epilog=""" 

79Examples: 

80 # All comments 

81 %(prog)s REQ-123 

82 

83 # Public comments only 

84 %(prog)s REQ-123 --public-only 

85 

86 # Internal comments only 

87 %(prog)s REQ-123 --internal-only 

88 

89 # Specific comment 

90 %(prog)s REQ-123 --id 10001 

91 

92 # JSON output 

93 %(prog)s REQ-123 --output json 

94 """ 

95 ) 

96 

97 parser.add_argument('issue_key', 

98 help='Request key (e.g., REQ-123)') 

99 parser.add_argument('--public-only', action='store_true', 

100 help='Show only public (customer-visible) comments') 

101 parser.add_argument('--internal-only', action='store_true', 

102 help='Show only internal (agent-only) comments') 

103 parser.add_argument('--id', 

104 help='Get specific comment by ID') 

105 parser.add_argument('--output', choices=['text', 'json'], default='text', 

106 help='Output format (default: text)') 

107 parser.add_argument('--all-pages', action='store_true', 

108 help='Fetch all pages (default: first 100)') 

109 parser.add_argument('--profile', 

110 help='JIRA profile to use') 

111 

112 parsed_args = parser.parse_args(args) 

113 

114 # Get JIRA client 

115 jira = get_jira_client(parsed_args.profile) 

116 

117 # Get specific comment by ID 

118 if parsed_args.id: 

119 comment = jira.get_request_comment(parsed_args.issue_key, parsed_args.id, expand=None) 

120 if parsed_args.output == 'json': 

121 print(json.dumps(comment, indent=2)) 

122 else: 

123 format_comments_table([comment]) 

124 return 0 

125 

126 # Determine visibility filter 

127 public_filter = None 

128 if parsed_args.public_only: 

129 public_filter = True 

130 elif parsed_args.internal_only: 

131 public_filter = False 

132 

133 # Get comments 

134 if parsed_args.all_pages: 

135 # Fetch all pages 

136 all_comments = [] 

137 start = 0 

138 limit = 100 

139 while True: 

140 response = jira.get_request_comments( 

141 parsed_args.issue_key, 

142 public=public_filter, 

143 start=start, 

144 limit=limit 

145 ) 

146 comments = response.get('values', []) 

147 all_comments.extend(comments) 

148 

149 if response.get('isLastPage', True): 

150 break 

151 start += limit 

152 

153 comments_data = all_comments 

154 else: 

155 # Single page 

156 response = jira.get_request_comments( 

157 parsed_args.issue_key, 

158 public=public_filter, 

159 start=0, 

160 limit=100 

161 ) 

162 comments_data = response.get('values', []) 

163 

164 # Output 

165 if parsed_args.output == 'json': 

166 print(json.dumps(comments_data, indent=2)) 

167 else: 

168 format_comments_table(comments_data) 

169 

170 return 0 

171 

172 

173if __name__ == '__main__': 

174 sys.exit(main())