Init commit

This commit is contained in:
semenov
2024-08-14 10:02:09 +03:00
parent 1870d26468
commit c00efe0177
41 changed files with 2051 additions and 0 deletions

20
Core/FileData.h Normal file
View File

@@ -0,0 +1,20 @@
#include <QString>
#ifndef FILEDATA_H
#define FILEDATA_H
struct FileData
{
QString path;
QString hash;
bool operator==(const FileData& other)const{
if(this->path==(other.path)) return true;
return false;
}
}; //путь
#endif // FILEDATA_H

112
Core/UpdateController.cpp Normal file
View File

@@ -0,0 +1,112 @@
#include "UpdateController.h"
UpdateController::UpdateController(DataParser *parser, QObject *parent) :
QObject(parent)
{
this->dataParser = parser;
localPath = QDir::currentPath() + "/Application";
countSend = 0;
CalculateHash();
}
void UpdateController::SendFile(QDataStream &stream)
{
/* Открываем файл для Чтения*/
QFile file(hashFilename);
stream << PacketType::TYPE_FILE; //Отправляем тип блока
QFileInfo fileInfo(file);
fileSize = fileInfo.size();
stream << fileSize;
if(file.open(QFile::ReadOnly | QFile::Text)){
while(!file.atEnd()){
QByteArray data = file.readAll();//file.read(1025*250);
stream << data;
countSend++;
}
qDebug() << Tools::GetTime() << "count end Final: " << countSend;
}
file.close();
countSend = 0;
}
void UpdateController::CalculateHash()
{
QDirIterator iterator(localPath,QDirIterator::Subdirectories);
fileDataList.clear();
QList<FileData> *files = new QList<FileData>;
QList<FileData> * folders = new QList<FileData>;
if(!QDir("Application").exists()){ //проверка на наличие папки
QDir().mkdir("Application");
}
QDir dir(localPath);
QString hashString;
while (iterator.hasNext())
{
iterator.next();
QFileInfo fileInfo = iterator.fileInfo();
FileData currentFile;
QFile file(fileInfo.absoluteFilePath());
quint64 fileSize = file.size(); //буффер для хэширования крупных файлов
const quint64 bufferSize = 10240;
if(fileInfo.isHidden()) continue;
if(fileInfo.isFile() && file.open(QIODevice::ReadOnly))
{
char buffer[bufferSize];
int bytesRead;
int readSize = qMin(fileSize,bufferSize);
QCryptographicHash hash(QCryptographicHash::Md5);
while(readSize > 0 && (bytesRead = file.read(buffer,readSize)) > 0){
fileSize -= bytesRead;
hash.addData(buffer,bytesRead);
readSize = qMin(fileSize,bufferSize);
}
hashString = QString(hash.result().toHex());
currentFile.path = Tools::CreateLocalPath(fileInfo.absoluteFilePath());
currentFile.hash = hashString;
files->push_back(currentFile);
}
else if (fileInfo.isDir() && !fileInfo.isRoot() && fileInfo.fileName() != "..")
{
currentFile.path = Tools::CreateLocalPath(fileInfo.path());
currentFile.hash = "FOLDER";
if(!folders->contains(currentFile)){
folders->push_back(currentFile);
}
}
}
fileDataList.append(*folders);
fileDataList.append(*files);
dataParser->CreateXML(fileDataList);
delete folders;
delete files;
}
UpdateController::~UpdateController()
{
}

40
Core/UpdateController.h Normal file
View File

@@ -0,0 +1,40 @@
#ifndef FILEMANAGER_H
#define FILEMANAGER_H
#include "Core\FileData.h"
#include "Core\dataparser.h"
#include "Core\tcpclient.h"
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QXmlStreamAttribute>
#include <QCryptographicHash>
#include <QDirIterator>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QDebug>
#include <QList>
#include <QObject>
class UpdateController : public QObject
{
Q_OBJECT
public:
explicit UpdateController(DataParser *parser,QObject *parent = 0);
void SendFile(QDataStream &stream);
void CalculateHash();
~UpdateController();
private:
DataParser *dataParser;
QString localPath;
QList<FileData> fileDataList;
quint64 fileSize;
int countSend;
};
#endif // FILEMANAGER_H

