代码拉取完成,页面将自动刷新
同步操作将从 WisdIOT/AIOTEC 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
from io import BytesIO
import xlsxwriter
import pandas as pd
from flask import make_response, request, jsonify
import pymysql.cursors
from datetime import datetime
import uuid
import numpy as np
from configparser import ConfigParser
import os
import requests
import logging
# 读取配置文件
conf = ConfigParser()
conf.read("setting.ini", encoding='utf-8')
# 数据库连接
def mysql():
mydb = pymysql.connect(
host=conf.get("mysql_settings", "host"),
port=int(conf.get("mysql_settings", "port")),
user=conf.get("mysql_settings", "user"),
password=conf.get("mysql_settings", "password"),
database='device_info',
cursorclass=pymysql.cursors.DictCursor
)
return mydb
# 设备导入模板
def deviceTemplateDownload():
output = BytesIO()
# 创建Excel文件,不保存,直接输出
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
# 设置Sheet的名字为download
worksheet = workbook.add_worksheet('设备导入')
# 列首
title = ["设备名称", "设备编号", "位置", "摄像头账号", "摄像头密码", "摄像头IP","摄像头端口"]
worksheet.write_row('A1', title)
dictList = [{"设备名称": "必填项,最多一次导入500个设备,填写请删除该提示;", "设备编号": "必填项,填写请删除该提示;",
"位置": "必填项,填写请删除该提示;",
"摄像头账号": "非必填,只有导入摄像头的时候填写该参数;填写请删除该提示;",
"摄像头密码": "非必填,只有导入摄像头的时候填写该参数;填写请删除该提示;",
"摄像头IP": "非必填,只有导入摄像头的时候填写该参数;填写请删除该提示;",
"摄像头端口": "非必填,只有导入摄像头的时候填写该参数;填写请删除该提示;"}]
for i in range(len(dictList)):
row = [dictList[i]["设备名称"], dictList[i]["设备编号"], dictList[i]["位置"], dictList[i]["摄像头账号"], dictList[i]["摄像头密码"],
dictList[i]["摄像头IP"], dictList[i]["摄像头端口"]]
worksheet.write_row('A' + str(i + 2), row)
workbook.close()
response = make_response(output.getvalue())
output.close()
return response
# 设备导入
def deviceUpload():
mydb = mysql()
mydb.connect()
cursor = mydb.cursor()
try:
jsons = request.form
if jsons.__contains__('deviceClassify') and jsons.__contains__('productId') and jsons.__contains__('deviceClass') and jsons.__contains__('deviceType') and jsons.__contains__('is_children'):
# 获取文件流
file = request.files.get("file")
# 获取文件名
fileName = file.filename
fileNameArr = fileName.split(".")
# 校验文件后缀格式
if fileNameArr[1] != "xlsx": return jsonify(code=1, msg="文件后缀格式不正确,应为xlsx;")
# 是否是子设备
is_children = jsons.get("is_children")
# 传输装置编码
trans_device_code = ''
if int(is_children) == 1:
# 传输装置编码
trans_device_code = jsons.get("trans_device_code")
# 系统分类:1 视频设备2 消防设备
deviceClassify = jsons.get("deviceClassify")
# 产品id
productId = jsons.get("productId")
# 设备分类id
deviceClass = jsons.get("deviceClass")
# 设备类型id
deviceType = jsons.get("deviceType")
# 创建日期
time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
df = pd.read_excel(file)
# 表格数据
dataMapList = df.to_dict(orient='records')
keyMap = ['设备名称', '设备编号', '位置', '安装人员', '安装人员电话', '摄像头账号', '摄像头密码','摄像头IP', '摄像头端口']
# 校验表头是否和模板一致
for tableHeaderMap in dataMapList:
# 获取表头
tableHeaders = pd.Series(tableHeaderMap).index.values
for tableHeader in tableHeaders:
if tableHeader not in keyMap:
return jsonify(code=1, msg="文件表头不匹配")
break
sql = "SELECT number from device_info"
cursor.execute(sql)
cursor_date = cursor.fetchall()
numberForDataBaseList = []
for num in cursor_date:
numberForDataBaseList.append(num['number'])
# 组装最终插入数据
insertList = []
# 错误数据
errorList = []
# 用于存储导入文档中已有的设备号
numberForImpList = []
for dataMap in dataMapList:
# 设备名称
deviceName = ''
# 设备号
number = ''
# 位置
position = ''
# 安装人员
#install_person = ''
# 安装人员电话
#install_person_phone = ''
# 摄像头账号
camera_account = ''
# 摄像头密码
camera_password = ''
# 摄像头ip
camera_ip = ''
# 摄像头端口
camera_port = ''
# 是否有错误信息
errorFlag = True
# 错误信息
error = ''
for key in dataMap:
if dataMap[key] is None:
dataMap[key] = ''
elif type(dataMap[key]) == float:
if np.isnan(float(dataMap[key])):
dataMap[key] = ''
if key == '设备名称' or key == '设备编号' or key == '位置' or key == '摄像头账号' or key == '摄像头密码' or key == '摄像头IP' or key == '摄像头端口':
if key == '设备名称':
deviceName = dataMap[key]
elif key == '设备编号':
number = dataMap[key]
elif key == '位置':
position = dataMap[key]
# elif key == '安装人员':
# install_person = dataMap[key]
# elif key == '安装人员电话':
# install_person_phone = dataMap[key]
elif key == '摄像头账号':
camera_account = dataMap[key]
elif key == '摄像头密码':
camera_password = dataMap[key]
elif key == '摄像头IP':
camera_ip = dataMap[key]
elif key == '摄像头端口':
camera_port = dataMap[key]
value = dataMap[key]
if value == None or value == '':
if deviceClass != '1001':
if key != '摄像头账号' and key != '摄像头密码' and key != '摄像头IP' and key != '摄像头端口':
errorFlag = False
error = error + key + "不能为空;"
else:
errorFlag = False
error = error + key + "不能为空;"
if errorFlag:
if number in numberForImpList:
errorFlag = False
error = error + "文档中已经导入过此仪表设备号;"
if str(number) in numberForDataBaseList:
errorFlag = False
error = error + "数据库中已经存在此仪表设备号;"
if not errorFlag:
dataMap["错误信息"] = error
errorList.append(dataMap)
errorFlag = True
else:
data = []
data.append(str(uuid.uuid4()))
data.append(deviceName)
data.append(number)
data.append(time)
data.append(position)
# data.append(install_person)
# data.append(install_person_phone)
data.append('1')
data.append(time)
data.append(time)
data.append(deviceType)
data.append(camera_account)
data.append(camera_password)
data.append(camera_ip)
data.append(camera_port)
data.append(deviceClassify)
data.append(productId)
data.append(deviceClass)
data.append(is_children)
data.append(trans_device_code)
insertList.append(data)
if len(insertList) > 0:
sql = "insert into device_info (id,name,number,install_time,position,current_state,create_time,normal_update_time,device_type,camera_account,camera_password,camera_ip,camera_port,device_classify,product_id,device_class,is_children,trans_device_code) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
insert = cursor.executemany(sql, insertList)
mydb.commit()
cursor.close() # 关闭游标
else:
return jsonify(code=1, msg="缺少必要参数deviceClassify、productId、deviceClass、deviceType、is_children")
except Exception as e:
print(e)
return jsonify(
code=1,
msg="Server internal error"
)
finally:
cursor.close() # 关闭游标
mydb.close() # 再关闭数据库连接
if len(errorList) <= 0:
return jsonify(
msg="success",
code=0
)
else:
response = deviceErrorListDownload(errorList)
response.headers['Content-Type'] = "utf-8"
response.headers["Cache-Control"] = "no-cache"
response.headers["Content-Disposition"] = "attachment; filename=deviceErrorListDownload.xlsx"
return response
# 错误信息下载
def deviceErrorListDownload(dictList):
output = BytesIO()
# 创建Excel文件,不保存,直接输出
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
# 设置Sheet的名字为download
worksheet = workbook.add_worksheet('错误信息')
# 列首
title = ["设备名称", "设备编号", "位置", "安装人员", "安装人员电话", "摄像头账号", "摄像头密码", "摄像头IP",
"摄像头端口", "错误信息"]
worksheet.write_row('A1', title)
for i in range(len(dictList)):
row = [dictList[i]["设备名称"], dictList[i]["设备编号"], dictList[i]["位置"], dictList[i]["安装人员"],
dictList[i]["安装人员电话"], dictList[i]["摄像头账号"], dictList[i]["摄像头密码"],
dictList[i]["摄像头IP"], dictList[i]["摄像头端口"], dictList[i]["错误信息"]]
worksheet.write_row('A' + str(i + 2), row)
workbook.close()
response = make_response(output.getvalue())
output.close()
return response
# 上传文件
def upload():
fname = request.files.get('file') # 获取上传的文件
ip = request.remote_addr
if fname:
time = datetime.now().strftime("%Y%m%d%H%M%S")
new_fname = r'/mnt/work/www/upload/' + time + fname.filename
fname.save(new_fname) # 保存文件到指定路径
return jsonify(
code=0,
msg="success",
data="http://"+ip+"/upload/" + time + fname.filename
)
else:
return jsonify(
code=1,
msg="Server internal error"
)
# 上传许可
def upload_permit():
fname = request.files.get('file') # 获取上传的文件
if fname:
if 'crt' in fname.filename:
new_fname = r'./dev.crt'
fname.save(new_fname) # 保存文件到指定路径
cmd = "openssl verify -CAfile rootCA.crt -partial_chain dev.crt"
result = os.popen(cmd).read()
if result != '' and 'OK' in result:
return jsonify(
code=0,
msg="success",
data="上传许可成功,请重新登录!"
)
else:
return jsonify(
code=1,
msg="许可无效,请重新上传!"
)
else:
return jsonify(
code=1,
msg="上传许可文件格式不正确!"
)
else:
return jsonify(
code=1,
msg="Server internal error"
)
# 上传解析驱动
def upload_analysis():
fname = request.files.get('file') # 获取上传的文件
if fname:
if 'py' in fname.filename:
new_fname = r'./analysis/'+fname.filename
fname.save(new_fname) # 保存文件到指定路径
return jsonify(
code=0,
msg="success"
)
else:
return jsonify(
code=1,
msg="上传解析文件格式不正确!"
)
else:
return jsonify(
code=1,
msg="Server internal error"
)
# 上传配置文件(数据库)
def upload_profile():
fname = request.files.get('file') # 获取上传的文件
if fname:
if 'mysql5.7.tar.gz' in fname.filename:
new_fname = r'/mnt/work/www/upload/'+fname.filename
fname.save(new_fname) # 保存文件到指定路径
cmd = "nsenter -m -n -t 1 sudo -i tar -zxvf /mnt/work/www/upload/mysql5.7.tar.gz -C /"
result = os.popen(cmd).read()
cmd = "nsenter -m -n -t 1 sudo -i docker restart mysql"
result = os.popen(cmd).read()
return jsonify(
code=0,
msg="success"
)
else:
return jsonify(
code=1,
msg="不是导出文件,请用导出的文件导入!"
)
else:
return jsonify(
code=1,
msg="Server internal error"
)
# 下载驱动
def download_drive():
try:
jsons = request.json
url = jsons['url']
my_file = requests.get(url)
file_name = url.split('/')[5]
open('./analysis/'+file_name,'wb').write(my_file.content)
except Exception as e:
print(e)
return jsonify(
code=1,
msg="Server internal error"
)
return jsonify(
code=0,
msg="success"
)
# 消防部件导入模板
def component_template_download():
output = BytesIO()
# 创建Excel文件,不保存,直接输出
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
# 设置Sheet的名字为download
worksheet = workbook.add_worksheet('消防部件导入')
# 列首
title = ["部件名称", "部件编号", "位置"]
worksheet.write_row('A1', title)
dictList = [{"部件名称": "必填项,最多一次导入500个设备,填写请删除该提示;", "部件编号": "必填项,填写请删除该提示;",
"位置": "必填项,填写请删除该提示;"}]
for i in range(len(dictList)):
row = [dictList[i]["部件名称"], dictList[i]["部件编号"], dictList[i]["位置"]]
worksheet.write_row('A' + str(i + 2), row)
workbook.close()
response = make_response(output.getvalue())
output.close()
return response
# 消防部件导入
def component_upload():
mydb = mysql()
mydb.connect()
cursor = mydb.cursor()
try:
jsons = request.form
if jsons.__contains__('trans_device_code') and jsons.__contains__('part_type') and jsons.__contains__(
'part_type_name'):
# 获取文件流
file = request.files.get("file")
# 获取文件名
fileName = file.filename
fileNameArr = fileName.split(".")
# 校验文件后缀格式
if fileNameArr[1] != "xlsx": return jsonify(code=1, msg="文件后缀格式不正确,应为xlsx;")
# 传输装置编码
trans_device_code = jsons.get("trans_device_code")
# 部件类型id
part_type = jsons.get("part_type")
# 部件类型名称
part_type_name = jsons.get("part_type_name")
# 创建日期
time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
df = pd.read_excel(file)
# 表格数据
dataMapList = df.to_dict(orient='records')
keyMap = ["部件名称", "部件编号", "位置"]
# 校验表头是否和模板一致
for tableHeaderMap in dataMapList:
# 获取表头
tableHeaders = pd.Series(tableHeaderMap).index.values
for tableHeader in tableHeaders:
if tableHeader not in keyMap:
return jsonify(code=1, msg="文件表头不匹配")
break
sql = "SELECT number from fire_fighting_component"
cursor.execute(sql)
cursor_date = cursor.fetchall()
numberForDataBaseList = []
for num in cursor_date:
numberForDataBaseList.append(num['number'])
# 组装最终插入数据
insertList = []
# 错误数据
errorList = []
# 用于存储导入文档中已有的设备号
numberForImpList = []
for dataMap in dataMapList:
# 部件名称
name = ''
# 部件编号
number = ''
# 位置
position = ''
# 是否有错误信息
errorFlag = True
# 错误信息
error = ''
for key in dataMap:
if dataMap[key] is None:
dataMap[key] = ''
elif type(dataMap[key]) == float:
if np.isnan(float(dataMap[key])):
dataMap[key] = ''
if key == '部件名称' or key == '部件编号' or key == '位置':
if key == '部件名称':
name = dataMap[key]
elif key == '部件编号':
number = dataMap[key]
elif key == '位置':
position = dataMap[key]
value = dataMap[key]
if value == None or value == '':
errorFlag = False
error = error + key + "不能为空;"
if errorFlag:
if number in numberForImpList:
errorFlag = False
error = error + "文档中已经导入过此仪表设备号;"
if str(number) in numberForDataBaseList:
errorFlag = False
error = error + "数据库中已经存在此仪表设备号;"
if not errorFlag:
dataMap["错误信息"] = error
errorList.append(dataMap)
else:
data = []
data.append(str(uuid.uuid4()))
data.append(name)
data.append(number)
data.append(position)
data.append('1')
data.append(time)
data.append(time)
data.append(part_type)
data.append(part_type_name)
data.append(trans_device_code)
insertList.append(data)
if len(insertList) > 0:
sql = "insert into fire_fighting_component (id,name,number,position,current_state,create_time,normal_update_time,part_type,part_type_name,trans_device_code) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
insert = cursor.executemany(sql, insertList)
mydb.commit()
cursor.close() # 关闭游标
else:
return jsonify(code=1, msg="缺少必要参数trans_device_code、part_type、part_type_name")
except Exception as e:
print(e)
return jsonify(
code=1,
msg="Server internal error"
)
finally:
cursor.close() # 关闭游标
mydb.close() # 再关闭数据库连接
if len(errorList) <= 0:
return jsonify(
msg="success",
code=0
)
else:
response = component_error_list_download(errorList)
response.headers['Content-Type'] = "utf-8"
response.headers["Cache-Control"] = "no-cache"
response.headers["Content-Disposition"] = "attachment; filename=component_error_list_download.xlsx"
return response
# 消防部件错误信息下载
def component_error_list_download(dictList):
output = BytesIO()
# 创建Excel文件,不保存,直接输出
workbook = xlsxwriter.Workbook(output, {'in_memory': True})
# 设置Sheet的名字为download
worksheet = workbook.add_worksheet('错误信息')
# 列首
title = ["部件名称", "部件编号", "位置", "错误信息"]
worksheet.write_row('A1', title)
for i in range(len(dictList)):
row = [dictList[i]["部件名称"], dictList[i]["部件编号"], dictList[i]["位置"], dictList[i]["错误信息"]]
worksheet.write_row('A' + str(i + 2), row)
workbook.close()
response = make_response(output.getvalue())
output.close()
return response
# 上传logo
def upload_logo():
fname = request.files.get('file') # 获取上传的文件
ip = request.remote_addr
if fname:
time = datetime.now().strftime("%Y%m%d%H%M%S")
path = r'/mnt/work/www/upload/logo/'
if os.path.exists(path):
new_fname = r'/mnt/work/www/upload/logo/' + time + fname.filename
fname.save(new_fname) # 保存文件到指定路径
else:
os.mkdir(path)
new_fname = r'/mnt/work/www/upload/logo/' + time + fname.filename
fname.save(new_fname) # 保存文件到指定路径
conf.set("gateway_box",'logo',"/upload/logo/" + time + fname.filename)
with open('setting.ini', 'w') as f:
conf.write(f)
conf.read('setting.ini')
return jsonify(
code=0,
msg="success",
data="/upload/logo/" + time + fname.filename
)
else:
return jsonify(
code=1,
msg="Server internal error"
)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。