JIRA所有项目的任务看板

需求

利用JIRA创建看板,并且能自动刷新。

看板有三列,显示所有项目今天从处理中拖动到完成的任务,今天从待办拖动到处理中的任务,在处理中超过一天的任务

代码

注意,从JIRA服务器获取的信息时间是UTC时间,要么转换要么都使用UTC时间

from jira import JIRA
import json
import requests
import time
import datetime
from datetime import datetime

options = {'server': 'https://localhost:8080/'}
url = options['server']
loginData={
    "username": "bob",
    "password": "111111"
}

jsessionid = None
headers = {'Content-type': 'application/json'}
projectList = ['P1', 'P2', 'P3', 'P4']
projectOwner = {
    'P1':'zhou',
    'P2':'fu',
    'P3':'fang',
    'P4':'fu',
    'P5': 'zhou'
}

#根据对应story在对应项目里的状态,在pilot中设置相应的状态
issueTargetStatus = {
    'In Progress':21, # issue status is In progress
    'Done':31,
    'To Do':11,
    '开发环境已集成': 31,
    '预发布环境已集成':31,
    '测试完成待发布生产':31,
    '生产环境已集成': 31, # done status
}


def loginJira():
    # Login and get session id
    urlLogin = url + "rest/auth/1/session"
    data_json = json.dumps(loginData)
    loginResponse = requests.post(urlLogin, data=data_json, headers=headers)
    global jsessionid
    jsessionid = json.loads(loginResponse.text)['session']['value']

def updateIssueStatus(issueId, targetStatusId):
    requestBody = {
    "update": {
        "comment": [
            {
                "add": {
                    "body": ""
                }
            }
        ]
    },
    "transition": {
        "id": targetStatusId
    }
    }

    updateIssueStatus = url + 'rest/api/2/issue/' + issueId + '/transitions?expand=transitions.fields'
    cookies = {'JSESSIONID': jsessionid}
    requestResponse = requests.post(updateIssueStatus, cookies=cookies, data=json.dumps(requestBody), headers=headers)
    print(requestResponse.status_code)

def createIssueInSprint(summary, link, assignee):
    #sprint 1 id is 51, hardcoded
    requestBody = {
    "fields": {
       "project":
       {
          "key": 'TASKBOARD'
       },
       "summary": summary,
       "description": link,
       "issuetype": {
          "name": "任务"
       },
       "customfield_10104": 51,
       "assignee":{
        "name":assignee
        }
    }

    }

    createIssueUrl = url + "rest/api/2/issue"
    cookies = {'JSESSIONID': jsessionid}
    requestResponse = requests.post(createIssueUrl, cookies=cookies, data=json.dumps(requestBody), headers=headers)
    print(requestResponse.status_code)
    return json.loads(requestResponse.text)['key']

def deleteAllIssues():
    jira = JIRA(options, basic_auth=(loginData['username'], loginData['password']))
    allStories = jira.search_issues('project = TASKBOARD AND issuetype in ( Task, 任务) and sprint in openSprints()', maxResults=1000)

    cookies = {'JSESSIONID': jsessionid}
    for story in allStories:
        deleteStoryUrl = url + "rest/api/2/issue/" + str(story)
        deleteStoryResponse = requests.delete(deleteStoryUrl, cookies=cookies, headers=headers)