98
Core/dataparser.cpp Normal file
View File

@@ -0,0 +1,98 @@
#include "FileData.h"
#include "dataparser.h"
#include "tools.h"
DataParser::DataParser()
{
}
void DataParser::CreateXML(QList<FileData> fileDataList)
{
QFile file(hashFilename);
file.open(QIODevice::WriteOnly);
QXmlStreamWriter xmlWriter(&file);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("FileDataList");
foreach (FileData data,fileDataList)
{
xmlWriter.writeStartElement("FileData");
xmlWriter.writeAttribute("Path",data.path);
xmlWriter.writeAttribute("Hash",data.hash);
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();
file.close();
}
void DataParser::CreateServerSettings(QString address, QString port)
{
QFile file(settingsName);
file.open(QIODevice::WriteOnly);
QXmlStreamWriter xmlWriter(&file);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("ServerSettingsContainer");
xmlWriter.writeStartElement("ServerSettings");
xmlWriter.writeAttribute("Address",address);
xmlWriter.writeAttribute("Port",port);
xmlWriter.writeEndElement();
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();
file.close();
}
ServerSettings *DataParser::GetServerSettings()
{
ServerSettings *settings = new ServerSettings;
QFile file(settingsName);
file.open(QIODevice::ReadOnly);
QXmlStreamReader xmlReader(&file);
while (!xmlReader.atEnd()){
if(xmlReader.isStartElement()){
if(xmlReader.name() == "ServerSettings"){
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes()){
QString name = attr.name().toString();
QString value = attr.value().toString();
if(name == "Address"){
settings->Address = value;
}
if(name == "Port"){
settings->Port = value;
}
}
}
}
xmlReader.readNext();
}
return settings;
}

21
Core/dataparser.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef DATAPARSER_H
#define DATAPARSER_H
#include "FileData.h"
#include <Datas.h>
#include <QFile>
#include <QXmlStreamWriter>
class DataParser
{
public:
DataParser();
~DataParser();
void CreateServerSettings(QString server,QString port);
ServerSettings* GetServerSettings();
void CreateXML(QList<FileData> fileDataList);
};
#endif // DATAPARSER_H

37
Core/externalexecuter.cpp Normal file
View File

@@ -0,0 +1,37 @@
#include "externalexecuter.h"
ExternalExecuter::ExternalExecuter()
{
}
ExternalExecuter::~ExternalExecuter()
{
}
void ExternalExecuter::CallApp()
{
QProcess myProcess(this);
QStringList args;
args << "1";
myProcess.start(programPath,args);
myProcess.waitForFinished(-1);
}
void ExternalExecuter::FindApp()
{
QString localPath = QDir::currentPath() + "/Application";
QDirIterator iterator(localPath,QDirIterator::Subdirectories);
while(iterator.hasNext()){
iterator.next();
if(iterator.fileInfo().fileName() == "RRJ.exe"){
programPath = iterator.fileInfo().absoluteFilePath();
qDebug() << "Bin found: " << programPath;
}
}
}

25
Core/externalexecuter.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef EXTERNALEXECUTER_H
#define EXTERNALEXECUTER_H
#include <QObject>
#include <QString>
#include <QDir>
#include <QDirIterator>
#include <QProcess>
#include <QDebug>
class ExternalExecuter : public QObject
{
Q_OBJECT
public:
ExternalExecuter();
void CallApp();
void FindApp();
~ExternalExecuter();
private:
QString programPath;
};
#endif // EXTERNALEXECUTER_H

36
Core/main.cpp Normal file
View File

