You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Cigarette/Cigarette/exportData.cpp

581 lines
21 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "exportData.h"
#include "QtCore\qfile.h"
#include "QtCore\qtextstream.h"
#include <QTimer>
#include <QFileInfoList>
#include <QDir>
#include <QFileInfo>
#include <QIODevice>
#include <QTextStream>
#include <QProcess>
#include <string>
//#include <ftpManager.h>
#include <wininet.h>
#include <Windows.h>
#include <sys/stat.h>
#include <io.h>
#pragma comment(lib, "Wininet.lib")
Cigarette* cg;
extern SyncQueue<_XMLExportDataInfo>* export_XMLData_Info_queue;
extern ConfPath g_conf_path;
extern bool flag;
extern SysConf g_sys_conf; //系统配置参数
ExportDataThread::ExportDataThread(QObject* parent) : QThread(parent)
{
/* Move to init()
//第一步执行
cg->read_conf(g_conf_path);
for (int index = 0; index < NumberOfSupportedCameras; index++)
{
XMLError error;
pDocument[index] = new tinyxml2::XMLDocument();
QString xmlPath = QString(EXPORTDATA_FILE).arg(index);
QString filePath = g_conf_path.config_path + "/" + xmlPath;
error = pDocument[index]->LoadFile(filePath.toLocal8Bit().constData());
if (error != XML_SUCCESS) {
XMLDeclaration* declaration = pDocument[index]->NewDeclaration();
pDocument[index]->InsertFirstChild(declaration);
}
}
init(ip,port,username,userpwd);
cout << "11111111111111";
hint = InternetOpen(0, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
if (hint == NULL) {
return;
}
if (!ConnectFtp(&ip, &port, &username, &userpwd))
qDebug() << "First connect FTP failed because " << GetLastError();
*/
readyToSendZip = false;
listToZip.clear();
tmpListToZip.clear();
lastTimeStamp.clear();
zipTimeStamp.clear();
hftp = NULL;
hint = NULL;
}
void ExportDataThread::init(string ip_, int port_, string username_, string userpwd_)
{
//初始化FTP连接信息
ip = ip_;
port = port_;
username = username_;
userpwd = userpwd_;
cout << "ftp ip =" << ip << "| prot =" << port << endl;
cout << "username =" << username << "| pwd =" << userpwd << endl;
b_quit = false;
flag = false;
timer = new QTimer(this);
timer->setTimerType(Qt::PreciseTimer);
timer->setSingleShot(true);
//第一步执行
cg->read_conf(g_conf_path);
for (int index = 0; index < NumberOfSupportedCameras; index++)
{
XMLError error;
pDocument[index] = new tinyxml2::XMLDocument();
QString xmlPath = QString(EXPORTDATA_FILE).arg(index);
QString filePath = g_conf_path.config_path + "/" + xmlPath;
error = pDocument[index]->LoadFile(filePath.toLocal8Bit().constData());
if (error != XML_SUCCESS) {
XMLDeclaration* declaration = pDocument[index]->NewDeclaration();
pDocument[index]->InsertFirstChild(declaration);
}
}
//init(ip, port, username, userpwd);
hint = InternetOpen(0, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
if (hint == NULL) {
return;
}
if (!ConnectFtp(&ip, &port, &username, &userpwd))
qDebug() << "First connect FTP failed because " << GetLastError();
}
void ExportDataThread::start_work()
{
start(HighestPriority);
}
void ExportDataThread::stop()
{
b_quit = true;
_XMLExportDataInfo data;
export_XMLData_Info_queue->put(data);
//InternetCloseHandle(hftp);
//InternetCloseHandle(hint);
}
bool ExportDataThread::FtpConnectionTest () {
int retryCount = 3;
if ((hftp == NULL) || (!FtpSetCurrentDirectoryA(hftp, "/"))) {
while (!ConnectFtp(&ip, &port, &username, &userpwd)) {
if (retryCount-- == 0) {
break;
}
QTime delayTime = QTime::currentTime().addMSecs(100); //100ms
while (QTime::currentTime() < delayTime) {
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
}
}
return (retryCount > 0);
}
bool ExportDataThread::ConnectFtp(string *ip_, int *port_, string *username_, string *userpwd_) {
//// FTP地址
//string ftpServer = "192.168.1.180";
///* 端口号一般为21 */
//int port = 666;
///* 用户名 */
//string userName = "FTP2";
///* 密码 */
//string pwd = "123";
if (hftp != NULL) {
InternetCloseHandle(hftp);
hftp = NULL;
}
// 创建ftp连接
// hftp = InternetConnectA(hint, ftpServer.c_str(), port, userName.c_str(), pwd.c_str(), INTERNET_SERVICE_FTP, 0, 0);
hftp = InternetConnectA(hint, ip_->c_str(), *port_, username_->c_str(), userpwd_->c_str(), INTERNET_SERVICE_FTP, 0, 0);
if (hftp == NULL) {
qDebug() << "ftp connect failed because " << GetLastError();
return false;
}
//else
// qDebug() << "ftp reconnect success";
return true;
}
//bool _ExportDataInfo::getAverageData(map<string, float>& averageData, int index)
//{
// tinyxml2::XMLDocument doc;
// //char xmlPath[256];
// XMLError error;
// map<string, float> data;
// //memset(xmlPath, 0, 256);
// QString xmlPath = QString(EXPORTDATA_FILE).arg(index);
// //sprintf(xmlPath, EXPORTDATA_FILE, index);
// QString filePath = g_conf_path.config_path + "/" + xmlPath;
// error = doc.LoadFile(filePath.toLocal8Bit().constData());
// if (error != XML_SUCCESS)
// if (doc.LoadFile(filePath.toLocal8Bit().constData()) != 0)
// {
// cout << "load xml file failed" << endl;
// return false;
// }
// XMLElement* root = doc.RootElement();
// XMLElement* userNode = root->FirstChildElement("Camera");
// data["CameraId"] = index;
// data["IsNG"] = 0;
// data["IsJdExist"] = 0;
// data["Total"] = 0;
// while (userNode != NULL)
// {
// if (atoi(userNode->Attribute("Id")) == index) {
// data["IsNG"]++;
// data["IsJdExist"]++;
// data["Total"]++;
// XMLElement* IsNgNode = userNode->FirstChildElement("IsNG");
// data["IsNg"] = strcmp(IsNgNode->GetText(), "TRUE");
// XMLElement* IsJdExistNode = userNode->FirstChildElement("IsJdExist");
// if (strcmp(IsJdExistNode->GetText(), "TRUE") == 0)
// data["IsJdExist"]++;
// XMLElement* TimeCostNode = userNode->FirstChildElement("TimeCost");
// data["TimeCost"] += stof(TimeCostNode->GetText());
// }
// userNode = userNode->NextSiblingElement();//下一个兄弟节点
// }
// if (data["Total"] == 0)
// return false;
// data["TimeCost"] = data["TimeCost"] / data["Total"];
//
// averageData = data;
//
// return true;
//}
//XML文件
//写数据到XML文件
int ExportDataThread::insertXMLNode(const char* xmlPath, _XMLExportDataInfo& data)
{
XMLElement* root = pDocument[data.cameraId]->RootElement();
if (root == NULL) {
root = pDocument[data.cameraId]->NewElement("Root");
pDocument[data.cameraId]->InsertEndChild(root);
pDocument[data.cameraId]->SaveFile(xmlPath);
//return 0;
}
/// 总统计数据
// 总检测数量
XMLElement* Total = pDocument[data.cameraId]->NewElement("TotalDatas");
XMLElement* time = pDocument[data.cameraId]->NewElement("CurrentTime");
QString currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
time->InsertEndChild(pDocument[data.cameraId]->NewText(currentTime.toStdString().c_str()));
Total->InsertEndChild(time);
XMLElement* TotalCheckNum = pDocument[data.cameraId]->NewElement("TotalCheckNum");
char s[20];
TotalCheckNum->InsertEndChild(pDocument[data.cameraId]->NewText(itoa(data.TotalCheckNum, s, 10)));
Total->InsertEndChild(TotalCheckNum);
// 总剔除数量
XMLElement* TotalKickNum = pDocument[data.cameraId]->NewElement("TotalKickNum");
TotalKickNum->InsertEndChild(pDocument[data.cameraId]->NewText(itoa(data.TotalKickNum, s, 10)));
Total->InsertEndChild(TotalKickNum);
root->InsertEndChild(Total);
/// 各相机数据
// 相机id & 总数
XMLElement* CameraNode = pDocument[data.cameraId]->NewElement("Camera");
CameraNode->SetAttribute("Count ", data.cameraTotal);
CameraNode->SetAttribute("Id", data.cameraId);
XMLElement* JudgeNum = pDocument[data.cameraId]->NewElement("JudgeNum");
// 各相机检测数量
XMLElement* checkNum = pDocument[data.cameraId]->NewElement("CheckNum");
checkNum->InsertEndChild(pDocument[data.cameraId]->NewText(itoa(data.checkNum, s, 10)));
JudgeNum->InsertEndChild(checkNum);
// 各相机ok数量
XMLElement* okNum = pDocument[data.cameraId]->NewElement("OkNum");
okNum->InsertEndChild(pDocument[data.cameraId]->NewText(itoa(data.okNum, s, 10)));
JudgeNum->InsertEndChild(okNum);
// 各相机ng数量
XMLElement* ngNum = pDocument[data.cameraId]->NewElement("NgNum");
ngNum->InsertEndChild(pDocument[data.cameraId]->NewText(itoa(data.ngNum, s, 10)));
JudgeNum->InsertEndChild(ngNum);
// 各相机实际剔除数量(单通道剔除时为总剔除数量)
XMLElement* kickNum = pDocument[data.cameraId]->NewElement("KickNum");
kickNum->InsertEndChild(pDocument[data.cameraId]->NewText(itoa(data.kickNum, s, 10)));
JudgeNum->InsertEndChild(kickNum);
// 合格率
XMLElement* PassRate = pDocument[data.cameraId]->NewElement("PassRate");
std::string temp_str = std::to_string(data.PassRate * 100) + "%";
const char* temp_char = temp_str.c_str();
PassRate->InsertEndChild(pDocument[data.cameraId]->NewText(temp_char));
JudgeNum->InsertEndChild(PassRate);
// 剔除率
XMLElement* KickRate = pDocument[data.cameraId]->NewElement("KickRate");
temp_str = std::to_string(data.KickRate * 100) + "%";
temp_char = temp_str.c_str();
KickRate->InsertEndChild(pDocument[data.cameraId]->NewText(temp_char));
JudgeNum->InsertEndChild(KickRate);
// 各相机胶点识别个数
XMLElement* JdNum = pDocument[data.cameraId]->NewElement("JdNum");
JdNum->InsertEndChild(pDocument[data.cameraId]->NewText(data.jdNum.toStdString().c_str()));
JudgeNum->InsertEndChild(JdNum);
XMLElement* shotCounts = pDocument[data.cameraId]->NewElement("ShotCounts");
shotCounts->InsertEndChild(pDocument[data.cameraId]->NewText(itoa(data.shotCounts, s, 10)));
JudgeNum->InsertEndChild(shotCounts);
CameraNode->InsertEndChild(JudgeNum);
// 各相机采集速度
XMLElement* speed = pDocument[data.cameraId]->NewElement("Speed");
XMLElement* AcquisitionSpeed = pDocument[data.cameraId]->NewElement("AcquisitionSpeed");
AcquisitionSpeed->InsertEndChild(pDocument[data.cameraId]->NewText(data.AcquisitionSpeed.toStdString().c_str()));
speed->InsertEndChild(AcquisitionSpeed);
// 各相机检测速度
XMLElement* DetectSpeed = pDocument[data.cameraId]->NewElement("DetectSpeed");
DetectSpeed->InsertEndChild(pDocument[data.cameraId]->NewText(data.DetectSpeed.toStdString().c_str()));
speed->InsertEndChild(DetectSpeed);
CameraNode->InsertEndChild(speed);
root->InsertEndChild(CameraNode);
return pDocument[data.cameraId]->SaveFile(xmlPath);
}
void ExportDataThread::run()
{
while (!b_quit || (b_quit && (!export_XMLData_Info_queue->isEmpty() || readyToSendZip || !tmpListToZip.isEmpty()))) {
_XMLExportDataInfo element;
if (!export_XMLData_Info_queue->isEmpty()) {
export_XMLData_Info_queue->take(element);
if (element.cameraId != -1 && flag) {
char buf[256];
memset(buf, 0, 256);
QString xmlPath = QString(EXPORTDATA_FILE).arg(element.cameraId);
QString filePath = g_conf_path.config_path + "/" + xmlPath;
sprintf(buf, filePath.toLocal8Bit().constData(), element.cameraId);
insertXMLNode(buf, element);
QString remotePath = "/tmp/" + xmlPath;
ConnectServer(filePath, remotePath);
}
}
if ((b_quit || (!timer->isActive() && !readyToSendZip)) && (!tmpListToZip.isEmpty())) {
listToZip += tmpListToZip;
tmpListToZip.clear();
zipTimeStamp.append(lastTimeStamp[0]);
lastTimeStamp.clear();
readyToSendZip = true;
}
if (readyToSendZip && !listToZip.isEmpty()) {
QString remotePath;
QStringList zipFilePaths;
QStringList fileList;
QString okStr = "1";
QProcess process(0);
//QDateTime now_ts = QDateTime::currentDateTime();
QStringList argsNg;
QStringList argsOk;
//条盒TJ 小盒BJ
/*zipFilePaths.append(g_conf_path.save_pics_path + "/" + "416_BJ_" + zipTimeStamp[0] + "-00_" + zipTimeStamp[0] + "-59_0.zip");
zipFilePaths.append(g_conf_path.save_pics_path + "/" + "416_BJ_" + zipTimeStamp[0] + "-00_" + zipTimeStamp[0] + "-59_1.zip");
fileList.append(g_conf_path.save_pics_path + "/" + zipTimeStamp[0] + "ng.txt");
fileList.append(g_conf_path.save_pics_path + "/" + zipTimeStamp[0] + "ok.txt");*/
zipFilePaths.append("416_TJ_" + zipTimeStamp[0] + "-00_" + zipTimeStamp[0] + "-59_0.zip");
zipFilePaths.append("416_TJ_" + zipTimeStamp[0] + "-00_" + zipTimeStamp[0] + "-59_1.zip");
fileList.append(zipTimeStamp[0] + "ng.txt");
fileList.append(zipTimeStamp[0] + "ok.txt");
zipTimeStamp.clear();
QFile* file[2] = { NULL };
file[0] = new QFile(fileList[0]);
file[1] = new QFile(fileList[1]);
//QFile fileNg(fileList[0]);
// QFile fileOk(fileList[1]);
file[0]->open(QIODevice::WriteOnly);
file[1]->open(QIODevice::WriteOnly);
QTextStream ngStream(file[0]);
QTextStream okStream(file[1]);
argsNg.append("a");
argsNg.append(zipFilePaths[0]);
argsOk.append("a");
argsOk.append(zipFilePaths[1]);
// create zip file
for (int i = 0; i < listToZip.size(); i++) {
QStringList strList = listToZip[i].split("_");
strList = strList[strList.size() - 1].split(".");
int index = listToZip[i].lastIndexOf("/\\", 0);
if (strList[0] == okStr) {
okStream << listToZip[i] << endl;
}
else {
ngStream << listToZip[i] << endl;
}
}
argsNg.append("-i@" + fileList[0]);
argsNg.append("-mx=3");
argsOk.append("-i@" + fileList[1]);
argsOk.append("-mx=3");
file[0]->close();
file[1]->close();
for (int i = 0; i < zipFilePaths.size(); i++) {
if (file[i]->size() == 0) {
continue;
}
process.start(QApplication::applicationDirPath() + "/7z.exe", i == 0 ? argsNg : argsOk);
process.waitForStarted();
process.waitForFinished();
//QString out = QString::fromLocal8Bit(process.readAllStandardOutput());
//qDebug() << out;
remotePath = zipFilePaths[i].mid(zipFilePaths[i].indexOf("image") - 1);
qDebug() << remotePath;
ConnectServer(zipFilePaths[i], remotePath);
QFile file(zipFilePaths[i]);
file.remove();
}
file[0]->remove();
file[1]->remove();
listToZip.clear();
readyToSendZip = false;
}
}
flag = false;
for (int index = 0; index < NumberOfSupportedCameras; index++) {
pDocument[index]->~XMLDocument();
}
if (hftp != NULL) {
InternetCloseHandle(hftp);
hftp = NULL;
}
if (hftp != NULL) {
InternetCloseHandle(hint);
hint = NULL;
}
}
//*****************************************已经调试好,没有理清逻辑前不要动**********************
void ExportDataThread::check_save_dir(std::string dir_path)
{
// 如果目的路径不存在,一级一级创建
// 目的路径格式为:"./dir/dir1/.../"
if (FALSE == FtpSetCurrentDirectoryA(hftp, dir_path.c_str())) {
FtpSetCurrentDirectoryA(hftp, "/");
int pos = 1;
while (pos > 0) {
// 从第二个“/”开始依次找到目的路径中的“/”位置
pos = dir_path.find_first_of('/', pos + 1);
if (pos == -1)
break;
string tempPath = dir_path.substr(0, pos + 1);
FtpCreateDirectoryA(hftp, tempPath.c_str());
}
//FtpSetCurrentDirectoryA(hftp, dir_path.c_str());
}
}
void ExportDataThread::EDrecMsgFromCigarette() {
flag = true;
}
//发送数据给服务器
void ExportDataThread::ConnectServer(QString srcPath, QString destPath) {
string filePath = srcPath.toLocal8Bit().constData();
string remotePath = destPath.toLocal8Bit().constData();
std::vector<string> files;
// 判断上传的是文件还是文件夹标识
int size = 0;
struct stat st;
stat(filePath.c_str(), &st);
if (st.st_mode & S_IFDIR) {
//qDebug() << "filePath is Directory";
// 获取文件夹下所有文件名
GetFiles(filePath, files);
size = files.size();
}
if (!FtpConnectionTest()) {
qDebug() << "Failed to connect FTP server";
return;
}
// 上传文件源为一个文件
if (size == 0) {
int pos = remotePath.find_last_of('/');
string destFileName = remotePath.substr(pos + 1);
string tempPath = remotePath.substr(0, pos + 1);
if (!InternetGetConnectedState(NULL, 0)) {
qDebug() << "计算机未连接到互联网";
}
else {
check_save_dir(tempPath);
while (!FtpPutFileA(hftp, filePath.c_str(), remotePath.c_str(), FTP_TRANSFER_TYPE_BINARY, 0)) {
qDebug() << "ftp put file " << filePath.c_str() << "failed because" << GetLastError();
if (!ConnectFtp(&ip, &port, &username, &userpwd))
qDebug() << "connect FTP failed because " << GetLastError();
}
}
}
// 上传源为一个文件夹
else {
for (int i = 0; i < size; i++) {
string tempFilePath = (string(files[i]).erase(0, filePath.length() + 1)).c_str();
// 获取上传路径中的文件名
int pos = tempFilePath.find_last_of('/');
string destFileName = tempFilePath.substr(pos + 1);
check_save_dir(remotePath + tempFilePath.substr(0, pos + 1));
//发送函数
if (!FtpPutFileA(hftp, files[i].c_str(), destFileName.c_str(), FTP_TRANSFER_TYPE_BINARY, 0))
qDebug() << "ftp put files failed because " << GetLastError();
}
}
}
void ExportDataThread::GetDataFromSaveThread(QString filePath) {
QString remotePath;
QStringList currentTimeStamp;
QRegExp rx("((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))_([0-1]?[0-9]|2[0-3])-([0-5][0-9])");
if (filePath.indexOf("ng") == -1) {
if (rx.indexIn(filePath) != -1) {
currentTimeStamp = rx.capturedTexts();
}
else {
QDateTime now_ts = QDateTime::currentDateTime();
currentTimeStamp.append(now_ts.toString("yyyy-MM-dd_HH-mm"));
}
if (lastTimeStamp.isEmpty() || (currentTimeStamp[0] != lastTimeStamp[0])) {
if (!tmpListToZip.isEmpty()) {
listToZip = tmpListToZip;
tmpListToZip.clear();
}
if (!listToZip.isEmpty()) {
zipTimeStamp.append(lastTimeStamp[0]);
readyToSendZip = true;
}
lastTimeStamp.clear();
lastTimeStamp.append(currentTimeStamp[0]);
timer->stop();
timer->start(1000 * (60 * 1 + 10));
}
tmpListToZip.append(filePath);
}
}
//*****************************************已经调试好,没有理清逻辑前不要动**********************
void ExportDataThread::GetFiles(string path, std::vector<string>& files) {
//文件句柄
intptr_t hFile = 0;
//文件信息的结构体
struct _finddata_t fileinfo;
string p;
if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
{
// "\\*"是指读取文件夹下的所有类型的文件
do
{
//如果是目录,迭代之
//如果不是,加入列表
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
GetFiles(p.assign(path).append("/").append(fileinfo.name), files);
}
else
{
files.push_back(p.assign(path).append("/").append(fileinfo.name));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}