# encoding:utf-8
# @Time : 2022/3/21
# @Author : TianChunpeng
# @FileName: Int_PostMail.py
# @function: send integration information to relevant personnel
import email.utils
import os
import smtplib
import re
import sys
import yagmail
import openpyxl
import subprocess
import requests
import pymysql
from dbutils.pooled_db import PooledDB, SharedDBConnection
import zipfile
Pool = PooledDB(
creator=pymysql,
maxconnections=6,
mincached=2,
maxcached=5,
maxshared=3,
blocking=True,
maxusage=None,
setsession=[],
ping=0,
host='127.0.0.1',
port=3306,
user='root',
password='123456',
db='int',
charset='utf8',
# cursorclass=pymysql.cursors.DictCursor
)
# 调用企业微信api,让机器人发送消息
def RobotPostInfo(content, receivers, url):
headers = {
'Content-Type': 'application/json',
}
# newreceivers = receivers.encode('utf-8').decode('latin1')
data = '{"msgtype": "text","text": {"content": "' + content + '","mentioned_list": [' + receivers + ']}}'
# 由于字符编码的问题会导致post请求中的中文无法识别,需要进行转码
# data = data.encode('utf-8').decode('latin1')
data = data.encode('utf-8')
response = requests.post(url, headers=headers, data=data)
print(response.text)
# 在路径中查找出对应的文件
def SearchFile(filename, dir):
for root, dirs, files in os.walk(dir):
if filename in files:
return os.path.join(root, filename)
# 根据出错文件到svn中寻找到对应的上传者
def GetSvnLog(prjname, prj_info, type, filelist):
# filedir = {}
# 集成任务书路径
task_dir = 'H:/Jenkins/集成任务书配置/' + prjname + '/集成任务书_' + prj_info[0] + '.xlsx'
# 服务器上svn的路径,与matlab中的设置的一致
svnroot = 'D:/SVNwork/'
# 读取集成任务书内容,为读取svnlog做准备
excel_obj = openpyxl.load_workbook(task_dir)
sheet = excel_obj.get_sheet_by_name('集成任务书')
if type == 'ASW':
filedir = []
sheetcell = sheet['B3']
logdir = svnroot + sheetcell.value
for i in range(0, len(filelist)):
filelist[i] = filelist[i] + '.slx'
filedir.append(SearchFile(filelist[i], logdir))
elif type == 'BSW':
logdir = []
filedir = []
sheetcell = sheet['B6']
bswdir = re.split('\\n+', sheetcell.value)
# print(bswdir[2])
for i in range(0, len(bswdir)):
logdir.append(svnroot + bswdir[i])
for i in range(0, len(filelist)):
for j in range(0, len(logdir)):
curfile = SearchFile(filelist[i], logdir[j])
if curfile is not None:
filedir.append(curfile)
elif type == 'lib':
filedir = ['']
sheetcell = sheet['B5']
sint = re.split('\\n+', sheetcell.value)
logdir = svnroot + sint[3] + '/' + filelist[0]
filedir[0] = logdir;
elif type == 'ld':
filedir = ['']
sheetcell = sheet['B5']
sint = re.split('\\n+', sheetcell.value)
logdir = svnroot + sint[2] + '/' + filelist[0]
filedir[0] = logdir;
# subprocess执行svn指令,获取svn输出
commiter = []
for x in filedir:
log_info = subprocess.run('svn log -v --limit 1 ' + x, shell=True, capture_output=True, text=True)
if log_info.stderr == '':
name = re.findall('\| (\w+)', log_info.stdout)
commiter.append(name[0])
else:
temp_list = []
x = re.sub('(_\w+)*\.c', '', x)
temp_list[0] = x
if type == 'BSW':
commiter += GetSvnLog(prjname, prj_info, 'ASW', temp_list)
else:
commiter.append('weipengkun')
return commiter
def sendmail(receivers, mail_content):
# get all user mailbox
db = Pool.connection()
cur = db.cursor()
cur.execute(
'SELECT username,mailbox FROM user'
)
user_list = cur.fetchall()
# send mail
mail_host = 'smtp.qiye.aliyun.com'
mail_user = '[email protected]'
mail_pass = 'Zpzn123456@'
# 接收者查询,根据svn的上传记录,
# 文件内容组成 : 项目名称 报错信息 网址链接 说明文字
mailbox = []
for name in receivers:
for elem in user_list:
if elem[0] == name:
mailbox.append(elem[1])
email_title = 'Integrate Info'
try:
yag_server = yagmail.SMTP(user=mail_user, password=mail_pass, host=mail_host)
yag_server.send(mailbox, email_title, mail_content)
yag_server.close()
print('success')
except smtplib.SMTPException as e:
print('error', e)
def copy_and_zip(prjname, version, source, dest):
sourceName = source + "\\" + prjname + "\\" + version
if not os.path.exists(source + "\\" + prjname):
os.mkdir(source + "\\" + prjname)
destName = dest + "\\" + prjname + "\\" + version + ".zip"
zip = zipfile.ZipFile(destName, "w", zipfile.ZIP_DEFLATED)
for path, dirnames, filenames in os.walk(sourceName):
# 去掉目标跟路径,只对目标文件夹下边的文件及文件夹进行压缩
fpath = path.replace(sourceName, '')
for filename in filenames:
zip.write(os.path.join(path, filename), os.path.join(fpath, filename))
zip.close()
# Build报错提取出文件名
# Model报错提取出模型名
# matlab报错返回‘matlab’
# 集成任务书报错直接返回‘集成任务书’
# 获取Jenkins中设置的项目参数,包含项目名称、项目经理
if __name__ == '__main__':
prjname = sys.argv[1]
prjmanager = sys.argv[2]
robot_wh = sys.argv[3]
# prjname = 'EQ02_2'
# prjname = 'EQ18B'
# prjmanager = 'xiepeiwen'
# robot_wh = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=d496f650-201c-4dbb-bcbb-7a1261097923'
source = "H:\Jenkins\BuildDir"
dlDir = "H:\Jenkins\download"
# prjname = 'TEST'
# prjmanager = 'tianchunpeng'
# robot_wh = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=283f7d1a-baca-4826-a85c-61c8dcb3d122'
# 每个项目同一时间只可以有一版程序集成,当集成报错时,将项目的集成文件路径写入文件中
# 集成文件中包含了报错文件
# 在集成环境中新添一个文件夹,用来管理当前集成的状态,文件中保存工程的名称和版本号,换行保存集成文件的地址
prj_file = open("H:\Jenkins\IntEnvPlat\other\\" + prjname + '.txt', 'r')
# prj_file = open("H:\Jenkins\IntEnvPlat\other\\STCU.txt", 'r')
prj_info = prj_file.read()
prj_info = re.split('[\r\n]+', prj_info)
os.chdir(prj_info[1])
# 从数据库中获取pid信息
db = Pool.connection()
cur = db.cursor()
cur.execute(
'SELECT EXISTS(SELECT version FROM projectversion WHERE version = (%s))', (prj_info[0],)
)
isexist = cur.fetchone()
if isexist[0] == 1:
cur.execute(
'SELECT pid FROM projectversion WHERE version = (%s)', (prj_info[0],)
)
pid = cur.fetchone()
if pid[0] != 'NULL':
os.system('taskkill /pid ' + pid[0] + ' -f')
# 不管是什么文件导致此次集成报错,以下只提取出文件的名称,将文件的名称传递到获取上传者时,再在svn中寻找到文件的路径,进行log的探索
# 若是模型的代码报错,不进行判断,只有找不到log时,递归一次进行模型的查找
# 针对不同类型的报错进行操作,确定邮件发送人和发送的内容
receivers = []
error_file = ['ErrorInfo.txt', 'ModelErrorInfo.txt', 'BuildErrorInfo.txt', 'matlab_ErrorInfo.txt', 'A2l_del.txt',
'Success.txt']
for x in error_file:
if os.path.exists(x) == False:
continue
setfile = x
file = open(x, 'r', encoding='gb18030', errors='ignore')
txt = file.read()
file.close()
if x == 'ErrorInfo.txt':
receivers.append(prjmanager)
mail_content = prj_info[0] + '集成任务书内容出错,请核对!\n' + txt
robot_content = prj_info[0] + '集成任务书报错啦,请项目经理查看邮件!'
# robot_wh = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=283f7d1a-baca-4826-a85c-61c8dcb3d122'
elif x == 'A2l_del.txt':
receivers.append(prjmanager)
delvar_name = re.findall('/\* Name\s+\*/\s+([\w\.\[\]]+)', txt)
mail_content = prj_info[0] + ' 生成A2l时存在被删除变量!\n' + ' , '.join(delvar_name)
robot_content = prj_info[0] + ' A2l中存在没有地址的变量,请查收邮件查看具体变量!'
copy_and_zip(prjname, prj_info[0], source, dlDir)
elif x == 'ModelErrorInfo.txt':
modelname = re.findall(": (\w+)", txt)
receivers += GetSvnLog(prjname, prj_info, 'ASW', modelname)
mail_content = prj_info[0] + '报错模型:' + '; '.join(modelname)
robot_content = prj_info[0] + '模型编译报错啦,请查收邮件!'
# 匹配svn中上传者,更新receivers
elif x == 'BuildErrorInfo.txt':
cfile = re.findall('\w+\.c', txt)
hfile = re.findall('\w+\.h', txt)
ofile = re.findall('\w+\.o', txt)
ldfile = re.findall('\w+\.ld|ldf|lsl|dld', txt)
libfile = re.findall('\w+\.a', txt)
if len(ofile):
for item in ofile:
cfile.append(re.sub('\.o', '.c', item))
if len(hfile):
cfile += hfile
if len(cfile):
cfile = list(set(cfile))
receivers += GetSvnLog(prjname, prj_info, 'BSW', cfile)
if len(ldfile):
ldfile = list(set(ldfile))
receivers += GetSvnLog(prjname, prj_info, 'ld', ldfile)
if len(libfile):
libfile = list(set(libfile))
receivers += GetSvnLog(prjname, prj_info, 'lib', libfile)
# 匹配svn中上传者,更新receivers
if len(receivers) == 0:
# receivers = ['weipengkun']
# robot_wh = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=283f7d1a-baca-4826-a85c-61c8dcb3d122'
receivers.append(prjmanager)
mail_content = prj_info[0] + '工程报错信息如下:\n' + txt
robot_content = prj_info[0] + '工程编译报错啦,请查收邮件查看具体报错信息!'
copy_and_zip(prjname, prj_info[0], source, dlDir)
elif x == 'matlab_ErrorInfo.txt':
receivers = ['weipengkun']
mail_content = prj_info[0] + '脚本报错啦!\n报错信息如下:\n' + txt
robot_content = prj_info[0] + '集成过程报错啦,请查收邮件查看具体报错信息!'
robot_wh = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=283f7d1a-baca-4826-a85c-61c8dcb3d122'
elif x == 'Success.txt':
receivers.append(prjmanager)
mail_content = prj_info[0] + '集成完成!'
robot_content = prj_info[0] + '集成成功啦!'
copy_and_zip(prjname, prj_info[0], source, dlDir)
os.remove(x)
# 发送邮件到指定人员
# 删除重复值
receivers = list(set(receivers))
print(receivers)
print(mail_content)
sendmail(receivers, mail_content)
# 企业微信发送消息,调用curl_robot.bat脚本
robot_receivers = []
for i in range(len(receivers)):
robot_receivers.append('"' + receivers[i] + '"')
RobotPostInfo(robot_content, ','.join(robot_receivers), robot_wh)
starttime = prj_info[2]
if setfile == 'Success.txt':
# if isexist[0] == 0:
# cur.execute(
# 'INSERT INTO projectversion(project,version,intstatus,startdate,finishdate,isrelease,bswstate,aswstate,pid) VALUES((%s),(%s),"complete",(%s),now(),"no","locked","locked","NULL")',
# (prjname, prj_info[0], starttime,)
# )
# else:
cur.execute(
'UPDATE projectversion SET intstatus="complete",finishdate=now(),pid="NULL" WHERE version=(%s)', (prj_info[0],)
)
cur.execute(
'UPDATE project SET intstaus="NI" WHERE id=(%s)', (prjname,)
)
exit_num = 0
else:
# robot_receivers = ["tianchunpeng","weipengkun"]
# 报错启动计时提醒功能
p = subprocess.Popen(['H:/Jenkins/Otherscript/Python/pyfile/dist/Int_RemindMesg/Int_RemindMesg.exe', prj_info[0], ','.join(receivers), robot_wh])
# p = os.system('python D:/Jenkins/Otherscript/Python/pyfile/Int_RemindMesg.py '+ prj_info[0]+' '+ ','.join(receivers)+ ' '+ robot_wh)
# if isexist[0] == 0:
# cur.execute(
# 'INSERT INTO projectversion(project,version,intstatus,startdate,finishdate,isrelease,bswstate,aswstate,pid) VALUES((%s),(%s),"ongoing",(%s),now(),"no","locked","locked",(%s))',
# (prjname, prj_info[0], starttime, p.pid)
# )
# else:
cur.execute(
'UPDATE projectversion SET finishdate=now(),pid=(%s) WHERE version=(%s)', (p.pid, prj_info[0],)
)
exit_num = 1
db.commit()
cur.close()
db.close()
sys.exit(exit_num)
python调用数据库的脚本是上面的代码,如何关闭停止使用数据库
最新发布