@@ -0,0 +1,36 @@
#include "UpdateController.h"
#include "dataparser.h"
#include "externalexecuter.h"
#include "screenchecker.h"
#include <QCoreApplication>
#include <QDebug>
#include <QObject>
#include <nonblockedinput.h>
#include <tcpclient.h>
#include <QTextCodec>
#include <QProcess>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
setlocale(LC_ALL,"Russian");
NonBlockedInput cli;
TCPClient *client = new TCPClient;
DataParser *parser = new DataParser;
UpdateController *updateController = new UpdateController(parser);
RecognizeSystem *recognizeSystem = new RecognizeSystem;
ScreenChecker *screenChecker = new ScreenChecker;
ExternalExecuter *externalExecuter = new ExternalExecuter;
client->Initialize(updateController,recognizeSystem,externalExecuter);
recognizeSystem->Initialize(updateController);
QObject::connect(&cli,&NonBlockedInput::LineIsRead,client,&TCPClient::onMessageEntered);
//screenChecker->Check();
return a.exec();
}

18
Core/nonblockedinput.cpp Normal file
View File

@@ -0,0 +1,18 @@
#include "nonblockedinput.h"
NonBlockedInput::NonBlockedInput(QObject *parent)
{
this->moveToThread(&thread);
connect(&thread,&QThread::started, this, &NonBlockedInput::ReadLine);
thread.start();
}
void NonBlockedInput::ReadLine()
{
QTextStream inputStream(stdin);
QString line;
while (inputStream.readLineInto(&line)){
emit LineIsRead(line);
}
}

24
Core/nonblockedinput.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef NONBLOCKEDINPUT_H
#define NONBLOCKEDINPUT_H
#include <QTextStream>
#include <QDebug>
#include <QThread>
class NonBlockedInput : public QObject
{
Q_OBJECT
public:
explicit NonBlockedInput(QObject* parent = nullptr);
private:
QThread thread;
signals:
void LineIsRead(QString line);
private slots:
void ReadLine();
};
#endif // NONBLOCKEDINPUT_H

243
Core/recognizesystem.cpp Normal file
View File

