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

382 lines
12 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 <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;
ExportDataThread::ExportDataThread(QObject* parent) : QThread(parent)
{
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);
}
}
hint = InternetOpen(0, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
if (hint == NULL) {
return;
}
// FTP地址
string ftpServer = "192.168.1.170";
/* 端口号一般为21 */
int port = 666;
/* 用户名 */
string userName = "FTP2";
/* 密码 */
string pwd = "123";
// 创建ftp连接
hftp = InternetConnectA(hint, ftpServer.c_str(), port, userName.c_str(), pwd.c_str(), INTERNET_SERVICE_FTP, 0, 0);
if (hftp == NULL) {
qDebug() << "ftp connect failed";
return;
}
}
void ExportDataThread::init()
{
b_quit = false;
flag = 0;
}
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 _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;
}
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) {
_XMLExportDataInfo element;
export_XMLData_Info_queue->take(element);
if (element.cameraId != -1 && flag == 1) {
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);
}
}
for (int index = 0; index < NumberOfSupportedCameras; index++) {
pDocument[index]->~XMLDocument();
}
}
//*****************************************已经调试好,没有理清逻辑前不要动**********************
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();
}
DWORD dw = GetLastError();
// 上传文件源为一个文件
if (size == 0) {
int pos = remotePath.find_last_of('/');
string destFileName = remotePath.substr(pos + 1);
string tempPath = remotePath.substr(0, pos + 1);
check_save_dir(tempPath);
if (!FtpPutFileA(hftp, filePath.c_str(), remotePath.c_str(), FTP_TRANSFER_TYPE_BINARY, 0))
qDebug() << "ftp put file failed because" << dw;
}
// 上传源为一个文件夹
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 " << dw;
}
}
}
void ExportDataThread::GetDataFromSaveThread(QString filePath) {
QString remotePath;
remotePath = filePath.mid(filePath.indexOf("image") - 1);
ConnectServer(filePath, remotePath);
}
//*****************************************已经调试好,没有理清逻辑前不要动**********************
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);
}
}
/*
BOOL ExportDataThread::FtpUploadPic(uchar *buffer, string remotePath) {
DWORD dwBytesReturn = 0;
DWORD UploadDataSize = 0;
BYTE* pUploadData = NULL;
DWORD dwRet, bRet = 0;
string tempFile = "temp.jpg";
HINTERNET hFtpFile = NULL;
hFtpFile = FtpOpenFileA(hftp, remotePath.c_str(), GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_RELOAD, NULL);
// 打开文件
HANDLE hFile = CreateFileA(tempFile.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
if (INVALID_HANDLE_VALUE == hFile) {
qDebug() << "CreateFile error because " << GetLastError();
CloseHandle(hFile);
return FALSE;
}
/// -> 以下的代码还未改好
// 获取文件大小
UploadDataSize = GetFileSize(hFile, NULL);
pUploadData = new BYTE[UploadDataSize];
// 读取文件到缓冲区
ReadFile(hFile, pUploadData, UploadDataSize, &dwRet, NULL);
UploadDataSize = dwRet;
// 开始上传数据
bRet = InternetWriteFile(hFtpFile, buffer, UploadDataSize, &dwBytesReturn);
if (FALSE == bRet) {
qDebug() << "InternetWirteFile error because " << GetLastError();
delete[] buffer;
return FALSE;
}
delete[] buffer;
CloseHandle(hFile);
return TRUE;
}
*/