1 from jira import JIRA
2 from jira.resources import Issue
3 import datetime
4
5 """
6 pip install jira
7 """
8
9
10 class JIRATool(object):
11 def __init__(self, server: str, username: str, password: str, project: str = 'NET', root_issue: str = 'NET-15',
12 fix_version: str = None):
13 """
14 :param server:
15 :param username:
16 :param password:
17 :param project:
18 :param root_issue:
19 :param fix_version:
20 Usage:
21 # >>> #server = 'https://jira.xpaas.lenovo.com'
22 # >>> #root_issue = 'NET-834'
23 # >>> fix_version = 'FY1819'
24 # >>> fix_version = 'CWN1920'
25 # >>> description = 'Sub-task of %s test JIRA api' % root_issue
26 # >>> assignee = 'luoyj2'
27 # >>> summary = 'GSD331'
28 # >>> username = 'username'
29 # >>> password = 'password'
30 # >>> j = JIRATool(server, username, password, project='project', root_issue=root_issue, fix_version='')
31 # >>> issue = j.create_issue(description, assignee, summary, self_watch=False, attachment='screenshots.py')
32 # >>> for i in ['881', '882', '883', '884']:
33 # >>> iss = j.find_issue_by_id('NET-'+i)
34 # >>> print(j.delete_issue(iss))
35 # >>> for k, v in j.find_issue_by_id('NET-30').raw.get('fields').items():
36 # >>> if k.startswith('customfield_'):
37 # >>> continue
38 # >>> print(k, v)
39 """
40 self.server = server
41 self.username = username
42 self.basic_auth = (username, password)
43 self.project = project
44 self.root_issue = root_issue
45 self.fix_version = fix_version
46 self.due_date = str(datetime.date.today() + datetime.timedelta(days=30))
47 self.client = JIRA(server=self.server, basic_auth=self.basic_auth, options=dict(verify=False))
48
49 def find_issue_by_id(self, issue_id: str):
50 """
51 :param issue_id: 'NET-15'
52 :return: issue
53 """
54 if issue_id:
55 return self.client.issue(issue_id)
56 else:
57 return None
58
59 def create_issue(
60 self, description: str, assignee: str, summary: str, issuetype: str = 'Sub-task', component: str = 'Devops',
61 self_watch: bool = True, attachment: str = '', labels: str = None
62 ):
63
64 """
65 :param description:
66 :param assignee:
67 :param summary:
68 :param issuetype
69 :param component:
70 :param self_watch: True or False
71 :param attachment: filename
72 :param labels
73 :return: issue object
74 """
75
76 issue_dict = {
77 'project': {'key': self.project},
78 'issuetype': {'name': issuetype},
79 'parent': {'key': self.root_issue},
80 'summary': summary,
81 'description': description,
82 'assignee': {'name': assignee},
83 'priority': {'name': 'Medium'},
84 'duedate': self.due_date
85 }
86 if self.fix_version:
87 issue_dict.update(fixVersions=[{'name': self.fix_version}])
88 if component:
89 issue_dict.update(components=[{'name': component}])
90
91 issue = self.client.create_issue(DataConverter(issue_dict).convert())
92 if labels:
93 try:
94 if isinstance(labels, (list, tuple)):
95 for label in labels:
96 issue.add_field_value('labels', label)
97 elif isinstance(labels, (str, bytes)):
98 issue.add_field_value('labels', labels)
99 except Exception as e:
100 pass
101
102 self.client.assign_issue(issue, assignee)
103 if isinstance(attachment, (str, bytes)) and os.path.exists(attachment):
104 self.client.add_attachment(issue, attachment)
105 if not self_watch:
106 self.client.remove_watcher(issue, self.username)
107 self.remove_watcher(issue, self.username)
108 return issue
109
110 def delete_issue(self, issue: Issue):
111 """
112 :param issue: 'NET-15' or jira.resources.Issue object
113 :return:
114 """
115 if not isinstance(issue, Issue):
116 issue = self.find_issue_by_id(issue)
117 if issue:
118 issue.delete()
119 return True
120 return False
121
122 def add_watcher(self, issue: Issue, watchers: list):
123 """
124 :param issue: 'NET-15' or jira.resources.Issue object
125 :param watchers: ['xxx', 'xxx'] or 'xxx'
126 :return:
127 """
128 if issue and watchers:
129 if isinstance(watchers, (str, bytes)):
130 watchers = [watchers]
131 for watcher in watchers:
132 if self.client.search_users(user=watcher):
133 self.client.add_watcher(issue=issue, watcher=watcher)
134
135 def remove_watcher(self, issue: Issue, watchers: list):
136 """
137 :param issue: 'NET-15' or jira.resources.Issue object
138 :param watchers: ['xxx', 'xxx'] or 'xxx'
139 :return:
140 """
141 if isinstance(watchers, (str, bytes)):
142 watchers = [watchers]
143 issue_watchers = self.client.watchers(issue)
144 for watcher in watchers:
145 try:
146 issue_watchers.delete(watcher)
147 except:
148 pass