@@ -0,0 +1,243 @@
#include "Core/recognizesystem.h"
RecognizeSystem::RecognizeSystem(QObject *parent):
QObject(parent)
{
packetType = PacketType::TYPE_NONE;
filePath.clear();
fileSize = 0;
message.clear();
sizeReceiveData = 0;
tmpBlock.clear();
countSend = 0;
}
RecognizeSystem::~RecognizeSystem()
{
}
void RecognizeSystem::Initialize(UpdateController *updateController)
{
this->updateController = updateController;
}
void RecognizeSystem::SetSocket(QTcpSocket *socket)
{
this->socket = socket;
}
void RecognizeSystem::Recognize()
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
while(socket->bytesAvailable())
{
if(packetType == PacketType::TYPE_NONE){ //определение первичного пакета
stream.startTransaction();
stream >> packetType;
if(!stream.commitTransaction()){
emit onSendDebugLog(Tools::GetTime() + " CLIENT: packetType - FAIL commitTransaction");
if(socket->waitForReadyRead(TCP_READ_TIMEOUT)){
emit onSendDebugLog("ERROR: PACKET TYPE READ TIMEOUT");
return;
}
continue;
}
//qDebug() << Tools::GetTime() << "CLIENT: type: " << packetType;
}
if(packetType == PacketType::TYPE_MSG){ //поведение на тип пакета с сообщением
stream.startTransaction();
stream >> message;
if(!stream.commitTransaction()){
emit onSendDebugLog(Tools::GetTime() + "CLIENT: Message - FAIL commitTransaction");
if(socket->waitForReadyRead(TCP_READ_TIMEOUT)){
emit onSendDebugLog(Tools::GetTime() + "ERROR: MESSAGE READ TIMEOUT");
return;
}
continue;
}
emit onSendDebugLog(Tools::GetTime() + " CLIENT: Message from server " + message); //результат обрабатывать тут?
packetType = PacketType::TYPE_NONE;
continue;
}
if(packetType == PacketType::TYPE_FOLDER){ //создание папок
stream.startTransaction();
stream >> filePath;
if(!stream.commitTransaction()){
continue;
}
filePath = Tools::CreateFullPath(filePath);
QDir dir(filePath);
if(!dir.exists()){
if(dir.mkpath(filePath)){
qDebug() << "Dir Created";
}
}
packetType = PacketType::TYPE_NONE;
continue;
}
if(packetType == PacketType::TYPE_FILE) //загрузка файлов
{
//ПОЛУЧЕНИЕ ПУТИ
//ПОЛУЧЕНИЕ РАЗМЕРА ФАЙЛА
forever
{
stream.startTransaction();
stream >> filePath;
stream >> fileSize;
if(!stream.commitTransaction()){
emit onSendDebugLog(Tools::GetTime() + "CLIENT: filePath, fileSize - FAIL commitTransaction");
if (!socket->waitForReadyRead(TCP_READ_TIMEOUT)) {
emit onSendDebugLog(Tools::GetTime() + "CLIENT: ERROR! readyRead timeout - filePath, fileSize!!!");
return;
}
continue;
}
filePath = Tools::CreateFullPath(filePath);
emit onSendDebugLog("CLIENT: filesize: " + QString::number(fileSize));
emit onSendDebugLog("CLIENT: filePath: " + filePath);
socket->waitForReadyRead(100);
break;
}
//ПОЛУЧЕНИЕ САМОГО ФАЙЛА
emit onSendDebugLog(Tools::GetTime() + "AfterRead size and path BytesAvailable: " + socket->bytesAvailable());
//УКАЗАНИЕ ПУТИ ФАЙЛА
QFile file(filePath);
if (file.exists())
{
file.remove(); //удаление файла, если он уже есть, но необходимо обновить
emit onSendDebugLog(Tools::GetTime() + "Delete exist file: " + filePath);
}
file.open(QFile::Append);
forever
{
stream.startTransaction();
stream >> tmpBlock;
if(!stream.commitTransaction()){
//qDebug() << Tools::GetTime() << "CLIENT: tmpBlock - FAIL";
if(socket->waitForReadyRead(TCP_READ_TIMEOUT)){
continue;
}
continue;
}
quint64 toFile = file.write(tmpBlock);
emit onSendDebugLog(Tools::GetTime() + "CLIENT: toFile :" + toFile);
sizeReceiveData += toFile;
countSend++;
emit UpdateBytesAvailable(fileSize,sizeReceiveData);
tmpBlock.clear();
if(sizeReceiveData == fileSize){
emit onSendDebugLog(Tools::GetTime() + "FINAL Count send: " + QString::number(countSend));
emit onSendDebugLog(Tools::GetTime() + "FINAL Size received: " + QString::number(sizeReceiveData));
emit onSendDebugLog(Tools::GetTime() + "FINAL File size" + QString::number(fileSize));
break;
}
}
file.close();
emit onSendDebugLog(Tools::GetTime() + "File loaded");
//ОЧИСТКА ПОСЛЕ ПЕРЕДАЧИ
filePath.clear();
fileSize = 0;
tmpBlock.clear();
sizeReceiveData = 0;
countSend = 0;
}
if(packetType == PacketType::TYPE_DELETE) //удаление лишних файлов (рекурсивно удаляет все содежимое)
{
stream.startTransaction();
stream >> filePath;
if(!stream.commitTransaction()){
continue;
}
filePath = Tools::CreateFullPath(filePath);
QFileInfo fileInfo(filePath);
if(fileInfo.exists())
{
if(fileInfo.isFile()){
QFile file(filePath);
file.remove();
}
if(fileInfo.isDir()){
QDir dir(filePath);
dir.removeRecursively();
}
qDebug() << Tools::GetTime() << "Deleted: " << filePath;
}
packetType = PacketType::TYPE_NONE;
continue;
}
if(packetType ==PacketType::TYPE_FINISH){ //для повторного создания хэша после загрузки
updateController->CalculateHash();
emit LoadComplete();
packetType = PacketType::TYPE_NONE;
}
if(packetType == PacketType::TYPE_NEEDUPDATE){
bool flag;
stream.startTransaction();
stream >> flag;
emit onNeedUpdate(flag);
packetType = PacketType::TYPE_NONE;
}
packetType = PacketType::TYPE_NONE;
}
}

