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