addproject
This commit is contained in:
331
zhyy/library/CommonFun/handle_jira.py
Normal file
331
zhyy/library/CommonFun/handle_jira.py
Normal file
@@ -0,0 +1,331 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
人员当日jira任务、故事状态流转
|
||||
"""
|
||||
import os, sys
|
||||
|
||||
file_dir = os.path.dirname(__file__)
|
||||
project_dir = os.path.abspath(os.path.join(file_dir, "..", "..", ".."))
|
||||
sys.path.append(project_dir)
|
||||
|
||||
from jira import JIRA
|
||||
from base_framework.public_tools.utils import Tools
|
||||
from base_framework.public_tools.read_config import ReadConfig
|
||||
from base_framework.platform_tools.Message_service.Feishu_api import FeiShuMessage,get_user_name_by_email_prefix,get_feishu_config_value
|
||||
from configparser import ConfigParser
|
||||
from base_framework.base_config.current_pth import *
|
||||
import datetime
|
||||
|
||||
tools = Tools()
|
||||
ReadConfig = ReadConfig(filename=la_config_path)
|
||||
FS_INFO = [{"team": "TO", "users": "wuyonggang,xuwenjun,luohong"},
|
||||
{"team": "TO-RD", "users": "fengtian,guosongchao,zhaoxiaofang,"
|
||||
"zhuliang,majincheng,gaozhijun,liuxuegang,"
|
||||
"zhangxiong"},
|
||||
{"team": "USER-FE", "users": "zhaofei,liuxinlin,qingchen,yefei,xiangming,jianghao,jianglingmin,xuchangle,"
|
||||
"libaicheng,gouyuheng,jixiang.dong,baiyang01"}
|
||||
]
|
||||
|
||||
|
||||
class JiraApi:
|
||||
def __init__(self):
|
||||
self.jira = JIRA(server='https://jira.bg.huohua.cn/',
|
||||
basic_auth=("wuyonggang", "Mima@123"))
|
||||
|
||||
def close_jira_subtask(self, user_name):
|
||||
"""
|
||||
功能: 关闭指定人员名下当天结束的子任务
|
||||
请求参数 user_name (指定人员jira登录名,type: list)
|
||||
"""
|
||||
bad_name = []
|
||||
right_name = []
|
||||
for j in user_name:
|
||||
if j not in ReadConfig.get_sections():
|
||||
bad_name.append(j)
|
||||
elif j in ReadConfig.get_sections():
|
||||
right_name.append(j)
|
||||
success = []
|
||||
false = []
|
||||
today_time = tools.get_format_date(r_type=1)
|
||||
work_start_time = datetime.datetime.strptime('{0} 10:00:00'.format(today_time), '%Y-%m-%d %H:%M:%S')
|
||||
for name in right_name:
|
||||
jira = JIRA(server='https://jira.bg.huohua.cn/', basic_auth=(name, ReadConfig.get_value(name, 'password')))
|
||||
jql = 'project = HHC AND issuetype = 子任务 AND status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计,' \
|
||||
' 产品需求内审, 需求评审, 排期, 执行, 开发, 待测试, QA测试, SIM验证, 验证中, 待办, 处理中, 关闭) AND resolution = Unresolved' \
|
||||
' AND (QA in ({0}) OR assignee in ({1})) ORDER BY priority DESC, updated DESC'.format(name,name)
|
||||
issues = jira.search_issues(jql, fields='')
|
||||
# if len(issues) == 0: break
|
||||
not_need_closed = 0
|
||||
for i in issues:
|
||||
s = list(jira.transitions(i))
|
||||
close_status_id = [x['id'] for x in s if x['name'] == '关闭']
|
||||
if str(i.fields.status) == '处理中':
|
||||
if i.fields.aggregatetimeestimate != None:
|
||||
if i.fields.aggregatetimeestimate > 28800:
|
||||
jira.add_worklog(i, timeSpent='7', started=work_start_time)
|
||||
elif 0 < i.fields.aggregatetimeestimate <= 28800:
|
||||
jira.add_worklog(i, timeSpent='{0}'.format(i.fields.aggregatetimeestimate / 3600),
|
||||
started=work_start_time)
|
||||
else:
|
||||
jira.add_worklog(i, timeSpent='8', started=work_start_time)
|
||||
if str(i.fields.status) == '处理中' and str(i.fields.customfield_13406) == today_time:
|
||||
jira.transition_issue(i, int(close_status_id[0]))
|
||||
else:
|
||||
not_need_closed += 1
|
||||
issues2 = jira.search_issues(jql, fields='')
|
||||
if not_need_closed == len(issues2):
|
||||
success.append(name)
|
||||
else:
|
||||
false.append(name)
|
||||
return "{0}今日结束的子任务已关闭成功; {1}今日结束的子任务关闭失败; {2}没有进行账号配置".format(success, false, bad_name)
|
||||
|
||||
def start_jira_subtask(self, user_name):
|
||||
"""
|
||||
功能: 将待开始为今天的子任务状态流转为“处理中”
|
||||
请求参数 user_name (指定人员jira登录名,type: list)
|
||||
"""
|
||||
bad_name = []
|
||||
right_name = []
|
||||
for j in user_name:
|
||||
if j not in ReadConfig.get_sections():
|
||||
bad_name.append(j)
|
||||
elif j in ReadConfig.get_sections():
|
||||
right_name.append(j)
|
||||
success = []
|
||||
false = []
|
||||
for name in right_name:
|
||||
jira = JIRA(server='https://jira.bg.huohua.cn/', basic_auth=(name, ReadConfig.get_value(name, 'password')))
|
||||
jql = 'project = HHC AND issuetype = 子任务 AND status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计, 产品需求内审, 需求评审, ' \
|
||||
'排期, 执行, 开发, 待测试, QA测试, SIM验证, 验证中, 待办, 关闭) AND resolution = Unresolved' \
|
||||
' AND (QA in ({0}) OR assignee in ({1})) ORDER BY priority DESC, updated DESC'.format(name,name)
|
||||
today_time = tools.get_format_date(r_type=1)
|
||||
issues = jira.search_issues(jql, fields='')
|
||||
# if len(issues) == 0: break
|
||||
not_need_update = 0
|
||||
for i in issues:
|
||||
s = list(jira.transitions(i))
|
||||
start_status_id = [x['id'] for x in s if x['name'] == '处理中']
|
||||
if str(i.fields.status) == '待办' and str(i.fields.customfield_12700) == today_time:
|
||||
jira.transition_issue(i, int(start_status_id[0]))
|
||||
else:
|
||||
not_need_update += 1
|
||||
issues2 = jira.search_issues(jql, fields='')
|
||||
if not_need_update == len(issues2):
|
||||
success.append(name)
|
||||
else:
|
||||
false.append(name)
|
||||
return "{0}今日开始的子任务已将状态修改为“处理中”‘; {1}今日开始的子任务状态修改失败; {2}没有进行账号配置".format(success, false, bad_name)
|
||||
|
||||
def change_story(self, user_name, type):
|
||||
"""
|
||||
功能: 将提测时间为今天的指定人员名下的故事状态修改至“QA测试”
|
||||
请求参数 user_name (指定人员jira登录名,type: list)
|
||||
type (故事需要修改至的状态 1:提测日为今天,状态修改至【QA测试】 2:上线日为今天,状态修改至【关闭】)
|
||||
"""
|
||||
bad_name = []
|
||||
right_name = []
|
||||
for j in user_name:
|
||||
if j not in ReadConfig.get_sections():
|
||||
bad_name.append(j)
|
||||
elif j in ReadConfig.get_sections():
|
||||
right_name.append(j)
|
||||
success = []
|
||||
false = []
|
||||
for name in right_name:
|
||||
jira = JIRA(server='https://jira.bg.huohua.cn/', basic_auth=(name, ReadConfig.get_value(name, 'password')))
|
||||
jql = "project = HHC AND issuetype = 故事 AND " \
|
||||
"status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计, 产品需求内审, 需求评审, 排期, 执行, 开发, 待测试, 验证中, 待办, QA测试, SIM验证, 处理中, 关闭)" \
|
||||
" AND resolution = Unresolved AND QA in ({0}) ORDER BY priority DESC, updated DESC".format(name)
|
||||
today_time = tools.get_format_date(r_type=1)
|
||||
issues = jira.search_issues(jql, fields='')
|
||||
# if len(issues) == 0 : break
|
||||
x = 0
|
||||
need_update = 0
|
||||
if type == 1: # 将故事状态一直流转至“QA测试”
|
||||
for i in issues:
|
||||
if str(i.fields.status) == 'QA测试' or str(i.fields.status) == 'SIM验证': need_update += 1
|
||||
if str(i.fields.customfield_10504) == today_time:
|
||||
if str(i.fields.status) != 'QA测试' and str(i.fields.status) != 'SIM验证':
|
||||
need_update += 1
|
||||
for j in range(8):
|
||||
jira.transition_issue(i, int(jira.transitions(i)[2]['id']))
|
||||
issues_2 = jira.search_issues(jql, fields='') # 重新获取所有故事
|
||||
status_now = issues_2[x].fields.status
|
||||
print(status_now)
|
||||
if str(status_now) == 'QA测试' or str(status_now) == 'SIM验证':
|
||||
break
|
||||
x += 1
|
||||
jql2 = "project = HHC AND issuetype = 故事 AND " \
|
||||
"status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计, 产品需求内审, 需求评审, 排期, 执行, 开发, 待测试, 验证中, 待办, 处理中, 关闭)" \
|
||||
" AND resolution = Unresolved AND QA in ({0}) ORDER BY priority DESC, updated DESC".format(name)
|
||||
issues2 = jira.search_issues(jql2, fields='')
|
||||
if len(issues2) == len(issues) - need_update:
|
||||
success.append(name)
|
||||
else:
|
||||
false.append(name)
|
||||
elif type == 2: # 直接将故事关闭
|
||||
for i in issues:
|
||||
if str(i.fields.customfield_10606) == today_time:
|
||||
jira.transition_issue(i, int(jira.transitions(i)[1]['id']), comment="已上线") # 将故事修改为关闭状态
|
||||
need_update += 1
|
||||
issues2 = jira.search_issues(jql, fields='')
|
||||
if len(issues2) + need_update == len(issues):
|
||||
success.append(name)
|
||||
else:
|
||||
false.append(name)
|
||||
|
||||
return "{0}今日的故事已将状态修改成功!; {1}今日的故事状态修改失败; {2}没有进行账号配置".format(success, false, bad_name)
|
||||
|
||||
def change_jira_status(self, user_name):
|
||||
"""
|
||||
功能: 判断当前时间是否在下午18:00点以前,来选择打开或关闭【子任务】和【故事】
|
||||
请求参数 user_name (指定人员jira登录名,type: list)
|
||||
"""
|
||||
time_now = tools.get_format_date(r_type=4)
|
||||
time_now2 = '{0} 18:00:00'.format(time_now[0:10:1])
|
||||
if time_now < '{0} 18:00:00'.format(time_now2):
|
||||
a = self.start_jira_subtask(user_name)
|
||||
b = self.change_story(user_name, type=1)
|
||||
return a + '\n' + b
|
||||
elif time_now >= '{0} 18:00:00'.format(time_now2):
|
||||
a = self.close_jira_subtask(user_name)
|
||||
b = self.change_story(user_name, type=2)
|
||||
return a + '\n' + b
|
||||
|
||||
def query_jira_subtask(self, user_name, begin_date=0, end_date=0):
|
||||
"""
|
||||
| 功能 | 查询用户对应的jira子任务 |
|
||||
| 入参 | user_name | 用户名字 |
|
||||
| | begin_date | 开始时间:0-今天,X-未来X天,-X-过去的X天 |
|
||||
| | end_date | 开始时间:0-今天,X-未来X天,-X-过去的X天 |
|
||||
"""
|
||||
b_date = tools.get_format_date(r_type=1, add_days=int(begin_date))
|
||||
e_date = tools.get_format_date(r_type=1, add_days=int(end_date))
|
||||
jql = "issuetype = 子任务 AND 计划开始时间 <= {} AND 计划结束时间 >= {} AND assignee in ({}) ORDER BY cf[12700] ASC"\
|
||||
.format(b_date, e_date, user_name)
|
||||
issues = self.jira.search_issues(jql, fields='')
|
||||
# print(jql)
|
||||
return issues
|
||||
# for item in issues:
|
||||
# print("{0}:{1}, 当前状态:{2}".format(item.key, item.fields.summary, item.fields.status))
|
||||
|
||||
def query_jira_by_id(self, jira_id):
|
||||
"""
|
||||
| 功能 | 跟进jira的id查询具体详情 |
|
||||
| 入参 | jira_id | jira的id |
|
||||
"""
|
||||
jql = "id={}".format(jira_id)
|
||||
issues = self.jira.search_issues(jql, fields='')
|
||||
if len(issues) == 0:
|
||||
raise Exception("根据jira_id未查询到对应的jira信息,请检查....")
|
||||
rd = issues[0].fields.assignee.displayName
|
||||
qa = issues[0].fields.reporter.displayName
|
||||
title = issues[0].fields.summary
|
||||
status = issues[0].fields.status
|
||||
j_time = issues[0].fields.created
|
||||
j_time = j_time[0:10] + ' ' + j_time[11:19]
|
||||
return {"jira_rd": rd,
|
||||
"jira_qa": qa,
|
||||
"jira_title": title,
|
||||
"jira_time": j_time,
|
||||
"jira_status": str(status)}
|
||||
|
||||
def query_overdue_issues(self, user_name):
|
||||
"""
|
||||
| 功能 | 查询逾期的子任务和故事 |
|
||||
| 入参 | 无 |
|
||||
"""
|
||||
today = tools.get_format_date()
|
||||
check_time = tools.get_format_date(r_type=4)
|
||||
if check_time < "{} 17:00:00".format(today):
|
||||
jql = "issuetype in (故事,子任务) AND (计划结束时间<now() OR 计划上线时间<now()) AND status!=关闭 AND " \
|
||||
"(assignee={0} OR QA={0})".format(user_name)
|
||||
else:
|
||||
jql = "issuetype in (故事,子任务) AND (计划结束时间<=now() OR 计划上线时间<=now()) AND status!=关闭 AND " \
|
||||
"(assignee={0} OR QA={0})".format(user_name)
|
||||
issues = self.jira.search_issues(jql, fields='')
|
||||
return issues
|
||||
|
||||
def check_overdue_issues(self):
|
||||
"""检查预期未关闭的故事和子任务"""
|
||||
today = tools.get_format_date()
|
||||
fs = FS_INFO[0]
|
||||
user_list = fs['users'].split(',')
|
||||
remind_info = []
|
||||
for user in user_list:
|
||||
issues = self.query_overdue_issues(user_name=user)
|
||||
if issues:
|
||||
for issue in issues:
|
||||
issue_info = [user, issue.key]
|
||||
remind_info.append(issue_info)
|
||||
if remind_info:
|
||||
msg = "【JIRA任务延期提醒{}】:\n".format(today)
|
||||
for info in remind_info:
|
||||
user_name = get_user_name_by_email_prefix(email_prefix=info[0])
|
||||
open_id = get_feishu_config_value(option_key=user_name)
|
||||
at_msg = " |--<at user_id='{}'>{}</at>".format(open_id, user_name)
|
||||
msg = msg + at_msg + ": https://jira.bg.huohua.cn/browse/{}\n".format(info[1])
|
||||
msg = msg + " |--请及时关闭以上逾期任务..."
|
||||
print(msg)
|
||||
fs = FeiShuMessage(team=fs['team'])
|
||||
fs.send_text(msg=msg)
|
||||
else:
|
||||
print("++++++++++++++++++++++")
|
||||
print("| 所有任务或故事均已关闭 |")
|
||||
print("++++++++++++++++++++++")
|
||||
|
||||
def check_pdp_standard(self):
|
||||
"""查找当天有无子任务,没有则发送飞书消息提醒"""
|
||||
# 非工作日构建
|
||||
today = tools.get_format_date()
|
||||
if not tools.check_the_date_is_a_working_day(today):
|
||||
print("### 非工作日,不检查....")
|
||||
return False
|
||||
|
||||
for fs in FS_INFO:
|
||||
user_list = fs['users'].split(',')
|
||||
need_remind_user = []
|
||||
for user in user_list:
|
||||
issues = self.query_jira_subtask(user_name=user)
|
||||
if not issues:
|
||||
need_remind_user.append(user)
|
||||
if need_remind_user:
|
||||
msg = "【JIRA子任务提醒{}】:\n |--".format(today)
|
||||
for user in need_remind_user:
|
||||
user_name = get_user_name_by_email_prefix(email_prefix=user)
|
||||
open_id = get_feishu_config_value(option_key=user_name)
|
||||
at_msg = "<at user_id='{}'>{}</at>".format(open_id, user_name)
|
||||
msg = msg + at_msg
|
||||
msg = msg + "\n |--请及时添加与今日工作对应的子任务哦..."
|
||||
print(msg)
|
||||
fs = FeiShuMessage(team=fs['team'])
|
||||
fs.send_text(msg=msg)
|
||||
else:
|
||||
print("++++++++++++++++++++++++++++++++")
|
||||
print("| {} 满足pdp规范,无须提示 |".format(fs['team']))
|
||||
print("++++++++++++++++++++++++++++++++")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# 关闭自动修改jira的代码,不要再打开了...
|
||||
# lp = Jira_About()
|
||||
# print(lp.change_jira_status(['liupeng', 'zhourenhua', 'xuwenjun', 'lichao04', 'wanggang02', 'baoli']))
|
||||
|
||||
# 以下内容若有修改,请勿上传,否则会影响jira监控的每日构建
|
||||
# 1.获取命令行参数
|
||||
cmd_params = sys.argv
|
||||
try:
|
||||
index = cmd_params.index('-t')
|
||||
except ValueError:
|
||||
raise Exception("类型参数必填:pdp-检查PDP规范,overdue-检查预期未关闭的故事和子任务....")
|
||||
else:
|
||||
check_type = cmd_params[index + 1]
|
||||
if check_type.lower() not in ("pdp", "overdue"):
|
||||
raise Exception("目前仅支持pdp和overdue,但你输入的是:{}".format(check_type))
|
||||
|
||||
jira = JiraApi()
|
||||
if check_type.lower() == "pdp":
|
||||
jira.check_pdp_standard()
|
||||
elif check_type.lower() == "overdue":
|
||||
jira.check_overdue_issues()
|
||||
Reference in New Issue
Block a user