45
Core/recognizesystem.h Normal file
View File

@@ -0,0 +1,45 @@
#ifndef RECOGNIZESYSTEM_H
#define RECOGNIZESYSTEM_H
#include <QObject>
#include <QDataStream>
#include <QTcpSocket>
#include <mainwindow.h>
#include <Core\tools.h>
#include <Core\UpdateController.h>
class UpdateController;
class RecognizeSystem : public QObject
{
Q_OBJECT
public:
explicit RecognizeSystem(QObject *parent = 0);
~RecognizeSystem();
void Initialize(UpdateController* updateController);
void SetSocket(QTcpSocket *socket);
void Recognize();
signals:
void UpdateBytesAvailable(qint64 size,quint64 sended);
void LoadComplete();
void onNeedUpdate(bool flag);
void onSendDebugLog(QString message);
private:
UpdateController *updateController;
QTcpSocket *socket;
PacketType packetType;
QString message;
QString filePath;
QByteArray tmpBlock;
qint64 sizeReceiveData;
qint64 fileSize;
int countSend;
};
#endif // RECOGNIZESYSTEM_H

24
Core/screenchecker.cpp Normal file
View File

@@ -0,0 +1,24 @@
#include "screenchecker.h"
ScreenChecker::ScreenChecker()
{
screenCount = 0;
}
void ScreenChecker::Check()
{
screens = QGuiApplication::screens();
for (int i = 0; i < screens.size();i++){
qDebug() << screens[i]->name();
screenCount++;
}
qDebug() << "Now worked: " << screenCount <<" displays" << endl;
}
QString ScreenChecker::getScreenCount() const
{
return QString::number(screenCount);
}

21
Core/screenchecker.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef SCREENCHECKER_H
#define SCREENCHECKER_H
#include <QObject>
#include <QScreen>
#include <QGuiApplication>
#include <QDebug>
class ScreenChecker
{
public:
ScreenChecker();
void Check();
QString getScreenCount() const;
private:
qint64 screenCount;
QList<QScreen *> screens;
};
#endif // SCREENCHECKER_H

100
Core/tcpclient.cpp Normal file
View File

@@ -0,0 +1,100 @@
#include "tcpclient.h"
#include "UpdateController.h"
#include "externalexecuter.h"
#include <QDir>
TCPClient::TCPClient(QObject *parent) :
QObject(parent)
{
socket = new QTcpSocket(this);
connect(socket,&QTcpSocket::readyRead,this,&TCPClient::onReadyRead);
}
void TCPClient::Initialize(UpdateController *updateController,
RecognizeSystem *recognize,
ExternalExecuter *externalExecuter)
{
this->updateController = updateController;
this->recognizeSystem = recognize;
this->externalExecuter = externalExecuter;
recognize->SetSocket(socket);
emit onSendDebugLog(Tools::GetTime() + " Client started");
}
void TCPClient::SetConnect(ServerSettings *serverSettings)
{
socket->connectToHost(serverSettings->Address,serverSettings->Port.toShort());
emit onSendDebugLog("Try connect...");
socket->waitForReadyRead();
if(socket->state() != QTcpSocket::ConnectedState){
emit onSendDebugLog("Connect invalid");
return;
}
}
void TCPClient::WaitWrites()
{
socket->waitForBytesWritten();
}
QTcpSocket *TCPClient::GetSocket()
{
return socket;
}
TCPClient::~TCPClient()
{
}
void TCPClient::onMessageEntered(QString message)
{
QDataStream stream(socket);
QByteArray data;
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
if(!message.isEmpty() && socket->state() == QTcpSocket::ConnectedState){
socket->waitForBytesWritten();
if(message == "check")
{
stream << PacketType::TYPE_COMMAND;
stream << message;
socket->waitForBytesWritten();
updateController->SendFile(stream);
emit onSendDebugLog(Tools::GetTime() + " Local checkFile sended");
WaitWrites();
socket->readyRead();
}
else if(message == "update"){
emit onSendDebugLog("Update started");
stream << PacketType::TYPE_COMMAND;
stream << message;
socket->waitForBytesWritten();
}
else if(message == "run"){
externalExecuter->CallApp();
}
}else{
emit onSendDebugLog("WRONG SOCKET AFTER ENTERED");
}
}
void TCPClient::onReadyRead()
{
if(!socket){
emit onSendDebugLog("WRONG SOCKET");
return;
}
//возврат на случай недоступного сокета
recognizeSystem->Recognize();
}

