Coverage for scripts / list_requests.py: 20%
71 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-25 18:08 -0500
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-25 18:08 -0500
1#!/usr/bin/env python3
2"""
3List JSM service requests with filtering.
5Usage:
6 python list_requests.py --service-desk 1
7 python list_requests.py --service-desk "IT Support" --status "In Progress"
8 python list_requests.py --service-desk 1 --jql 'reporter=currentUser()'
9 python list_requests.py --service-desk 1 --output json
10"""
12import sys
13import os
14import argparse
15import json
16from pathlib import Path
17from typing import Optional, Dict, Any, List
19sys.path.insert(0, str(Path(__file__).parent.parent.parent / 'shared' / 'scripts' / 'lib'))
21from config_manager import get_jira_client
22from error_handler import print_error, JiraError
25def list_service_requests(service_desk_id: str, status: Optional[str] = None,
26 request_type: Optional[str] = None,
27 jql: Optional[str] = None,
28 max_results: int = 50, start_at: int = 0,
29 profile: Optional[str] = None) -> Dict[str, Any]:
30 """
31 List service requests.
33 Args:
34 service_desk_id: Service desk ID or project key
35 status: Filter by status
36 request_type: Filter by request type name
37 jql: Custom JQL filter
38 max_results: Maximum results to return
39 start_at: Pagination offset
40 profile: JIRA profile to use
42 Returns:
43 Search results with issues and total count
44 """
45 # Build JQL query
46 jql_parts = []
48 # Add service desk filter
49 jql_parts.append(f'project="{service_desk_id}"')
51 # Add status filter
52 if status:
53 jql_parts.append(f'status="{status}"')
55 # Add custom JQL
56 if jql:
57 jql_parts.append(f'({jql})')
59 final_jql = ' AND '.join(jql_parts)
61 with get_jira_client(profile) as client:
62 return client.search_issues(
63 jql=final_jql,
64 max_results=max_results,
65 start_at=start_at
66 )
69def format_table(issues: List[Dict[str, Any]]) -> str:
70 """Format issues as table."""
71 if not issues:
72 return "No requests found."
74 lines = []
75 lines.append(f"\n{'Key':<12} {'Summary':<40} {'Status':<20} {'Reporter'}")
76 lines.append("-" * 100)
78 for issue in issues:
79 key = issue.get('key', 'N/A')
80 fields = issue.get('fields', {})
82 summary = fields.get('summary', 'N/A')
83 if len(summary) > 37:
84 summary = summary[:37] + '...'
86 status = fields.get('status', {}).get('name', 'N/A')
88 reporter = fields.get('reporter', {})
89 reporter_email = reporter.get('emailAddress', 'N/A')
91 lines.append(f"{key:<12} {summary:<40} {status:<20} {reporter_email}")
93 return '\n'.join(lines)
96def format_json(issues: List[Dict[str, Any]]) -> str:
97 """Format issues as JSON."""
98 return json.dumps(issues, indent=2)
101def main():
102 """Main entry point."""
103 parser = argparse.ArgumentParser(
104 description='List JSM service requests',
105 formatter_class=argparse.RawDescriptionHelpFormatter,
106 epilog="""
107Examples:
108 List all requests:
109 %(prog)s --service-desk 1
111 Filter by status:
112 %(prog)s --service-desk 1 --status "In Progress"
114 Multiple statuses:
115 %(prog)s --service-desk 1 --jql 'status in ("In Progress", "Waiting for support")'
117 Current user's requests:
118 %(prog)s --service-desk 1 --jql 'reporter=currentUser()'
120 Pagination:
121 %(prog)s --service-desk 1 --max-results 50 --start-at 50
123 JSON output:
124 %(prog)s --service-desk 1 --output json
125 """
126 )
128 parser.add_argument('--service-desk', required=True,
129 help='Service desk ID or project key')
130 parser.add_argument('--status',
131 help='Filter by status')
132 parser.add_argument('--request-type',
133 help='Filter by request type name')
134 parser.add_argument('--jql',
135 help='Additional JQL filter')
136 parser.add_argument('--max-results', type=int, default=50,
137 help='Maximum results to return (default: 50)')
138 parser.add_argument('--start-at', type=int, default=0,
139 help='Pagination offset (default: 0)')
140 parser.add_argument('--output', choices=['text', 'json'], default='text',
141 help='Output format (default: text)')
142 parser.add_argument('--profile',
143 help='JIRA profile to use from config')
145 args = parser.parse_args()
147 try:
148 result = list_service_requests(
149 service_desk_id=args.service_desk,
150 status=args.status,
151 request_type=args.request_type,
152 jql=args.jql,
153 max_results=args.max_results,
154 start_at=args.start_at,
155 profile=args.profile
156 )
158 issues = result.get('issues', [])
159 total = result.get('total', 0)
161 if args.output == 'json':
162 print(format_json(issues))
163 else:
164 print(format_table(issues))
165 print(f"\nTotal: {total} requests")
167 if total > len(issues):
168 shown = len(issues)
169 remaining = total - shown - args.start_at
170 if remaining > 0:
171 print(f"Showing {shown} of {total} (use --start-at {args.start_at + shown} for next page)")
173 return 0
175 except JiraError as e:
176 print_error(f"Failed to list requests: {e}")
177 return 1
178 except Exception as e:
179 print_error(f"Unexpected error: {e}")
180 return 1
183if __name__ == '__main__':
184 sys.exit(main())