#获取所有不在Todo或者Open状态的task
def listAllTasks():

    rt = {}

    jira = JIRA(options, basic_auth=(loginData['username'], loginData['password']))

    for project in projectList:
        print()
        allTasks = jira.search_issues('project = ' + project + ' AND issuetype in ( 任务, Task) and sprint in openSprints()', maxResults=1000)
        for task in allTasks:
            cookies = {'JSESSIONID': jsessionid}
            # urlIssueDetails = url + "rest/agile/1.0/issue/NSM-116?expand=changelog"
            urlIssueDetails = url + "rest/agile/1.0/issue/" + str(task) + "?expand=changelog"
            getIssueDetailsResponse = requests.get(urlIssueDetails, cookies=cookies, headers=headers)

            issueDetails = json.loads(getIssueDetailsResponse.text)
            # print(issueDetails)
            starInprogressTime = None
            finishInprogressTime = None

            if str(task.fields.status) != 'Open':
                for i in issueDetails['changelog']['histories']:
                    if (str(i['items'][0]['fromString']) == 'Open' and str(i['items'][0]['toString'] == 'In Progress')) or (str(i['items'][0]['fromString']) == 'To Do' and str(i['items'][0]['toString'] == 'In Progress')):
                        if starInprogressTime == None or i['created'] > starInprogressTime:  # 要么只有一次修改记录,要么有多次修改记录
                            starInprogressTime = i['created']
                            # print("start progress: " + starInprogressTime)

                    if (str(i['items'][0]['fromString']) == 'In Progress' and str(i['items'][0]['toString'] == '开发环境已集成')) or (str(i['items'][0]['fromString']) == 'In Progress' and str(i['items'][0]['toString'] == 'Done')):
                        if finishInprogressTime == None or i['created'] > finishInprogressTime:
                            finishInprogressTime = i['created']
                            # print("finish progress: " + finishInprogressTime)

            rt.update({str(task): {"start": starInprogressTime, "finish": finishInprogressTime, "project": project, "summary": task.fields.summary, "status":str(task.fields.status)}})
    print(rt)
    return rt


def copyTasksInOpenSprintAndSetStatus():
    taskList = listAllTasks()
    todayMorning = datetime.utcnow().strftime('%Y-%m-%d')+ " 00:00:00"  # utc 当天早上零点零分

    for task, taskDetails in taskList.items():
        print(task)
        print(taskDetails)

        link = 'https://localhost:8080/browse/' + str(task)
        #如果状态是完成或已部署到开发环境,并且拖动的时间是今天,则创建
        if (taskDetails['status'] == 'Done' or taskDetails['status'] == '开发环境已集成'):
            if str2date(taskDetails['finish']) > str2date(todayMorning):
                #创建
                newlyCreatedStoryId = createIssueInSprint('【' + taskDetails['project'] + '】' + taskDetails['summary'], link, projectOwner[taskDetails['project']])
                #设置状态为完成
                updateIssueStatus(newlyCreatedStoryId, issueTargetStatus[taskDetails['status']])
        #如果状态是处理中,并且拖动到处理中的时间是今天,则创建
        if(taskDetails['status'] == 'In Progress'):
            if str2date(taskDetails['start']) > str2date(todayMorning):
                newlyCreatedStoryId = createIssueInSprint('【' + taskDetails['project'] + '】' + taskDetails['summary'], link, projectOwner[taskDetails['project']])
                updateIssueStatus(newlyCreatedStoryId, issueTargetStatus[taskDetails['status']])
            #如果状态是处理中,并且拖动到处理中的时间不是今天,则计算是否超过一天,超过一天则创建
            if str2date(taskDetails['start']) < str2date(todayMorning):
                # 如果当前时间减去拖动到处理中的时间超过1天,则创建
                if (int(datetime.utcnow().timestamp() - str2date(taskDetails['start'])) - 86400) >=0 :
                    newlyCreatedStoryId = createIssueInSprint('【' + taskDetails['project'] + '】' + taskDetails['summary'], link, projectOwner[taskDetails['project']])


def str2date(issueDate):
    # return seconds
    rt = None
    if '000+0800' in issueDate:
        print(issueDate)
        rt = time.mktime(time.strptime(issueDate.replace('T', ' ').replace('.000+0800', ''), "%Y-%m-%d %H:%M:%S"))
    else:
        rt = time.mktime(time.strptime(issueDate.replace('T', ' ').replace('.000+0000', ''), "%Y-%m-%d %H:%M:%S"))
    return int(rt)


if __name__ == '__main__':
    print('started...')
    loginJira()
    deleteAllIssues()
    copyTasksInOpenSprintAndSetStatus()

页面自动刷新

方法有两种:
方式一:用selenium加载一个或者多个页面自动刷新。
方式二:使用浏览器插件,让浏览器自动刷新,还能在多个TAB之间幻灯片轮播,比如使用Tab Rotator by David Fichtmueller(firefox extension)

你可能感兴趣的:(JIRA所有项目的任务看板)