46
Core/tcpclient.h Normal file
View File

@@ -0,0 +1,46 @@
#ifndef TCPCLIENT_H
#define TCPCLIENT_H
#include <QObject>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDataStream>
#include <QTcpServer>
#include <QFile>
#include <QCoreApplication>
#include "Core\recognizesystem.h"
#include "Core\tools.h"
#include "Core\UpdateController.h"
#include "Core\externalexecuter.h"
class UpdateController;
class RecognizeSystem;
class TCPClient : public QObject
{
Q_OBJECT
public:
explicit TCPClient(QObject *parent = 0);
void Initialize(UpdateController *updateController,RecognizeSystem *recognize,ExternalExecuter *externalExecuter);
void SetConnect(ServerSettings *serverSettings);
void WaitWrites();
QTcpSocket* GetSocket();
~TCPClient();
signals:
void onSendDebugLog(QString message);
public slots:
void onMessageEntered(QString message);
private slots:
void onReadyRead();
private:
QTcpSocket *socket;
UpdateController *updateController;
RecognizeSystem *recognizeSystem;
ExternalExecuter * externalExecuter;
};
#endif // TCPCLIENT_H

38
Core/tools.cpp Normal file
View File

@@ -0,0 +1,38 @@
#include "tools.h"
#include <qdir.h>
void Tools::PrintTime()
{
qDebug() << QTime::currentTime().toString("hh:mm:ss");
}
QString Tools::GetTime()
{
return QTime::currentTime().toString(("hh:mm:ss"));
}
QString Tools::CreateLocalPath(QString path)
{
qDebug() << "Full path: " << path;
qint8 pos = path.indexOf("Application");
QString localPath = path.remove(0,--pos);
qDebug() << "Local path: " << localPath;
return localPath;
}
QString Tools::CreateFullPath(QString path)
{
QString fullPath;
qint8 pos = path.indexOf("Application");
QString localPath = path.remove(0,--pos);
qDebug() << "CLIENT: localPath" << localPath;
fullPath = QDir::currentPath() + localPath;
return fullPath;
}

33
Core/tools.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef GLOBAL_H
#define GLOBAL_H
#include <QString>
#include <QTime>
#include <QDebug>
#define TCP_READ_TIMEOUT 1000
static QString hashFilename = "hash.xml";
static QString settingsName = "settings.xml";
enum PacketType{
TYPE_NONE = 0,
TYPE_MSG = 1,
TYPE_FILE = 2,
TYPE_COMMAND = 3,
TYPE_FOLDER = 4,
TYPE_DELETE = 5,
TYPE_FINISH = 6,
TYPE_NEEDUPDATE =7
};
class Tools {
public:
static void PrintTime();
static QString GetTime();
static QString CreateLocalPath(QString path);
static QString CreateFullPath(QString path);
};
#endif // GLOBAL_H