Files
qiaoxinjiu 6994b185a3 addproject
2026-01-22 19:10:37 +08:00

332 lines
17 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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()