This commit is contained in:
2025-12-05 11:48:24 +03:00
parent 63cd6a71d1
commit 57673d0ee4
160 changed files with 315 additions and 315 deletions

View File

@@ -0,0 +1,3 @@
{
"CurrentProjectSetting": "Нет конфигураций"
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,7 @@
{
"ExpandedNodes": [
""
],
"SelectedNode": "\\processingsystem.cpp",
"PreviewInSolutionExplorer": false
}

Binary file not shown.

View File

@@ -0,0 +1,127 @@
#include "clientanswerparser.h"
ClientAnswerParser::ClientAnswerParser(QObject *parent) : QObject(parent)
{
}
void ClientAnswerParser::initialize(DataParser *dataParser)
{
this->dataParser = dataParser;
}
QByteArray ClientAnswerParser::authorization(bool result, QString instructorName,QString clientName, QString accessType, QString login, int id)
{
QList<SXmlAnswerTag> listTag;
SAttribute attribute1 = {"Result", result? "true" : "false"};
SAttribute attribute2 = {"InstructorName", instructorName};
SAttribute attribute3 = {"ClientName", clientName};
SAttribute attribute4 = {"AccessType", accessType};
SAttribute attribute5 = {"Login", login};
SAttribute attribute6 = {"id_client", QString::number(id)};
QList<SAttribute> listAttr = {attribute1, attribute2, attribute3, attribute4, attribute5, attribute6};
SXmlAnswerTag tag = {"ServerAuthorization", listAttr};
listTag.append(tag);
return dataParser->xmlAnswer(listTag);
}
QByteArray ClientAnswerParser::deAuthorization(bool result, QString login)
{
QList<SXmlAnswerTag> listTag;
SAttribute attribute1 = {"Result", result? "true" : "false"};
SAttribute attribute2 = {"Login", login};
QList<SAttribute> listAttr = {attribute1, attribute2};
SXmlAnswerTag tag = {"ServerDeAuthorization", listAttr};
listTag.append(tag);
return dataParser->xmlAnswer(listTag);
}
QByteArray ClientAnswerParser::message(QString loginFrom,QString loginTo,QString text)
{
QList<SXmlAnswerTag> listTag;
QList<SAttribute> listAttr;
SAttribute attribute1;
attribute1 = {"From",loginFrom};
listAttr.append(attribute1);
attribute1 = {"To",loginTo};
listAttr.append(attribute1);
attribute1 = {"Text",text};
listAttr.append(attribute1);
SXmlAnswerTag tag = {"ClientMessage", listAttr};
listTag.append(tag);
return dataParser->xmlAnswer(listTag);
}
QByteArray ClientAnswerParser::task(QString text)
{
QList<SXmlAnswerTag> listTag;
SAttribute attribute1 = {"Text", text};
QList<SAttribute> listAttr = {attribute1};
SXmlAnswerTag tag = {"ServerTask", listAttr};
listTag.append(tag);
return dataParser->xmlAnswer(listTag);
}
QByteArray ClientAnswerParser::notify(QString code)
{
QList<SXmlAnswerTag> listTag;
SAttribute attribute1 = {"Code", code};
QList<SAttribute> listAttr = {attribute1};
SXmlAnswerTag tag = {"ServerNotify", listAttr};
listTag.append(tag);
return dataParser->xmlAnswer(listTag);
}
QByteArray ClientAnswerParser::tasks(QStringList listTasks)
{
QList<SXmlAnswerTag> listTag;
foreach(QString task, listTasks)
{
QList<SAttribute> listAttr;
SAttribute attribute1 = {"Head", task};
SAttribute attribute2 = {"IsComplete", "false"};
listAttr.append(attribute1);
listAttr.append(attribute2);
SXmlAnswerTag tag = {"ServerTask", listAttr};
listTag.append(tag);
}
return dataParser->xmlAnswer(listTag, "TaskArray", "Tasks");
}
QByteArray ClientAnswerParser::currentVersion()
{
QByteArray array;
QFile fileR(version);
if (!fileR.open(QFile::ReadOnly | QFile::Text))
{
QString str = "Не удалось открыть файл";
qDebug() << "xmlAnswer: " << str;
}
else
{
array = fileR.readAll();
fileR.close(); // Закрываем файл
}
return array;
}

View File

@@ -0,0 +1,30 @@
#ifndef CLIENTANSWERPARSER_H
#define CLIENTANSWERPARSER_H
#include <QObject>
#include <Systems/Parsers/dataparser.h>
#include <Data/typesDataServerClient.h>
class ClientAnswerParser : public QObject
{
Q_OBJECT
public:
explicit ClientAnswerParser(QObject *parent = nullptr);
void initialize(DataParser *dataParser);
QByteArray authorization(bool result, QString instructorName, QString clientName, QString accessType, QString login, int id);
QByteArray deAuthorization(bool result, QString login);
QByteArray message(QString loginFrom,QString loginTo,QString text);
QByteArray task(QString text);
QByteArray notify(QString code);
QByteArray tasks(QStringList listTasks);
QByteArray currentVersion();
signals:
private:
DataParser *dataParser;
};
#endif // CLIENTANSWERPARSER_H

View File

@@ -0,0 +1,139 @@
#include "dataparser.h"
#include <QFile>
#include <QDomDocument>
DataParser::DataParser(AssetsManager *assetManager,ProcessingSystem *processingSystem,QObject *parent) :
QObject(parent)
{
this->processingSystem = processingSystem;
this->assetsManager = assetManager;
clientAnswer = new ClientAnswerParser;
clientAnswer->initialize(this);
dbAnswer = new DBAnswerParser;
dbAnswer->initialize(this);
docsAnswer = new DocsAnswerParser;
processParser = new ProcessParser;
processParser->initialize(processingSystem);
mutex = new QMutex;
qDebug() << "ParserThread: " << QThread::currentThreadId();
}
QByteArray DataParser::xmlAnswer(QList<SXmlAnswerTag> listTag, QString elemUp1, QString elemUp2)
{
try {
mutex->lock();
/* Открываем файл для Записи*/
QFile file(tempFile);
file.open(QIODevice::WriteOnly);
/* Создаем объект, с помощью которого осуществляется запись в файл */
QXmlStreamWriter xmlWriter(&file);
xmlWriter.setAutoFormatting(true); // Устанавливаем автоформатирование текста
xmlWriter.writeStartDocument(); // Запускаем запись в документ
if(elemUp1 != "")
xmlWriter.writeStartElement(elemUp1); // Записываем тег
if(elemUp2 != "")
xmlWriter.writeStartElement(elemUp2); // Записываем тег
//Записываем все элементы
foreach(SXmlAnswerTag tag, listTag)
{
xmlWriter.writeStartElement(tag.elementName); // Записываем тег
// Записываем атрибуты
foreach(SAttribute attr, tag.attr)
xmlWriter.writeAttribute(attr.name, attr.value);
xmlWriter.writeEndElement(); // Закрываем тег
}
if(elemUp1 != "")
xmlWriter.writeEndElement(); // Закрываем тег
if(elemUp1 != "")
xmlWriter.writeEndElement(); // Закрываем тег
/* Завершаем запись в документ*/
xmlWriter.writeEndDocument();
file.close(); // Закрываем файл
QByteArray array;
array = readTempFile();
mutex->unlock();
return array;
}
catch(const std::exception& e)
{
qDebug() << e.what();
return nullptr;
}
}
QByteArray DataParser::readTempFile()
{
QByteArray array;
QFile fileR(tempFile);
if (!fileR.open(QFile::ReadOnly | QFile::Text))
{
QString str = "Не удалось открыть файл";
qDebug() << "xmlAnswer: " << str;
}
else
{
array = fileR.readAll();
fileR.close();
}
return array;
}
ClientAnswerParser *DataParser::ClientAnswer() const
{
return clientAnswer;
}
DBAnswerParser *DataParser::DbAnswer() const
{
return dbAnswer;
}
ProcessParser *DataParser::getProcessParser() const
{
return processParser;
}
DocsAnswerParser *DataParser::getDocsAnswerParser() const
{
return docsAnswer;
}
DataParser::~DataParser()
{
delete clientAnswer;
delete dbAnswer;
delete docsAnswer;
delete processParser;
delete mutex;
}

View File

@@ -0,0 +1,64 @@
#ifndef DATAPARSER_H
#define DATAPARSER_H
#include "Systems/processingsystem.h"
#include "Systems/tools.h"
#include "Systems/assetsmanager.h"
#include "Systems/logger.h"
#include "Systems/Parsers/clientanswerparser.h"
#include "dbanswerparser.h"
#include "docsanswerparser.h"
#include "processparser.h"
#include "serverlmswidget.h"
#include <QByteArray>
#include <QXmlStreamReader>
#include <QDebug>
#include <QDomDocument>
#include <Data/typesDataServerClient.h>
#include <Data/StreamingVersionData.h>
class ProcessingSystem;
class ClientHandler;
class AssetsManager;
class ClientAnswerParser;
class DBAnswerParser;
class DocsAnswerParser;
class ProcessParser;
class DataParser : public QObject
{
Q_OBJECT
public:
DataParser(AssetsManager *assetManager,ProcessingSystem *processingSystem,QObject* parent = nullptr);
void xmlParser(ClientHandler *client, QByteArray array);
void xmlFileDataParse(QByteArray array);
QByteArray xmlAnswer(QList<SXmlAnswerTag> listTag,QString elemUp1 = "", QString elemUp2 = "");
~DataParser();
ClientAnswerParser *ClientAnswer() const;
DBAnswerParser *DbAnswer() const;
ProcessParser *getProcessParser() const;
DocsAnswerParser *getDocsAnswerParser() const;
signals:
void sigLogMessage(QString log);
private:
QMutex *mutex;
ProcessingSystem *processingSystem;
AssetsManager *assetsManager;
ClientAnswerParser *clientAnswer;
DBAnswerParser *dbAnswer;
DocsAnswerParser* docsAnswer;
ProcessParser *processParser;
QByteArray readTempFile();
};
#endif // DATAPARSER_H

View File

@@ -0,0 +1,249 @@
#include "dbanswerparser.h"
DBAnswerParser::DBAnswerParser(QObject *parent) : QObject(parent)
{
}
void DBAnswerParser::initialize(DataParser *dataParser)
{
this->dataParser = dataParser;
}
QByteArray DBAnswerParser::listInstructors(bool result, QList<Instructor> *listInstructors)
{
QDomDocument commonDOM;
if(! Tools::loadXMLtoDOM(":/resources/blankXML/ListInstructors.xml", &commonDOM))
return QByteArray();
QDomNode listNode = commonDOM.namedItem("ListInstructors");
for(Instructor instructor : *listInstructors)
{
//Инструктор
QDomNode instructorNode = commonDOM.createElement("Instructor");
listNode.appendChild(instructorNode);
instructorNode.toElement().setAttribute("instructor_id", QString::number(instructor.getID()));
instructorNode.toElement().setAttribute("name", instructor.getName());
instructorNode.toElement().setAttribute("login", instructor.getLogin());
instructorNode.toElement().setAttribute("password", instructor.getPassword());
instructorNode.toElement().setAttribute("is_admin", instructor.getIsAdmin());
instructorNode.toElement().setAttribute("archived", instructor.getArchived());
instructorNode.toElement().setAttribute("logged_in", instructor.getLoggedIn());
}
Tools::saveDOMtoXML("ListInstructors.xml", &commonDOM);
return commonDOM.toByteArray();
}
QByteArray DBAnswerParser::listGroups(bool result, QList<Group> *listGroups)
{
QDomDocument commonDOM;
if(! Tools::loadXMLtoDOM(":/resources/blankXML/ListGroups.xml", &commonDOM))
return QByteArray();
QDomNode listNode = commonDOM.namedItem("ListGroups");
for(Group group : *listGroups)
{
//Группа
QDomNode groupNode = commonDOM.createElement("Group");
listNode.appendChild(groupNode);
groupNode.toElement().setAttribute("group_id", QString::number(group.getID()));
groupNode.toElement().setAttribute("name", group.getName());
}
Tools::saveDOMtoXML("ListGroups.xml", &commonDOM);
return commonDOM.toByteArray();
}
QByteArray DBAnswerParser::listTrainees(bool result, QList<Trainee> *listTrainees)
{
QDomDocument commonDOM;
if(! Tools::loadXMLtoDOM(":/resources/blankXML/ListTrainees.xml", &commonDOM))
return QByteArray();
QDomNode listNode = commonDOM.namedItem("ListTrainees");
for(Trainee trainee : *listTrainees)
{
//Обучаемый
QDomNode traineeNode = commonDOM.createElement("Trainee");
listNode.appendChild(traineeNode);
traineeNode.toElement().setAttribute("trainee_id", trainee.getID());
traineeNode.toElement().setAttribute("name", trainee.getName());
traineeNode.toElement().setAttribute("login", trainee.getLogin());
traineeNode.toElement().setAttribute("password", trainee.getPassword());
traineeNode.toElement().setAttribute("archived", trainee.getArchived());
traineeNode.toElement().setAttribute("logged_in", trainee.getLoggedIn());
traineeNode.toElement().setAttribute("group_trainee", trainee.getGroup().getID());
traineeNode.toElement().setAttribute("computer_trainee", trainee.getComputer().getID());
//trainee.setTasks()
//Тайминг
QDomNode timingNode = commonDOM.createElement("timing");
traineeNode.appendChild(timingNode);
TimingOfTrainee timing = trainee.getTiming();
timingNode.toElement().setAttribute("entryTime", timing.getEntryTimeS());
timingNode.toElement().setAttribute("exitTime", timing.getExitTimeS());
timingNode.toElement().setAttribute("operatingTime", timing.getOperatingTimeS());
}
Tools::saveDOMtoXML("ListTrainees.xml", &commonDOM);
return commonDOM.toByteArray();
}
QByteArray DBAnswerParser::listComputers(bool result, QList<Computer> *listComputers)
{
//TODO
return QByteArray();
}
QByteArray DBAnswerParser::listClassrooms(bool result, QList<Classroom> *listClassrooms)
{
//TODO
return QByteArray();
}
QByteArray DBAnswerParser::listContacts(bool result, QList<ContactModel> *listContacts)
{
QDomDocument doc;
QDomProcessingInstruction xmlDecl = doc.createProcessingInstruction("xml", "version='1.0' encoding='utf-8'");
doc.insertBefore(xmlDecl,doc.firstChild());
QDomElement root = doc.createElement("ContactArray");
for(ContactModel entity : *listContacts)
{
QDomElement contact = doc.createElement("ContactData");
contact.toElement().setAttribute("name",entity.getName());
contact.toElement().setAttribute("id",entity.getID());
QString isLogged = entity.getLoggedIn() ? "1" : "0";
contact.toElement().setAttribute("isOnline",isLogged);
contact.toElement().setAttribute("UserType",entity.getType());
contact.toElement().setAttribute("Login",entity.getLogin());
root.appendChild(contact);
}
doc.appendChild(root);
qDebug() << doc.toString();
return doc.toByteArray();
}
QByteArray DBAnswerParser::listTasksAMMofTrainee(bool result, QList<TaskAmmFim> *listTasks, int trainee_id, bool full_list)
{
QDomDocument commonDOM;
if(! Tools::loadXMLtoDOM(":/resources/blankXML/ListTasksAMM.xml", &commonDOM))
return QByteArray();
QDomNode listNode = commonDOM.namedItem("ListTasksAMM");
listNode.toElement().setAttribute("trainee_id", QString::number(trainee_id));
if(full_list)
listNode.toElement().setAttribute("full_list", "true");
else
listNode.toElement().setAttribute("full_list", "false");
for(TaskAmmFim task : *listTasks)
{
//Задача
QDomNode taskNode = commonDOM.createElement("taskAMM");
listNode.appendChild(taskNode);
taskNode.toElement().setAttribute("task_id", QString::number(task.getID()));
taskNode.toElement().setAttribute("title", task.ammProcedure.title);
taskNode.toElement().setAttribute("dmCode", task.ammProcedure.dmCode);
taskNode.toElement().setAttribute("status", task.status);
for(SubProc subProc : task.listSubProc)
{//Подпроцедура
QDomNode subProcNode = commonDOM.createElement("SubProc");
taskNode.appendChild(subProcNode);
subProcNode.toElement().setAttribute("dmCode", subProc.getDmCode());
subProcNode.toElement().setAttribute("title", subProc.getTitle());
subProcNode.toElement().setAttribute("canplay", subProc.getModeListStr());
}
}
Tools::saveDOMtoXML("ListTasksAMM.xml", &commonDOM);
return commonDOM.toByteArray();
}
QByteArray DBAnswerParser::listTasksFIMofTrainee(bool result, QList<TaskAmmFim> *listTasks, int trainee_id, bool full_list)
{
QDomDocument commonDOM;
if(! Tools::loadXMLtoDOM(":/resources/blankXML/ListTasksFIM.xml", &commonDOM))
return QByteArray();
QDomNode listNode = commonDOM.namedItem("ListTasksFIM");
listNode.toElement().setAttribute("trainee_id", QString::number(trainee_id));
if(full_list)
listNode.toElement().setAttribute("full_list", "true");
else
listNode.toElement().setAttribute("full_list", "false");
for(TaskAmmFim task : *listTasks)
{
//Задача
QDomNode taskNode = commonDOM.createElement("taskFIM");
listNode.appendChild(taskNode);
taskNode.toElement().setAttribute("task_id", QString::number(task.getID()));
taskNode.toElement().setAttribute("title", task.title);
taskNode.toElement().setAttribute("status", task.status);
for(Malfunction malfunction : task.malfunctionList)
{//Неисправность
QDomNode malfunctionNode = commonDOM.createElement("malfunction");
taskNode.appendChild(malfunctionNode);
malfunctionNode.toElement().setAttribute("dmCode", malfunction.dmCode);
malfunctionNode.toElement().setAttribute("num", malfunction.num);
malfunctionNode.toElement().setAttribute("description", malfunction.description);
for(MalfunctionSign sign : malfunction.malfunctionSigns)
{//Сигналы
QDomNode signNode = commonDOM.createElement("malfunctionSign");
malfunctionNode.appendChild(signNode);
signNode.toElement().setAttribute("type", sign.type);
signNode.toElement().setAttribute("description", sign.description);
}
}
{//FIMReport
FIMReport report = task.report;
QDomNode reportNode = commonDOM.createElement("report");
taskNode.appendChild(reportNode);
reportNode.toElement().setAttribute("report_id", report.id);
for(FIMReportItem reportItem : task.report.itemList)
{//FIMReportItem
QDomNode reportItemNode = commonDOM.createElement("reportItem");
reportNode.appendChild(reportItemNode);
reportItemNode.toElement().setAttribute("item_id", reportItem.id);
reportItemNode.toElement().setAttribute("text", reportItem.text);
//ProcedureID
QDomNode procedureIDNode = commonDOM.createElement("procedureID");
reportItemNode.appendChild(procedureIDNode);
procedureIDNode.toElement().setAttribute("doc", reportItem.procedure.doc);
procedureIDNode.toElement().setAttribute("title", reportItem.procedure.title);
procedureIDNode.toElement().setAttribute("dmCode", reportItem.procedure.dmCode);
procedureIDNode.toElement().setAttribute("result", reportItem.procedure.result);
}
}
}
Tools::saveDOMtoXML("ListTasksFIM.xml", &commonDOM);
return commonDOM.toByteArray();
}

View File

@@ -0,0 +1,33 @@
#ifndef DBANSWERPARSER_H
#define DBANSWERPARSER_H
#include "dataparser.h"
#include "serverlmswidget.h"
#include <QObject>
#include <QDomDocument>
#include <contactModel.h>
class DBAnswerParser : public QObject
{
Q_OBJECT
public:
explicit DBAnswerParser(QObject *parent = nullptr);
void initialize(DataParser *dataParser);
QByteArray listInstructors(bool result, QList<Instructor> *listInstructors);
QByteArray listGroups(bool result, QList<Group> *listGroups);
QByteArray listTrainees(bool result, QList<Trainee> *listTrainees);
QByteArray listComputers(bool result, QList<Computer> *listComputers);
QByteArray listClassrooms(bool result, QList<Classroom> *listClassrooms);
QByteArray listContacts(bool result, QList<ContactModel> *listContacts);
QByteArray listTasksAMMofTrainee(bool result, QList<TaskAmmFim> *listTasks, int trainee_id, bool full_list);
QByteArray listTasksFIMofTrainee(bool result, QList<TaskAmmFim> *listTasks, int trainee_id, bool full_list);
signals:
private:
DataParser *dataParser;
};
#endif // DBANSWERPARSER_H

View File

@@ -0,0 +1,30 @@
#include "docsanswerparser.h"
#include "docsupdater.h"
DocsAnswerParser::DocsAnswerParser(QObject *parent) : QObject(parent)
{
}
QByteArray DocsAnswerParser::listSubProc(QList<SubProc> list, QString dmCode)
{
QDomDocument commonDOM;
if(! Tools::loadXMLtoDOM(":/resources/blankXML/ListSubProc.xml", &commonDOM))
return QByteArray();
QDomNode listNode = commonDOM.namedItem("ListSubProc");
listNode.toElement().setAttribute("dmCode", dmCode);
for(SubProc subProc : list)
{
QDomNode subProcNode = commonDOM.createElement("SubProc");
listNode.appendChild(subProcNode);
subProcNode.toElement().setAttribute("dmCode", subProc.getDmCode());
subProcNode.toElement().setAttribute("title", subProc.getTitle());
subProcNode.toElement().setAttribute("canplay", subProc.getModeListStr());
}
Tools::saveDOMtoXML("ListSubProc.xml", &commonDOM);
return commonDOM.toByteArray();
}

View File

@@ -0,0 +1,23 @@
#ifndef DOCSANSWERPARSER_H
#define DOCSANSWERPARSER_H
#include <QObject>
#include <QList>
#include "docsupdater.h"
struct SubProc;
class DocsAnswerParser : public QObject
{
Q_OBJECT
public:
explicit DocsAnswerParser(QObject *parent = nullptr);
public:
QByteArray listSubProc(QList<SubProc> list, QString dmCode);
signals:
};
#endif // DOCSANSWERPARSER_H

View File

@@ -0,0 +1,606 @@
#include "processparser.h"
#include "tasksAmmFim.h"
ProcessParser::ProcessParser(QObject *parent) : QObject(parent) //TODO: переименовать в XMLProcessParser?
{
}
void ProcessParser::initialize(ProcessingSystem *processingSystem)
{
this->processingSystem = processingSystem;
}
void ProcessParser::slot_read(ClientHandler *client, QByteArray array)
{
QXmlStreamReader xmlReader(array);
xmlReader.readNext(); // Переходим к первому элементу в файле
//Крутимся в цикле до тех пор, пока не достигнем конца документа
while(!xmlReader.atEnd())
{
//Проверяем, является ли элемент началом тега
if(xmlReader.isStartElement())
{
//Анализируем теги
if(xmlReader.name() == "ClientAutorization")
{//Запрос авторизации от клиента
clientAuth(xmlReader,client);
}
else if(xmlReader.name() == "ClientDeAutorization")
{//Запрос ДеАвторизации от клиента
clientDeAuth(xmlReader,client);
}
else if(xmlReader.name() == "QueryToDB")
{//Запрос к базе данных от клиента
queryToDb(xmlReader,client, array);
}
else if(xmlReader.name() == "QueryTasksXML")
{//Запрос файла XML с задачами
queryTasksXML(xmlReader,client);
}
else if(xmlReader.name() == "QueryListSubProc")
{//Запрос списка подпроцедур
queryListSubProc(xmlReader,client);
}
else if(xmlReader.name() == "ClientMessage")
{//Сообщение от клиента
clientMessage(xmlReader,client);
}
else if(xmlReader.name() == "ClientNotify")
{//Уведомление от клиента
clientNotify(xmlReader,client);
}
else if(xmlReader.name() == "DataInfo")
{
clientDataInfo(xmlReader,client);
}
else if(xmlReader.name() == "ListTasksAMM")
{
if(client->getClient()->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{//Отчет по задаче АММ от Юнити-клиента
clientUnityTaskAMMreport(xmlReader,client, array);
}
}
else if(xmlReader.name() == "ListTasksFIM")
{
if(client->getClient()->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{//Отчет по задаче FIM от Юнити-клиента
clientUnityTaskFIMreport(xmlReader,client, array);
}
}
else if(xmlReader.name() == "BlockAuth")
{//Запрос Блокировки Авторизации от клиента ГУИ
clientBlockAuth(xmlReader,client);
}
else
{
emit sigLogMessage("XmlParser: unrecognized tag");
}
}
xmlReader.readNext(); // Переходим к следующему элементу файла
}//while(!xmlReader.atEnd())
}
void ProcessParser::clientDataInfo(QXmlStreamReader &xmlReader,ClientHandler *client)
{
DataInfo *dataInfo = new DataInfo;
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
if(name == "path")
dataInfo->path= value.toUtf8();
if(name == "size")
dataInfo->size = value.toLong();
}
processingSystem->setCurrentDataInfo(dataInfo);
}
void ProcessParser::clientUnityTaskAMMreport(QXmlStreamReader &xmlReader, ClientHandler *client, QByteArray array)
{
QDomDocument commonDOM;
commonDOM.setContent(array);
QList<TaskAmmFim> listTasks;
int trainee_id = 0;
QDomNode listNode = commonDOM.namedItem("ListTasksAMM");
trainee_id = listNode.toElement().attribute("trainee_id").toInt();
for(int i = 0; i < listNode.childNodes().count(); i++)
{
QDomNode taskNode = listNode.childNodes().at(i);
if(taskNode.nodeName() == "taskAMM")
{//Задача
TaskAmmFim task;
task.setID(taskNode.toElement().attribute("task_id").toInt());
task.ammProcedure.title = taskNode.toElement().attribute("title");
task.ammProcedure.dmCode = taskNode.toElement().attribute("dmCode");
task.status = taskNode.toElement().attribute("status");
listTasks.append(task);
//Изменение задачи
void* data = nullptr;
data = &task;
ClientQueryToDB queryToDB;
queryToDB.typeQuery = TypeQueryToDB::TYPE_QUERY_SET_REPORT_TASK_AMM_TO_TRAINEE;
processingSystem->processingClientQueryToDB(client, queryToDB, trainee_id, data);
}
}
emit processingSystem->sigStatusTasksAMMofTraineeChanged(trainee_id);
}
void ProcessParser::clientUnityTaskFIMreport(QXmlStreamReader &xmlReader, ClientHandler *client, QByteArray array)
{
QDomDocument commonDOM;
commonDOM.setContent(array);
QList<TaskAmmFim> listTasks;
int trainee_id = 0;
QDomNode listNode = commonDOM.namedItem("ListTasksFIM");
trainee_id = listNode.toElement().attribute("trainee_id").toInt();
for(int i = 0; i < listNode.childNodes().count(); i++)
{//Задачи
QDomNode taskNode = listNode.childNodes().at(i);
if(taskNode.nodeName() == "taskFIM")
{
TaskAmmFim task;
task.setID(taskNode.toElement().attribute("task_id").toInt());
task.title = taskNode.toElement().attribute("title");
task.status = taskNode.toElement().attribute("status");
for(int j = 0; j < taskNode.childNodes().count(); j++)
{//Неисправности
QDomNode malfOrReportNode = taskNode.childNodes().at(j);
if(malfOrReportNode.nodeName() == "malfunction")
{
/*
Malfunction malfunction;
malfunction.num = malfunctionNode.toElement().attribute("num");
malfunction.dmCode = malfunctionNode.toElement().attribute("dmCode");
malfunction.description = malfunctionNode.toElement().attribute("description");
task.malfunctionList.append(malfunction);
*/
}
else
if(malfOrReportNode.nodeName() == "report")
{//Отчет
FIMReport report;
report.id = 0; //malfOrReportNode.toElement().attribute("report_id").toInt();
for(int k = 0; k < malfOrReportNode.childNodes().count(); k++)
{
QDomNode reportItemNode = malfOrReportNode.childNodes().at(k);
if(reportItemNode.nodeName() == "item")
{
FIMReportItem reportItem;
reportItem.id = 0; //reportItemNode.toElement().attribute("item_id").toInt();
reportItem.text = reportItemNode.toElement().attribute("title");
if(reportItemNode.childNodes().count())
{
QDomNode procedureIDNode = reportItemNode.childNodes().at(0);
reportItem.procedure.doc = procedureIDNode.toElement().attribute("doc");
reportItem.procedure.title = procedureIDNode.toElement().attribute("title");
reportItem.procedure.dmCode = procedureIDNode.toElement().attribute("dmCode");
reportItem.procedure.result = procedureIDNode.toElement().attribute("result");
}
report.itemList.append(reportItem);
}
}
task.report = report;
}
}
/*
//TODO -------------- (!Заглушка!) Отчет о выполнении
FIMReport report;
FIMReportItem reportItem;
QString text; // текст, вводимый обучаемым
ProcedureID procedure; // ссылка на процедуру, при необходимости
text = "1. Выполнил такую процедуру";
procedure.doc = "fim";
procedure.title = "Процедура №1";
procedure.dmCode = "RRJ-N-27-92-00-51D01-420A-A";
procedure.result = "viewed";
reportItem.text = text;
reportItem.procedure = procedure;
report.itemList.append(reportItem);
text = "2. Выполнил такую процедуру";
procedure.doc = "fim";
procedure.title = "Процедура №2";
procedure.dmCode = "RRJ-N-28-22-00-01A01-420A-A";
procedure.result = "viewed";
reportItem.text = text;
reportItem.procedure = procedure;
report.itemList.append(reportItem);
task.report = report;
//-----------------
*/
listTasks.append(task);
//Изменение задачи
void* data = nullptr;
data = &task;
ClientQueryToDB queryToDB;
queryToDB.typeQuery = TypeQueryToDB::TYPE_QUERY_SET_REPORT_TASK_FIM_TO_TRAINEE;
processingSystem->processingClientQueryToDB(client, queryToDB, trainee_id, data);
}
}
emit processingSystem->sigStatusTasksFIMofTraineeChanged(trainee_id);
}
TaskAmmFim ProcessParser::xmlParserQueryToDB_ASSIGN_TASK_FIM_TO_TRAINEE(QByteArray array)
{
TaskAmmFim task;
QDomDocument commonDOM;
commonDOM.setContent(array);
QDomNode mainNode = commonDOM.namedItem("QueryToDB");
task.title = mainNode.toElement().attribute("title");
for(int i = 0; i < mainNode.childNodes().count(); i++)
{
QDomNode malfunctionNode = mainNode.childNodes().at(i);
if(malfunctionNode.nodeName() == "malfunction")
{//Неисправность
Malfunction malfunction;
malfunction.num = malfunctionNode.toElement().attribute("num");
malfunction.dmCode = malfunctionNode.toElement().attribute("dmCode");
malfunction.description = malfunctionNode.toElement().attribute("description");
//Сигналы
for(int j = 0; j < malfunctionNode.childNodes().count(); j++)
{
QDomNode signNode = malfunctionNode.childNodes().at(j);
if(signNode.nodeName() == "malfunctionSign")
{
MalfunctionSign sign;
sign.type = signNode.toElement().attribute("type").toInt();
sign.description = signNode.toElement().attribute("description");
malfunction.malfunctionSigns.append(sign);
}
}
task.malfunctionList.append(malfunction);
}
}
return task;
}
TaskAmmFim ProcessParser::xmlParserQueryToDB_ASSIGN_TASK_AMM_TO_TRAINEE(QByteArray array)
{
TaskAmmFim task;
QDomDocument commonDOM;
commonDOM.setContent(array);
QDomNode mainNode = commonDOM.namedItem("QueryToDB");
task.ammProcedure.title = mainNode.toElement().attribute("title");
task.ammProcedure.dmCode = mainNode.toElement().attribute("dmCode");
for(int i = 0; i < mainNode.childNodes().count(); i++)
{
QDomNode subProcNode = mainNode.childNodes().at(i);
if(subProcNode.nodeName() == "SubProc")
{//Подпроцедура
SubProc subProc;
subProc.setTitle(subProcNode.toElement().attribute("title"));
subProc.setDmCode(subProcNode.toElement().attribute("dmCode"));
subProc.setModeListStr(subProcNode.toElement().attribute("canplay"));
task.listSubProc.append(subProc);
}
}
return task;
}
void ProcessParser::clientAuth(QXmlStreamReader &xmlReader,ClientHandler *client)
{
ClientAutorization clientAutorization;
/*Перебираем все атрибуты тега*/
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
//addTextToLogger(name + ": " + value);
if(name == "Login")
clientAutorization.Login = value;
else if(name == "Password")
clientAutorization.Password = value;
else if(name == "NumberOfScreen")
clientAutorization.NumberOfScreen = value.toInt();
else if(name == "TypeClient")
clientAutorization.TypeClient = (TypeClientAutorization)value.toInt();
}
processingSystem->processingClientAutorization(client, clientAutorization);
}
void ProcessParser::clientDeAuth(QXmlStreamReader &xmlReader,ClientHandler *client)
{
ClientDeAutorization clientDeAutorization;
/*Перебираем все атрибуты тега*/
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
//addTextToLogger(name + ": " + value);
if(name == "Login")
clientDeAutorization.Login = value;
}
processingSystem->processingClientDeAutorization(client, clientDeAutorization);
}
void ProcessParser::clientBlockAuth(QXmlStreamReader &xmlReader, ClientHandler *client)
{
bool block = false;
/*Перебираем все атрибуты тега*/
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
//addTextToLogger(name + ": " + value);
if(name == "Block")
block = (value == "1") ? true : false;
}
processingSystem->processingClientBlockAuth(client, block);
}
void ProcessParser::queryToDb(QXmlStreamReader &xmlReader,ClientHandler *client, QByteArray array)
{
ClientQueryToDB queryToDB;
int id = 0;
Instructor instructor;
Trainee trainee;
Group group;
TaskAmmFim task;
QString status = "";
void* data = nullptr;
/*Перебираем все атрибуты тега*/
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
//addTextToLogger(name + ": " + value);
if(name == "TypeQuery")
{
queryToDB.typeQuery = (TypeQueryToDB)value.toInt();
if(queryToDB.typeQuery == TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE)
{
task = xmlParserQueryToDB_ASSIGN_TASK_FIM_TO_TRAINEE(array);
}
else if(queryToDB.typeQuery == TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE)
{
task = xmlParserQueryToDB_ASSIGN_TASK_AMM_TO_TRAINEE(array);
}
}
else if(name == "id")
id = value.toInt();
else
{
switch (queryToDB.typeQuery)
{
case TypeQueryToDB::TYPE_QUERY_NEW_INSTRUCTOR:
case TypeQueryToDB::TYPE_QUERY_EDIT_INSTRUCTOR:
if(name == "instructor_id")
instructor.setID(value.toInt());
else if(name == "name")
instructor.setName(value);
else if(name == "login")
instructor.setLogin(value);
else if(name == "password")
instructor.setPassword(value);
else if(name == "is_admin")
instructor.setIsAdmin(value.toInt());
else if(name == "archived")
instructor.setArchived(value.toInt());
else if(name == "logged_in")
instructor.setLoggedIn(value.toInt());
break;
case TypeQueryToDB::TYPE_QUERY_NEW_TRAINEE:
case TypeQueryToDB::TYPE_QUERY_EDIT_TRAINEE:
if(name == "trainee_id")
trainee.setID(value.toInt());
else if(name == "name")
trainee.setName(value);
else if(name == "login")
trainee.setLogin(value);
else if(name == "password")
trainee.setPassword(value);
else if(name == "archived")
trainee.setArchived(value.toInt());
else if(name == "logged_in")
trainee.setLoggedIn(value.toInt());
else if(name == "group_trainee")
{
Group group(value.toInt(), "");
trainee.setGroup(group);
}
else if(name == "computer_trainee")
{
Computer computer(value.toInt(), "", "", Classroom());
trainee.setComputer(computer);
}
break;
case TypeQueryToDB::TYPE_QUERY_NEW_GROUP:
case TypeQueryToDB::TYPE_QUERY_EDIT_GROUP:
if(name == "group_id")
group.setID(value.toInt());
else if(name == "name")
group.setName(value);
break;
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE:
/*
if(name == "title")
task.ammProcedure.title = value;
else if(name == "dmCode")
task.ammProcedure.dmCode = value;
*/
break;
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE:
//if(name == "title")
//task.title = value;
break;
case TypeQueryToDB::TYPE_QUERY_CHANGE_STATUS_REPORT_TASK_AMM_TO_TRAINEE:
case TypeQueryToDB::TYPE_QUERY_CHANGE_STATUS_REPORT_TASK_FIM_TO_TRAINEE:
if(name == "status")
status = value;
break;
};
}
}
switch (queryToDB.typeQuery)
{
case TypeQueryToDB::TYPE_QUERY_NEW_INSTRUCTOR:
case TypeQueryToDB::TYPE_QUERY_EDIT_INSTRUCTOR:
data = &instructor;
break;
case TypeQueryToDB::TYPE_QUERY_NEW_TRAINEE:
case TypeQueryToDB::TYPE_QUERY_EDIT_TRAINEE:
data = &trainee;
break;
case TypeQueryToDB::TYPE_QUERY_NEW_GROUP:
case TypeQueryToDB::TYPE_QUERY_EDIT_GROUP:
data = &group;
break;
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE:
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE:
data = &task;
break;
case TypeQueryToDB::TYPE_QUERY_CHANGE_STATUS_REPORT_TASK_AMM_TO_TRAINEE:
case TypeQueryToDB::TYPE_QUERY_CHANGE_STATUS_REPORT_TASK_FIM_TO_TRAINEE:
data = &status;
break;
};
processingSystem->processingClientQueryToDB(client, queryToDB, id, data);
}
void ProcessParser::queryTasksXML(QXmlStreamReader &xmlReader, ClientHandler *client)
{
ClientQueryTasksXML clientQueryTasksXML;
/*Перебираем все атрибуты тега*/
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
//addTextToLogger(name + ": " + value);
if(name == "Type")
clientQueryTasksXML.Type = value;
}
processingSystem->processingClientQueryTasksXML(client, clientQueryTasksXML);
}
void ProcessParser::queryListSubProc(QXmlStreamReader &xmlReader, ClientHandler *client)
{
QString dmCode = "";
/*Перебираем все атрибуты тега*/
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
//addTextToLogger(name + ": " + value);
if(name == "dmCode")
dmCode = value;
}
processingSystem->processingClientQueryListSubProc(client, dmCode);
}
void ProcessParser::clientMessage(QXmlStreamReader &xmlReader,ClientHandler *client)
{
ClientMessage clientMessage;
/*Перебираем все атрибуты тега*/
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
//addTextToLogger(name + ": " + value);
if (name == "Text")
clientMessage.Text = value;
if (name == "From")
clientMessage.From = value;
if (name == "To")
clientMessage.To = value;
}
processingSystem->processingSendMessage(clientMessage);
}
void ProcessParser::clientNotify(QXmlStreamReader &xmlReader,ClientHandler *client)
{
ClientNotify clientNotify;
/*Перебираем все атрибуты тега*/
foreach(const QXmlStreamAttribute &attr, xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
if(name == "Code")
clientNotify.Code = value;
}
processingSystem->processingClientNotify(client, clientNotify);
}

View File

@@ -0,0 +1,43 @@
#ifndef PROCESSPARSER_H
#define PROCESSPARSER_H
#include <QObject>
#include <qxmlstream.h>
#include <clienthandler.h>
#include "Data/typesDataServerClient.h"
class ProcessParser : public QObject
{
Q_OBJECT
public:
explicit ProcessParser(QObject *parent = nullptr);
void initialize(ProcessingSystem *processingSystem);
public slots:
void slot_read(ClientHandler *client, QByteArray array);
signals:
void sigLogMessage(QString text);
//void sigStatusTasksAMMofTraineeChanged(int trainee_id);
//void sigStatusTasksFIMofTraineeChanged(int trainee_id);
private:
ProcessingSystem *processingSystem;
void clientAuth(QXmlStreamReader &xmlReader,ClientHandler *client);
void clientDeAuth(QXmlStreamReader &xmlReader,ClientHandler *client);
void clientBlockAuth(QXmlStreamReader &xmlReader,ClientHandler *client);
void toClientMessage(QXmlStreamReader &xmlReader,ClientHandler *client);
void queryToDb(QXmlStreamReader &xmlReader,ClientHandler *client, QByteArray array = QByteArray());
void queryTasksXML(QXmlStreamReader &xmlReader,ClientHandler *client);
void queryListSubProc(QXmlStreamReader &xmlReader,ClientHandler *client);
void clientMessage(QXmlStreamReader &xmlReader,ClientHandler *client);
void clientNotify(QXmlStreamReader &xmlReader,ClientHandler *client);
void clientDataInfo(QXmlStreamReader &xmlReader, ClientHandler *client);
void clientUnityTaskAMMreport(QXmlStreamReader &xmlReader,ClientHandler *client, QByteArray array = QByteArray());
void clientUnityTaskFIMreport(QXmlStreamReader &xmlReader,ClientHandler *client, QByteArray array = QByteArray());
TaskAmmFim xmlParserQueryToDB_ASSIGN_TASK_FIM_TO_TRAINEE(QByteArray array);
TaskAmmFim xmlParserQueryToDB_ASSIGN_TASK_AMM_TO_TRAINEE(QByteArray array);
};
#endif // PROCESSPARSER_H

View File

@@ -0,0 +1,431 @@
#include "assetsmanager.h"
AssetsManager::AssetsManager(QObject *parent) : QObject(parent)
{
}
void AssetsManager::initialize(UpdateController* updateContoller,DataParser *dataParser)
{
this->updateController = updateContoller;
//connect(this,&AssetsManager::sigSaveVersion,updateContoller,&UpdateController::saveVersionToFile);
datas = new QList<StreamingVersionData*>;
}
void AssetsManager::fillDatas()
{
QByteArray array;
QFile file(versionListFile);
if(!file.exists())
{
return;
}
datas->clear();
file.open(QIODevice::ReadOnly);
array = file.readAll();
file.close();
QXmlStreamReader xmlReader(array);
xmlReader.readNext();
QString name = xmlReader.name().toString();
while(!xmlReader.atEnd())
{
name = xmlReader.name().toString();
if(!xmlReader.isStartElement()) {
xmlReader.readNext();
continue;
}
if(xmlReader.name() == "VersionList")
{
xmlReader.readNext();
while (!xmlReader.atEnd())
{
if(xmlReader.isStartElement())
{
if(xmlReader.name() == "VersionData")
{
StreamingVersionData *data = new StreamingVersionData();
foreach(const QXmlStreamAttribute &attr,xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
if(name == "Version")
data->setViewName(value);
else if(name == "Created")
data->setCreateData(QDateTime::fromString(value));
else if(name == "isChangeable")
data->setIsChangeable(value.toInt());
else if(name == "author")
data->setAuthor(value);
}
datas->append(data);
}
}
xmlReader.readNext();
}
}
}
}
void AssetsManager::setVersionList(QList<StreamingVersionData*> *streamingVersion)
{
datas->clear();
datas = streamingVersion;
}
bool AssetsManager::findDuplicate(QString name)
{
QListIterator<StreamingVersionData*> iterator(*datas);
while (iterator.hasNext())
{
if (iterator.next()->getViewName() == name) return true;
}
return false;
}
QString AssetsManager::setVersion(QString versionName)
{
QListIterator<StreamingVersionData*> iterator(*datas);
while (iterator.hasNext())
{
StreamingVersionData *version = iterator.next();
if (version->getViewName() == versionName)
{
currentVersionData = version;
saveVersionToFile(currentVersionData);
emit signal_setVersion(versionName);
return version->getAbsolutPath();
}
}
return "none";
}
QList<FileData> *AssetsManager::prepareLocalPathList(QList<FileData> *fileData)
{
QList<FileData> *completeList = fileData;
for(int i = 0; i < completeList->count();i++)
{
FileData fileData = completeList->at(i);
int index = fileData.path.indexOf(currentVersionData->getViewName());
if(index != -1)
{
fileData.path = Tools::createRealPath(fileData.path,currentVersionData); //делаем в полный путь
completeList->replace(i,fileData);
}
else
{
fileData.path = Tools::createRootPath(fileData.path);
}
}
return completeList;
}
QList<FileData> *AssetsManager::prepareRealPathList(QList<FileData> *fileData)
{
QList<FileData> *completeList = fileData;
for(int i = 0; i < completeList->count();i++)
{
FileData fileData = completeList->at(i);
if(fileData.path.contains(streamingAssetsFolderName))
{
fileData.path = Tools::createStreamingToRealPath(fileData.path,currentVersionData);
}
else
{
fileData.path = Tools::createRealPath(fileData.path,currentVersionData); //делаем в полный путь
}
completeList->replace(i,fileData);
}
return completeList;
}
void AssetsManager::addVersion(StreamingVersionData *data)
{
datas->push_back(data);
}
void AssetsManager::createCopyVersion(QString versionName,QString newVersionName,QString author)
{
qDebug() << "assetManager thread ID " << QThread::currentThreadId();
StreamingVersionData* data = new StreamingVersionData;
data->setAbsolutePath(Tools::createSharedPath("/" + newVersionName));
data->setAuthor(author);
data->setIsChangeable(true);
data->setViewName(newVersionName);
data->setCreateData(QDateTime::currentDateTime());
datas->append(data);
qDebug() << "Version for copy " << versionName;
qDebug() << "New version name " << newVersionName;
//берем путь до копии
//преобразуем в реальный путь
QString sourcePath = QDir::currentPath() + "/" + sharedDataFolderName + "/" + versionName;
QString destinationPath = QDir::currentPath() + "/" + sharedDataFolderName + "/" + newVersionName;
QDir sourceDir(sourcePath);
if(!sourceDir.exists())
{
qDebug() << "Версии нет в SharedData";
return;
}
QDir destinationDir(destinationPath);
if(destinationDir.exists())
{
qDebug() << "Папка уже существует";
return;
}
//Создаем папку в Shared с новым именем
QDir().mkdir(destinationPath);
copyAllRecurse(sourcePath,destinationPath);
//добавляем в список текущих ассетов
updateController->calculateFullHash();
updateController->changeAssetVersion(newVersionName);
updateController->sendNewVersionList();
//повторно отправляем список версий из папки shared
}
void AssetsManager::deleteVersion(QString versionName)
{
QMutableListIterator<StreamingVersionData*> iterator(*datas);
//если версия равна текущей - игнор
if (currentVersionData->getViewName() == versionName)
return;
while (iterator.hasNext())
{
StreamingVersionData *version = iterator.next();
//проверка на наличие указанной версии
if (version->getViewName() == versionName)
{
//удаление папки
QString verFolderPath = QDir::currentPath() + "/" + sharedDataFolderName + "/" + versionName;
QDir dir(verFolderPath);
dir.removeRecursively();
//удаление хэша
QString hashPath = QDir::currentPath() + "/" + staticDataFolderName + "/" + versionName + "Hash.xml";
QFile file(hashPath);
if(file.exists()){
file.remove();
}
//удаление
datas->removeOne(version);
break;
}
}
updateController->calculateSharedHash();
updateController->sendNewVersionList();
}
void AssetsManager::copyAllRecurse(QString source,QString destination)
{
//Копируем все объекты туда
QDir sourceDir(source);
foreach(QString folder,sourceDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
{
QString destPath = destination + QDir::separator() + folder;
sourceDir.mkpath(destPath);
copyAllRecurse(source + QDir::separator() + folder,destPath);
}
foreach(QString file,sourceDir.entryList(QDir::Files))
{
QFile::copy(source + QDir::separator() + file,destination + QDir::separator() + file);
}
}
void AssetsManager::writeVersionsToFile(QList<StreamingVersionData*> version,bool isFirst)
{
QList<SXmlAnswerTag> listTag;
datas->clear();
QFile file(versionListFile);
foreach(StreamingVersionData* ver,version)
{
SAttribute attribute1 = {"Version", ver->getViewName()};
SAttribute attribute2 = {"Created", ver->getCreateData().toString()};
SAttribute attribute3;
SAttribute attribute4;
if(isFirst)
{
attribute3 = {"isChangeable",QString::number(false)};
QString author = tr("LLC Constanta-Design");
attribute4 = {"author",author};
ver->setAuthor(author);
}else
{
attribute3 ={"isChangeable",QString::number(ver->getIsChangeable())};
attribute4 = {"author",ver->getAuthor()};
}
QList<SAttribute> listAttr = {attribute1, attribute2,attribute3,attribute4};
SXmlAnswerTag tag = {"VersionData", listAttr};
listTag.append(tag);
datas->append(ver);
}
file.open(QIODevice::WriteOnly);
QXmlStreamWriter xmlWriter(&file);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("VersionList");
foreach(SXmlAnswerTag tag,listTag)
{
xmlWriter.writeStartElement(tag.elementName);
foreach(SAttribute attribute,tag.attr)
{
xmlWriter.writeAttribute(attribute.name,attribute.value);
}
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();
file.close();
}
void AssetsManager::createFirstVersionListXML(QList<StreamingVersionData*> version)
{
QFile file(versionListFile);
QList<StreamingVersionData*> *temp = new QList<StreamingVersionData*>();
if(!file.exists())
{
writeVersionsToFile(version,true);
}
else
{
if(datas->count() == 0) fillDatas();
foreach(StreamingVersionData* ver,version)
{
foreach(StreamingVersionData* data,*datas)
{
if(ver->getViewName() == data->getViewName())
{
StreamingVersionData *tempData = new StreamingVersionData;
tempData->fill(data);
tempData->setAbsolutePath(ver->getAbsolutPath());
temp->append(tempData);
break;
}
}
}
writeVersionsToFile(*temp,false);
}
}
QString AssetsManager::getLastVersion()
{
QString result;
QFile file(version);
if (!file.exists()) return setVersion("base");
if (file.open(QIODevice::ReadOnly))
{
QXmlStreamReader reader(file.readAll());
while (!reader.atEnd())
{
reader.readNext();
foreach(const QXmlStreamAttribute &attr,reader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
if(name == "Version")
{
result = value;
qDebug() << value;
break;
}
}
}
}
return setVersion(result);
}
void AssetsManager::saveVersionToFile(StreamingVersionData *streamingVersion) //TODO: переименовать и перебросить в AssetManager
{
QFile file(version);
file.open(QFile::WriteOnly);
QXmlStreamWriter xmlWriter(&file);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("VersionData");
xmlWriter.writeAttribute("Version",streamingVersion->getViewName());
xmlWriter.writeAttribute("Created",streamingVersion->getCreateData().toString());
xmlWriter.writeAttribute("isChangeable",QString::number(streamingVersion->getIsChangeable()));
xmlWriter.writeAttribute("author",streamingVersion->getAuthor());
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();
file.close();
}
AssetsManager::~AssetsManager()
{
}
StreamingVersionData *AssetsManager::getCurrentVersionData() const
{
return currentVersionData;
}

View File

@@ -0,0 +1,48 @@
#ifndef ASSETSMANAGER_H
#define ASSETSMANAGER_H
#include <QObject>
#include <Systems/updatecontroller.h>
#include <Data/StreamingVersionData.h>
class AssetsManager : public QObject
{
Q_OBJECT
public:
explicit AssetsManager(QObject *parent = nullptr);
void initialize(UpdateController* updateContoller,DataParser *dataParser);
void addVersion(StreamingVersionData *data);
void createCopyVersion(QString versionName,QString newName,QString author);
void deleteVersion(QString version);
void setVersionList(QList<StreamingVersionData *> *streamingVersion);
bool findDuplicate(QString name);
void createFirstVersionListXML(QList<StreamingVersionData*> assets);
QString getLastVersion();
QString setVersion(QString versionName);
QList<FileData> *prepareLocalPathList(QList<FileData>*fileData);
QList<FileData> *prepareRealPathList(QList<FileData> *fileData);
QList<FileData> *getRealPathList();
~AssetsManager();
StreamingVersionData *getCurrentVersionData() const;
void saveVersionToFile(StreamingVersionData *streamingVersion);
void writeVersionsToFile(QList<StreamingVersionData*> version,bool isFirst);
signals:
void sigSaveVersion(StreamingVersionData *versionData);
void signal_setVersion(QString versionStr);
private:
UpdateController *updateController;
QList<StreamingVersionData*> *datas;
StreamingVersionData* currentVersionData;
void copyAllRecurse(QString source, QString destination);
void fillDatas();
};
#endif // ASSETSMANAGER_H

View File

@@ -0,0 +1,81 @@
#include "chatsystem.h"
ChatSystem::ChatSystem()
{
}
void ChatSystem::initialize(CommonClientHandler *commonClientHandler, DataParser *dataParser, QMap<int, ClientHandler*> *clientsMap)
{
this->commonClientHandler = commonClientHandler;
this->dataParser = dataParser;
this->clientsMap = clientsMap;
clientNotSendedMessage = new QMap<QString,QQueue<ClientMessage>*>;
}
bool ChatSystem::sendTo(ClientMessage message)
{
QByteArray byteArrayMsg = dataParser->ClientAnswer()->message(message.From,message.To,message.Text);
foreach(int idSocket, clientsMap->keys())
{
ClientHandler *handler = clientsMap->value(idSocket);
if(handler->getClient()->getId() == message.To &&
handler->getClient()->getTypeClient() != TypeClientAutorization::TYPE_QT_CLIENT &&
handler->getClient()->getIsLoggedIn())
{
handler->sendXmlAnswer(byteArrayMsg, PacketType::TYPE_XMLANSWER);
QString str = "Msg From Client [" + message.From + " to " + message.To + "] : " + message.Text;
return true;
}
}
return false;
}
bool ChatSystem::sendMessage(ClientMessage message)
{
bool isSended = false;
isSended = sendTo(message);
if (!isSended)
{
if (clientNotSendedMessage->contains(message.To))
{
clientNotSendedMessage->find(message.To).value()->append(message);
}
else
{
auto stack = new QQueue<ClientMessage>;
stack->enqueue(message);
clientNotSendedMessage->insert(message.To, stack);
}
qDebug() << "Message stack count: " + QString::number(clientNotSendedMessage->count());
}
return true;
}
void ChatSystem::sendOldMessages(QString id)
{
qDebug() << id;
if (clientNotSendedMessage->contains(id))
{
auto queue = clientNotSendedMessage->find(id).value();
Logger::instance().log("Send old Messages " + QString::number(queue->length()));
while (!queue->isEmpty())
{
auto message = queue->dequeue();
sendTo(message);
}
}
else
{
qDebug() << "client empty";
}
}

View File

@@ -0,0 +1,27 @@
#ifndef CHATSYSTEM_H
#define CHATSYSTEM_H
#include "commonclienthandler.h"
#include <QObject>
#include <Data/typesDataServerClient.h>
class ChatSystem : public QObject
{
Q_OBJECT
public:
ChatSystem();
void initialize(CommonClientHandler *commonClientHandler, DataParser *dataParser, QMap<int, ClientHandler*> *clientsMap);
bool sendMessage(ClientMessage message);
//логика хранения отложенных сообщений
//хендлеры для отправки и приема
void sendOldMessages(QString id);
private:
CommonClientHandler *commonClientHandler;
DataParser *dataParser;
QMap<int, ClientHandler*> *clientsMap;
QMap<QString,QQueue<ClientMessage>*> *clientNotSendedMessage;
bool sendTo(ClientMessage message);
};
#endif // CHATSYSTEM_H

View File

@@ -0,0 +1,168 @@
#include "commonclienthandler.h"
CommonClientHandler::CommonClientHandler(QObject *parent) : QObject(parent)
{
}
void CommonClientHandler::initialize(QMap<int, ClientHandler *> *clientsMap, ProcessingSystem *processingSystem, DataParser *dataParser)
{
this->clientsMap = clientsMap;
this->processingSystem = processingSystem;
this->dataParser = dataParser;
}
void CommonClientHandler::sendNewVersionListToAllClient()
{
foreach(int idSocket,clientsMap->keys())
{
ClientHandler *handler = clientsMap->value(idSocket);
if (!handler->getClient()->getIsLoggedIn()) continue;
handler->sendVersionList();
}
}
void CommonClientHandler::sendCurrentVersionToAllClient()
{
foreach(int idSocket,clientsMap->keys())
{
ClientHandler *handler = clientsMap->value(idSocket);
if (!handler->getClient()->getIsLoggedIn()) continue;
handler->sendVersion();
}
}
void CommonClientHandler::slot_ListsInstructorsTraineesChanged()
{
//Проходим все открытые сокеты
foreach(int idSocket, clientsMap->keys())
{
ClientHandler *handler = clientsMap->value(idSocket);
//Проверяем, есть ли клиенты TYPE_GUI
if(handler->getClient()->getTypeClient() == TypeClientAutorization::TYPE_GUI)
{//Отправляем этому клиенту обновление списков
ClientQueryToDB queryToDB;
queryToDB.typeQuery = TypeQueryToDB::TYPE_QUERY_GET_ALL_LISTS;
processingSystem->processingClientQueryToDB(handler, queryToDB);
}
if(handler->getClient()->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
ClientQueryToDB queryToDB;
queryToDB.typeQuery = TypeQueryToDB::TYPE_QUERY_GET_CONTACT_LIST;
processingSystem->processingClientQueryToDB(handler, queryToDB);
}
}
}
void CommonClientHandler::slot_StatusTasksAMMofTraineeChanged(int trainee_id)
{
//Проходим все открытые сокеты
foreach(int idSocket, clientsMap->keys())
{
ClientHandler *handler = clientsMap->value(idSocket);
//Проверяем, есть ли клиенты TYPE_GUI
if(handler->getClient()->getTypeClient() == TypeClientAutorization::TYPE_GUI)
{//Отправляем этому клиенту задачи AMM для Обучаемого (с измененным статусом)
ClientQueryToDB queryToDB;
queryToDB.typeQuery = TypeQueryToDB::TYPE_QUERY_GET_TASKS_AMM_FOR_TRAINEE;
processingSystem->processingClientQueryToDB(handler, queryToDB, trainee_id);
}
}
/*
//Отправка списка задач AMM клиенту Юнити
if(ClientHandler* clientUnity = processingSystem->getUnityClientById(trainee_id))
{//Есть такой
//processingSystem->sendListTasksAMMofTraineetoClient(clientUnity, trainee_id);
}*/
}
void CommonClientHandler::slot_StatusTasksFIMofTraineeChanged(int trainee_id)
{
//Проходим все открытые сокеты
foreach(int idSocket, clientsMap->keys())
{
ClientHandler *handler = clientsMap->value(idSocket);
//Проверяем, есть ли клиенты TYPE_GUI
if(handler->getClient()->getTypeClient() == TypeClientAutorization::TYPE_GUI)
{//Отправляем этому клиенту задачи FIM для Обучаемого (с измененным статусом)
ClientQueryToDB queryToDB;
queryToDB.typeQuery = TypeQueryToDB::TYPE_QUERY_GET_TASKS_FIM_FOR_TRAINEE;
processingSystem->processingClientQueryToDB(handler, queryToDB, trainee_id);
}
}
/*
//Отправка списка задач FIM клиенту Юнити
if(ClientHandler* clientUnity = processingSystem->getUnityClientById(trainee_id))
{//Есть такой
//processingSystem->sendListTasksFIMofTraineetoClient(clientUnity, trainee_id);
}*/
}
void CommonClientHandler::slot_sendPacketToAllClients(PacketType packetType)
{
foreach(int idSocket, clientsMap->keys())
{
ClientHandler *handler = clientsMap->value(idSocket);
if (!handler->getClient()->getIsLoggedIn()) continue;
handler->sendPacketType(packetType);
Logger::instance().log("AllSending " + handler->getClient()->getLogin() + " " + enumToString(packetType));
}
emit sigSetServerState(packetType);
}
void CommonClientHandler::slot_sendTaskToClient(QString fullNameClient,QString textTask)
{
QByteArray byteArrayTask = dataParser->ClientAnswer()->task(textTask);
//Проходим все открытые сокеты
foreach(int idSocket, clientsMap->keys())
{
ClientHandler *handler = clientsMap->value(idSocket);
if(handler->getClient()->getFullName() == fullNameClient)
{//Отправляем ему
handler->getSocket()->write(byteArrayTask);
QString peerAddress = handler->getSocket()->peerAddress().toString();
QString peerPort = QString::number(handler->getSocket()->peerPort());
}
}
}
void CommonClientHandler::slot_DocsChanged()
{
//Проходим все открытые сокеты
foreach(int idSocket, clientsMap->keys())
{
ClientHandler *handler = clientsMap->value(idSocket);
TypeClientAutorization type = handler->getClient()->getTypeClient();
//Отправляем всем заинтересованным клиентам оповещение об изменении docs.xml
if(type == TypeClientAutorization::TYPE_GUI)
{
handler->sendPacketType(PacketType::TYPE_XMLANSWER_DOCS_CHANGED);
}
else if(type == TypeClientAutorization::TYPE_QT_CLIENT)
{
handler->sendPacketType(PacketType::TYPE_XMLANSWER_DOCS_CHANGED);
}
else if(type == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
//handler->sendPacketType(PacketType::TYPE_XMLANSWER_DOCS_CHANGED); //Unity не обязательно!
}
}
}

View File

@@ -0,0 +1,38 @@
#ifndef COMMONCLIENTHANDLER_H
#define COMMONCLIENTHANDLER_H
#include <QObject>
#include "clienthandler.h"
class ProcessingSystem;
class DataParser;
class Logger;
class CommonClientHandler : public QObject
{
Q_OBJECT
public:
explicit CommonClientHandler(QObject *parent = nullptr);
void initialize(QMap<int, ClientHandler*> *clientsMap,
ProcessingSystem *processingSystem,
DataParser *dataParser);
void sendNewVersionListToAllClient();
void sendCurrentVersionToAllClient();
void slot_ListsInstructorsTraineesChanged();
void slot_StatusTasksAMMofTraineeChanged(int trainee_id);
void slot_StatusTasksFIMofTraineeChanged(int trainee_id);
void slot_sendPacketToAllClients(PacketType packetType);
bool slotSendMessage(QString loginFrom, QString loginTo, QString text);
void slot_sendTaskToClient(QString fullNameClient, QString textTask);
void slot_DocsChanged();
signals:
void sigSetServerState(PacketType packetType);
private:
QMap<int, ClientHandler*> *clientsMap;
ProcessingSystem *processingSystem;
DataParser *dataParser;
};
#endif // COMMONCLIENTHANDLER_H

View File

@@ -0,0 +1,372 @@
#include <QString>
#include "docsupdater.h"
#include "tools.h"
DocsUpdater::DocsUpdater(UpdateController* updateController, QObject *parent):
QObject(parent),
updateController(updateController),
flagStop(false)
{
}
DocsUpdater::~DocsUpdater()
{
}
//PUBLIC
void DocsUpdater::lockAccessToDocsXML()
{
mtxAccess.lock();
}
void DocsUpdater::unLockAccessToDocsXML()
{
mtxAccess.unlock();
}
QList<SubProc> DocsUpdater::getListSubProcForDMcode(QString dmCode)
{
QMutexLocker locker(&mtxAccess);
if(!listSubProcMap.contains(dmCode))
return QList<SubProc>();
return listSubProcMap.value(dmCode);
}
bool DocsUpdater::updateDocsXML()
{
QMutexLocker locker(&mtxAccess);
QString nameDocsFile = tasksAMMfileName; //кручу верчу запутать хочу!
QString pathDocsFile = updateController->getPathAdditionalFile(nameDocsFile);
QDomDocument docTasksDOM;
if(! Tools::loadXMLtoDOM(pathDocsFile, &docTasksDOM))
return false;
QDomElement manifestElement = docTasksDOM.firstChildElement("manifest");
if(manifestElement.isNull())
return false;
deleteAllModulsAMM();
listTasksAMM.clear();
listSubProcMap.clear();
DMmodulesMap.clear();
domElementParserAMM(manifestElement, nullptr);
if(! Tools::saveDOMtoXML(pathDocsFile, &docTasksDOM))
{
deleteAllModulsAMM();
listTasksAMM.clear();
listSubProcMap.clear();
DMmodulesMap.clear();
return false;
}
//Проставляем canplay
for (auto it = listSubProcMap.begin(); it != listSubProcMap.end(); ++it)
{
QList<SubProc> listSP = it.value();
QString keyToReplace = it.key();
if(listSP.count())
{
for(int i = 0; i < listSP.count(); i++)
{
QString dmCode = listSP.at(i).getDmCode();
DM* module = getDMmoduleByDMcode(dmCode);
if(module)
{
SubProc sp = listSP.at(i);
sp.setModeList(module->getModeList());
listSP.replace(i, sp);
}
}
if (!keyToReplace.isEmpty())
{
listSubProcMap[keyToReplace] = listSP;
}
}
}
return true;
}
//PRIVATE
void DocsUpdater::domElementParserAMM(QDomElement element, Module* moduleParent)
{
QString name;
if(flagStop)
return;
QDomElement childElement = element.firstChildElement();
if(childElement.isNull())
return;
Module* module = nullptr;
do
{
name = childElement.nodeName();
QDomNamedNodeMap nodeMap = childElement.attributes();
if(name == "doc")
{
module = new PM();
}
else if(name == "pm")
{
module = new PM();
PM* PMmodul = static_cast<PM*>(module);
PMmodul->initialize(nodeMap.namedItem("modelIdentCode").nodeValue(),
nodeMap.namedItem("pmIssuer").nodeValue(),
nodeMap.namedItem("pmNumber").nodeValue(),
nodeMap.namedItem("pmVolume").nodeValue());
if(moduleParent)
{
PMmodul->setParentModule(moduleParent);
PM* PMmodulParent = static_cast<PM*>(moduleParent);
PMmodulParent->addChildModule(module);
}
}
else if(name == "dm")
{
module = new DM();
DM* DMmodul = static_cast<DM*>(module);
DMmodul->initialize(nodeMap.namedItem("modelIdentCode").nodeValue(),
nodeMap.namedItem("systemDiffCode").nodeValue(),
nodeMap.namedItem("systemCode").nodeValue(),
nodeMap.namedItem("subSystemCode").nodeValue(),
nodeMap.namedItem("subSubSystemCode").nodeValue(),
nodeMap.namedItem("assyCode").nodeValue(),
nodeMap.namedItem("disassyCode").nodeValue(),
nodeMap.namedItem("disassyCodeVariant").nodeValue(),
nodeMap.namedItem("infoCode").nodeValue(),
nodeMap.namedItem("infoCodeVariant").nodeValue(),
nodeMap.namedItem("itemLocationCode").nodeValue());
if(moduleParent)
{
DMmodul->setParentModule(moduleParent);
PM* PMmodulParent = static_cast<PM*>(moduleParent);
PMmodulParent->addChildModule(module);
}
DMmodulesMap.insert(DMmodul->dmCode(), DMmodul);
}
else if(name == "rus" || name == "eng")
{
if(moduleParent)
{
if(moduleParent->getType() == ModuleType::TYPE_PM)
{//PM
PM* PMmodulParent = static_cast<PM*>(moduleParent);
if(name == "rus")
PMmodulParent->setLangStructRus(nodeMap.namedItem("title").nodeValue());
else
PMmodulParent->setLangStructEng(nodeMap.namedItem("title").nodeValue());
}
else
{//DM
DM* DMmodulParent = static_cast<DM*>(moduleParent);
if(name == "rus")
{
DMmodulParent->setLangStructRus(nodeMap.namedItem("techName").nodeValue(),
nodeMap.namedItem("infoName").nodeValue(),
nodeMap.namedItem("pdf").nodeValue(),
nodeMap.namedItem("bookmark").nodeValue(),
nodeMap.namedItem("xml").nodeValue());
QString dmCode = DMmodulParent->dmCode();
QString canplay = "";
QList<SubProc> listSubProc;
if(processingScenXML(dmCode, canplay, listSubProc))
{
DMmodulParent->setModeList(SubProc::parseCanplay(canplay));
nodeMap.namedItem("canplay").setNodeValue(canplay);
listSubProcMap.insert(dmCode, listSubProc);
}
else
{
DMmodulParent->setModeList(SubProc::parseCanplay(canplay));
nodeMap.namedItem("canplay").setNodeValue(canplay);
}
}
else
DMmodulParent->setLangStructEng(nodeMap.namedItem("techName").nodeValue(),
nodeMap.namedItem("infoName").nodeValue(),
nodeMap.namedItem("pdf").nodeValue(),
nodeMap.namedItem("bookmark").nodeValue(),
nodeMap.namedItem("xml").nodeValue());
}
}
}
domElementParserAMM(childElement, module);
if(moduleParent == nullptr)
listAllModulesAMM.append(module);
if(module)
if(module->getType() == ModuleType::TYPE_DM)
{
TaskAmmFim* task = nullptr;
task = new TaskAmmFim();
task->setID(module->getID());
task->ammProcedure.title = static_cast<DM*>(module)->getLangStructRus().techName;
task->ammProcedure.dmCode = static_cast<DM*>(module)->dmCode();
listTasksAMM.append(*task);
delete task;
}
}while (! (childElement = childElement.nextSiblingElement()).isNull());
}
void DocsUpdater::deleteAllModulsAMM()
{
for(Module* module: listAllModulesAMM)
{
if(module->getType() == ModuleType::TYPE_PM)
delete static_cast<PM*>(module);
else
delete static_cast<DM*>(module);
}
listAllModulesAMM.clear();
}
bool DocsUpdater::processingScenXML(const QString dmCode, QString &canplay, QList<SubProc> &listSubProc)
{
listSubProc.clear();
ModeList modeList;
canplay = "";
QString signDemo = "-";
QString signTrain = "-";
QString signExam = "-";
QString signAuto = "-";
QString nameScenXMLFile = "/" + dmCode + ".xml";
QString pathScenXMLFile = updateController->getPathScensFile(nameScenXMLFile);
QDomDocument docScenDOM;
if(! Tools::loadXMLtoDOM(pathScenXMLFile, &docScenDOM))
return false;
QDomElement scenarioElement = docScenDOM.firstChildElement("scenario");
if(scenarioElement.isNull())
return false;
QDomElement demoElement = scenarioElement.firstChildElement("demo");
if(!demoElement.isNull())
{
//canplay
if(demoElement.toElement().attribute("canplay") == "True")
{
signDemo = "+";
modeList.demo = true;
}
//subProc
selectSubProc(demoElement, listSubProc);
}
QDomElement trainElement = scenarioElement.firstChildElement("train");
if(!trainElement.isNull())
{
//canplay
if(trainElement.toElement().attribute("canplay") == "True")
{
signTrain = "+";
modeList.train = true;
}
//subProc
selectSubProc(trainElement, listSubProc);
}
QDomElement examElement = scenarioElement.firstChildElement("exam");
if(!examElement.isNull())
{
//canplay
if(examElement.toElement().attribute("canplay") == "True")
{
signExam = "+";
modeList.exam = true;
}
//subProc
selectSubProc(examElement, listSubProc);
}
QDomElement autoElement = scenarioElement.firstChildElement("auto");
if(!autoElement.isNull())
{
//canplay
if(autoElement.toElement().attribute("canplay") == "True")
{
signAuto = "+";
modeList.autoM = true;
}
//subProc
//Из этого режима не берем!
}
canplay = QString("%1/%2/%3/%4").arg(signDemo, signTrain, signExam, signAuto);
return true;
}
void DocsUpdater::selectSubProc(QDomElement &modeElement, QList<SubProc> &listSubProc)
{
QDomNodeList nodeList = modeElement.elementsByTagName("node");
for(int i = 0; i < nodeList.count(); i++)
{
QDomNode node = nodeList.at(i);
if(node.toElement().attribute("type") == "Subproc")
{
QDomElement subProcElement = node.firstChildElement("subproc");
if(!subProcElement.isNull())
{
SubProc subProc;
subProc.setDmCode(subProcElement.toElement().attribute("dmCode"));
subProc.setTitle(subProcElement.toElement().attribute("title"));
if(! listSubProc.contains(subProc))
listSubProc.append(subProc);
}
}
}
}
DM *DocsUpdater::getDMmoduleByDMcode(QString dmCode)
{
if(!DMmodulesMap.contains(dmCode))
return nullptr;
return DMmodulesMap.value(dmCode);
}

View File

@@ -0,0 +1,44 @@
#ifndef DOCSUPDATER_H
#define DOCSUPDATER_H
#include <QObject>
#include "updatecontroller.h"
#include "module.h"
class DocsUpdater : public QObject
{
Q_OBJECT
public:
DocsUpdater(UpdateController* updateController, QObject *parent = nullptr);
~DocsUpdater();
public:
void lockAccessToDocsXML();
void unLockAccessToDocsXML();
QList<SubProc> getListSubProcForDMcode(QString dmCode);
bool updateDocsXML();
private:
void domElementParserAMM(QDomElement element, Module* moduleParent);
void deleteAllModulsAMM();
bool processingScenXML(const QString dmCode, QString& canplay, QList<SubProc>& listSubProc);
void selectSubProc(QDomElement& modeElement, QList<SubProc>& listSubProc);
DM* getDMmoduleByDMcode(QString dmCode);
private:
UpdateController* updateController;
QMutex mtxAccess;
bool flagStop;
QList<Module*> listAllModulesAMM; //?
QList<TaskAmmFim> listTasksAMM; //?
QMap<QString, DM*> DMmodulesMap; //общий (линейный) словарь всех DM-модулей
QMap<QString, QList<SubProc>> listSubProcMap; //словарь подпроцедур для всех DM-модулей
};
#endif // DOCSUPDATER_H

View File

@@ -0,0 +1,98 @@
#include "fasthashcalculator.h"
#include <QtConcurrent>
FastHashCalculator::FastHashCalculator(QObject *parent) : QObject(parent)
{
hashList = new QList<FileData>();
}
void FastHashCalculator::calculateHashes(QString path)
{
hashList->clear();
if(!QDir(path).exists()){
QDir().mkdir(path);
}
QString hashString;
QStringList filter;
filter << "*";
QList<FileData> *folders = new QList<FileData>;
QDirIterator dirIterator(path,filter, QDir::AllEntries, QDirIterator::Subdirectories);
while (dirIterator.hasNext())
{
QFileInfo fileInfo(dirIterator.next());
FileData currentFolder;
if(fileInfo.isDir() && !fileInfo.fileName().startsWith(".") && fileInfo.fileName() != projectFolderName)
{
currentFolder.path = Tools::createLocalPath(fileInfo.absoluteFilePath());
currentFolder.hash = "FOLDER";
if(!folders->contains(currentFolder))
{
folders->push_back(currentFolder);
}
}
}
hashList->append(*folders);
QDirIterator fileIterator(path,filter,QDir::Files | QDir::NoDotAndDotDot,QDirIterator::Subdirectories);
QList<QString> files;
files.clear();
while(fileIterator.hasNext())
{
fileIterator.next();
QFileInfo fileInfo = fileIterator.fileInfo();
QString path = fileInfo.absoluteFilePath();
//фильтры
if (fileInfo.isHidden()) continue;
if (!fileInfo.isFile()) continue;
if (fileInfo.fileName().contains(".meta")) continue;
if (fileInfo.fileName() == "docs.xml") continue;
files.append(path);
}
QtConcurrent::map(files, [this](const QString &filePath)
{
QByteArray hash = calculateFileHashOptimized(filePath);
QMutexLocker locker(&_mutex);
FileData currentFile;
QString hashName;
currentFile.path = Tools::createLocalPath(filePath);
currentFile.hash = hash.toHex();
hashList->append(currentFile);
}).waitForFinished();
emit finished();
}
QByteArray FastHashCalculator::calculateFileHashOptimized(const QString &filePath)
{
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) return QByteArray();
QCryptographicHash hash(QCryptographicHash::Md5);
const qint64 bufferSize = 2 * 1024; // 2MB
QByteArray buffer;
buffer.resize(bufferSize);
while (!file.atEnd()) {
qint64 bytesRead = file.read(buffer.data(), bufferSize);
hash.addData(buffer.constData(), bytesRead);
}
return hash.result();
}
QList<FileData> *FastHashCalculator::getHashList() const
{
return hashList;
}

View File

@@ -0,0 +1,31 @@
#ifndef FASTHASHCALCULATOR_H
#define FASTHASHCALCULATOR_H
#include <QHash>
#include <QMutex>
#include <QObject>
#include <QFile>
#include <QDirIterator>
#include <Data/typesDataServerClient.h>
#include "tools.h"
class FastHashCalculator : public QObject
{
Q_OBJECT
public:
explicit FastHashCalculator(QObject *parent = nullptr);
void calculateHashes(QString path);
QList<FileData> *getHashList() const;
signals:
void finished();
private:
QByteArray calculateFileHashOptimized(const QString &filePath);
void calculateSingleHash(const QString &filePath);
QList<FileData>* hashList;
QMutex _mutex;
};
#endif // FASTHASHCALCULATOR_H

138
Server/Systems/logger.cpp Normal file
View File

@@ -0,0 +1,138 @@
#include "logger.h"
#include <QThread>
Logger::Logger()
{
connect(this,&Logger::sigAddToLogger, this, &Logger::handleLog,Qt::AutoConnection);
createDirectory();
}
Logger &Logger::instance()
{
static Logger logger;
return logger;
}
Logger::~Logger()
{
}
void Logger::setLoggingType(LoggingType type)
{
this->loggingType = type;
}
void Logger::log(QString message, LogLevel level)
{
emit sigAddToLogger(message,level);
}
void Logger::setLogFile(QString filePath)
{
QMutexLocker locker(&mutex);
if (logFile.isOpen())
{
logFile.close();
}
logFile.setFileName(filePath);
logFile.open(QIODevice::WriteOnly | QIODevice::Append);
}
void Logger::setLogToFile(bool flag)
{
isLogToFile = flag;
if (flag)
{
QString filePath = logFolderPath + "/" + "log " + QDateTime::currentDateTime().toString("dd-MM-yyyy")+".txt";
setLogFile(filePath);
}
}
void Logger::handleLog(QString msg, LogLevel logLevel)
{
/*
color: red; * Красный *
color: green; * Зелёный *
color: blue; * Синий *
color: yellow; * Жёлтый *
color: black; * Чёрный *
color: white; * Белый *
color: purple; * Фиолетовый *
color: orange; * Оранжевый *
color: pink; * Розовый *
color: brown; * Коричневый *
color: gray; * Серый *
*/
QString level;
QString colorLevel = "pink";
#ifndef PROJECT_TYPE_DEBUG
if(logLevel == DEBUG)
return;
#endif
switch (logLevel)
{
case INFO:
level = "INFO";
colorLevel = "green";
break;
case WARNING:
level = "WARNING";
colorLevel = "yellow";
break;
case ERROR:
level = "ERROR";
colorLevel = "red";
break;
case CRITICAL:
level = "CRITICAL";
colorLevel = "purple";
break;
case DEBUG:
level = "DEBUG";
colorLevel = "brown";
break;
}
QString timeStamp = QDateTime::currentDateTime().toString("hh:mm:ss");
QString message = timeStamp + " " + level + " " + msg;
QString messageHTML = QString("<p><span style=\"color: blue;\">%1</span> <span style=\"color: %2;\">%3</span> <span style=\"color: black;\">%4</span></p>").
arg(timeStamp, colorLevel, level, msg);
if (loggingType == LoggingType::WIDGET)
{
emit sigLogToWidget(messageHTML);
}
else if(loggingType == LoggingType::CONSOLE)
{
qDebug() << messageHTML;
}
if(isLogToFile)
{
QMutexLocker locker(&mutex);
if (logFile.isOpen())
{
QTextStream stream(&logFile);
stream << message << "\n";
}
}
}
void Logger::createDirectory()
{
QString directoryPath = logFolderPath;
QDir dir(directoryPath);
if(!dir.exists()) dir.mkdir(".");
}

59
Server/Systems/logger.h Normal file
View File

@@ -0,0 +1,59 @@
#ifndef LOGGER_H
#define LOGGER_H
#include <QPlainTextEdit>
#include <QDateTime>
#include <QMutex>
#include <QObject>
#include <QDebug>
#include <QDir>
#include "Systems/tools.h"
enum LogLevel
{
INFO,
WARNING,
ERROR,
CRITICAL,
DEBUG
};
enum LoggingType
{
WIDGET,
CONSOLE,
TOFILE
};
class Logger : public QObject
{
Q_OBJECT
public:
Logger();
static Logger& instance();
~Logger();
void setWidget(QPlainTextEdit * widget);
void setLoggingType(LoggingType type);
void log(QString message,LogLevel level = INFO);
void setLogFile(QString filePath);
void setLogToFile(bool flag);
public slots:
void handleLog(QString msg,LogLevel logLevel = INFO);
signals:
void sigAddToLogger(QString msg, LogLevel logLevel = INFO);
void sigLogToWidget(QString message);
private:
QString msg;
QFile logFile;
LoggingType loggingType;
QMutex mutex;
bool isLogToFile;
void createDirectory();
};
#endif // LOGGER_H

View File

@@ -0,0 +1,762 @@
#include "processingsystem.h"
#include "providerdblms.h"
#include <clienthandler.h>
ProcessingSystem::ProcessingSystem(ProviderDBLMS* providerDBLMS, UpdateController* updateController, DocsUpdater* docsUpdater, QObject *parent):
QObject(parent),
updateController(nullptr),
docsUpdater(nullptr),
providerDBLMS(nullptr)
{
this->providerDBLMS = providerDBLMS;
this->updateController = updateController;
this->docsUpdater = docsUpdater;
}
void ProcessingSystem::initialize(MultiThreadServer *server, DataParser *dataParser,
CommonClientHandler *commonClientHandler,
UpdateController *updateController,
ChatSystem *chatSystem)
{
this->commonClientServer = commonClientHandler;
this->dataParser = dataParser;
this->server = server;
this->updateController = updateController;
this->chatSystem = chatSystem;
connect(this,&ProcessingSystem::sigListsInstructorsTraineesChanged,commonClientHandler, &CommonClientHandler::slot_ListsInstructorsTraineesChanged,Qt::AutoConnection);
connect(this,&ProcessingSystem::sigStatusTasksAMMofTraineeChanged,commonClientHandler, &CommonClientHandler::slot_StatusTasksAMMofTraineeChanged,Qt::AutoConnection);
connect(this,&ProcessingSystem::sigStatusTasksFIMofTraineeChanged,commonClientHandler, &CommonClientHandler::slot_StatusTasksFIMofTraineeChanged,Qt::AutoConnection);
connect(this,&ProcessingSystem::sigUpdateListClients,server,&MultiThreadServer::updateClientList,Qt::AutoConnection);
connect(this,&ProcessingSystem::sigSetData,updateController,&UpdateController::setDataInfo,Qt::AutoConnection);
}
void ProcessingSystem::processingClientAutorization(ClientHandler *client, ClientAutorization clientAutorization)
{
if(server->getStateBlockAutorization() == blocked)
{
QByteArray arrayAnswer = dataParser->ClientAnswer()->notify(NOTIFY_SERVER_BLOCKED);
client->sendXmlAnswer(arrayAnswer);
return;
}
//Попытка авторизации клиента (проверка по БД)
QString instructorName;
QString traineeName;
QByteArray arrayAnswer;
int clientID = 0;
InterfaceDataBaseLMS::ErrorAuth errorAuth = InterfaceDataBaseLMS::ErrorAuth::errNo;
if(providerDBLMS->authorizationInstructor(clientAutorization.Login, clientAutorization.Password, errorAuth))
{//Авторизуется инструктор
client->getClient()->setLogin(clientAutorization.Login);
client->getClient()->setAccessType(UserType::INSTRUCTOR);
client->getClient()->setTypeClient(clientAutorization.TypeClient);
emit sigUpdateListClients();
instructorName = providerDBLMS->getNameInstructorByLogin(clientAutorization.Login);
clientID = providerDBLMS->getIdInstructorByLogin(clientAutorization.Login);
client->getClient()->setId(QString::number(clientID));
arrayAnswer = dataParser->ClientAnswer()->authorization(true, instructorName, instructorName, "instructor", clientAutorization.Login, clientID);
}
else if(clientAutorization.TypeClient != TypeClientAutorization::TYPE_GUI)
{
if(providerDBLMS->authorizationTrainee(clientAutorization.Login, clientAutorization.Password, errorAuth, "", ""))
{//Авторизуется обучаемый
client->getClient()->setLogin(clientAutorization.Login);
client->getClient()->setAccessType(UserType::TRAINEE);
emit sigUpdateListClients();
//KAV redact
instructorName = providerDBLMS->getMainInstructorName();
traineeName = providerDBLMS->getNameTraineeByLogin(clientAutorization.Login);
clientID = providerDBLMS->getIdTraineeByLogin(clientAutorization.Login);
client->getClient()->setId(QString::number(clientID));
arrayAnswer = dataParser->ClientAnswer()->authorization(true, instructorName, traineeName, "trainee", clientAutorization.Login, clientID);
}
else
{//Никто не авторизовался
arrayAnswer = dataParser->ClientAnswer()->authorization(false, "", "", "", "", 0);
}
}
else
{//Никто не авторизовался
arrayAnswer = dataParser->ClientAnswer()->authorization(false, "", "", "", "", 0);
}
client->sendXmlAnswer(arrayAnswer);
if(errorAuth == InterfaceDataBaseLMS::ErrorAuth::errNo)
{
client->sendVersion();
//client->sendPacketType(PacketType::BUSY);
//client->sendPacketType(PacketType::FREE);
//Извещаем об изменениях в авторизации
emit sigListsInstructorsTraineesChanged();
}
else
{
QString notifyText = "";
switch (errorAuth)
{
case InterfaceDataBaseLMS::ErrorAuth::errDB:
notifyText = NOTIFY_ERROR_AUTH_DB;
break;
case InterfaceDataBaseLMS::ErrorAuth::errArchived:
notifyText = NOTIFY_ERROR_AUTH_ARCHIVED;
break;
case InterfaceDataBaseLMS::ErrorAuth::errAlreadyLogIn:
notifyText = NOTIFY_ERROR_AUTH_ALREADYLOGIN;
break;
case InterfaceDataBaseLMS::ErrorAuth::errLoginOrPassword:
notifyText = NOTIFY_ERROR_AUTH_LOGINORPASSWORD;
break;
default:
break;
}
QByteArray arrayAnswer = dataParser->ClientAnswer()->notify(notifyText);
client->sendXmlAnswer(arrayAnswer);
}
}
void ProcessingSystem::processingClientDeAutorization(ClientHandler *client, ClientDeAutorization clientDeAutorization)
{
/*
if(server->getStateBlockAutorization() == blocked)
{
QByteArray arrayAnswer = dataParser->ClientAnswer()->notify(NOTIFY_SERVER_BLOCKED);
client->sendXmlAnswer(arrayAnswer);
QString str = QString(arrayAnswer);
Logger::instance().log("To Client: " + str);
return;
}
*/
//Попытка ДеАвторизации клиента (проверка по БД)
QByteArray arrayAnswer;
if(providerDBLMS->deAuthorizationTrainee(clientDeAutorization.Login))
{//ДеАвторизуется обучаемый
client->getClient()->setLogin("");
client->getClient()->setAccessType(UserType::NONE);
client->getClient()->setIsLoggedIn(false);
emit sigUpdateListClients();
arrayAnswer = dataParser->ClientAnswer()->deAuthorization(true, clientDeAutorization.Login);
client->sendXmlAnswer(arrayAnswer);
//Извещаем об изменениях в авторизации
emit sigListsInstructorsTraineesChanged();
}
else if(providerDBLMS->deAuthorizationInstructor(clientDeAutorization.Login))
{//ДеАвторизуется инструктор
client->getClient()->setLogin("");
client->getClient()->setAccessType(UserType::NONE);
client->getClient()->setIsLoggedIn(false);
emit sigUpdateListClients();
arrayAnswer = dataParser->ClientAnswer()->deAuthorization(true, clientDeAutorization.Login);
client->sendXmlAnswer(arrayAnswer);
//Извещаем об изменениях в авторизации
emit sigListsInstructorsTraineesChanged();
}
else
{//Никто не ДеАвторизовался
arrayAnswer = dataParser->ClientAnswer()->deAuthorization(false, "");
client->sendXmlAnswer(arrayAnswer);
}
}
void ProcessingSystem::processingClientBlockAuth(ClientHandler *client, bool block)
{
emit providerDBLMS->signal_BlockAutorization(block);
}
//упращенная деавторизация при выключении сервера
void ProcessingSystem::processingClientDeAutorization(QString login)
{
//Отмена авторизации в БД
if(providerDBLMS->deAuthorizationTrainee(login))
{//Деавторизовался обучаемый
}
else if(providerDBLMS->deAuthorizationInstructor(login))
{//Деавторизовался инструктор
}
}
void ProcessingSystem::processingEntryUnityClient(ClientHandler *client)
{
QString login = client->getClient()->getLogin();
UserType userType = client->getClient()->getAccessType();
if(userType == UserType::TRAINEE)
{
int id_trainee = providerDBLMS->getIdTraineeByLogin(login);
providerDBLMS->entryTraineeOnSimulator(id_trainee);
}
else if(userType == UserType::INSTRUCTOR)
{
//Здесь пока ничего не происходит
}
}
void ProcessingSystem::processingExitUnityClient(ClientHandler *client)
{
QString login = client->getClient()->getLogin();
UserType userType = client->getClient()->getAccessType();
if(userType == UserType::TRAINEE)
{
int id_trainee = providerDBLMS->getIdTraineeByLogin(login);
providerDBLMS->exitTraineeFromSimulator(id_trainee);
}
else if(userType == UserType::INSTRUCTOR)
{
//Здесь пока ничего не происходит
}
}
void ProcessingSystem::processingClientQueryToDB(ClientHandler *client, ClientQueryToDB clientQueryToDB, int id, void* data)
{
qDebug() << "ProcessingQueryThread " << QThread::currentThreadId();
switch (clientQueryToDB.typeQuery)
{
case TypeQueryToDB::TYPE_QUERY_GET_ALL_LISTS:
{
QList<Instructor> listInstructors = providerDBLMS->GetListAllInstructors();
QList<Trainee> listTrainees = providerDBLMS->GetListAllTrainees();
QList<Group> listGroups = providerDBLMS->GetListAllGroups();
QByteArray arrayAnswer;
arrayAnswer = dataParser->DbAnswer()->listInstructors(true, &listInstructors);
//client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_DB__LIST_INSTRUCTORS);
client->sendFileBlockByteArray(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_DB__LIST_INSTRUCTORS);
arrayAnswer = dataParser->DbAnswer()->listGroups(true, &listGroups);
//client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_DB__LIST_GROUPS);
client->sendFileBlockByteArray(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_DB__LIST_GROUPS);
arrayAnswer = dataParser->DbAnswer()->listTrainees(true, &listTrainees);
//client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_DB__LIST_TRAINEES);
client->sendFileBlockByteArray(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_DB__LIST_TRAINEES);
break;
}
case TypeQueryToDB::TYPE_QUERY_NEW_INSTRUCTOR:
{
int id_new;
id_new = providerDBLMS->newInstructor();
if(id_new)
{
(*(Instructor*)data).setID(id_new);
providerDBLMS->editInstructor(*(Instructor*)data);
}
emit sigListsInstructorsTraineesChanged();
break;
}
case TypeQueryToDB::TYPE_QUERY_DEL_INSTRUCTOR:
{
providerDBLMS->delInstructor(id);
emit sigListsInstructorsTraineesChanged();
break;
}
case TypeQueryToDB::TYPE_QUERY_EDIT_INSTRUCTOR:
{
providerDBLMS->editInstructor(*(Instructor*)data);
emit sigListsInstructorsTraineesChanged();
break;
}
case TypeQueryToDB::TYPE_QUERY_NEW_TRAINEE:
{
int id_new;
id_new = providerDBLMS->newTrainee(id);
if(id_new)
{
(*(Trainee*)data).setID(id_new);
providerDBLMS->editTrainee(*(Trainee*)data);
}
emit sigListsInstructorsTraineesChanged();
break;
}
case TypeQueryToDB::TYPE_QUERY_DEL_TRAINEE:
{
providerDBLMS->delTrainee(id);
emit sigListsInstructorsTraineesChanged();
break;
}
case TypeQueryToDB::TYPE_QUERY_EDIT_TRAINEE:
{
providerDBLMS->editTrainee(*(Trainee*)data);
emit sigListsInstructorsTraineesChanged();
break;
}
case TypeQueryToDB::TYPE_QUERY_NEW_GROUP:
{
int id_new;
id_new = providerDBLMS->newGroup();
if(id_new)
{
(*(Group*)data).setID(id_new);
providerDBLMS->editGroup(*(Group*)data);
}
emit sigListsInstructorsTraineesChanged();
break;
}
case TypeQueryToDB::TYPE_QUERY_DEL_GROUP:
{
providerDBLMS->delGroup(id);
emit sigListsInstructorsTraineesChanged();
break;
}
case TypeQueryToDB::TYPE_QUERY_EDIT_GROUP:
{
providerDBLMS->editGroup(*(Group*)data);
emit sigListsInstructorsTraineesChanged();
break;
}
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_AMM_TO_TRAINEE:
{
int id_trainee = id;
if(int id_new = providerDBLMS->newTaskAMM(*(TaskAmmFim*)data, id_trainee))
{
//Отправка списка задач AMM всем клиентам GUI
//sendListTasksAMMofTraineetoClient(client, id_trainee);
emit sigStatusTasksAMMofTraineeChanged(id_trainee);
//Отправка списка задач AMM клиенту Юнити
if(ClientHandler* clientUnity = getUnityClientById(id_trainee))
{//Есть такой
//sendListTasksAMMofTraineetoClient(clientUnity, id_trainee);
QList<int> listID;
listID.append(id_new);
sendListTasksAMMofTraineeByIDtoClient(clientUnity, id_trainee, listID);
}
}
break;
}
case TypeQueryToDB::TYPE_QUERY_ASSIGN_TASK_FIM_TO_TRAINEE:
{
int id_trainee = id;
if(int id_new = providerDBLMS->newTaskFIM(*(TaskAmmFim*)data, id_trainee))
{
//Отправка списка задач FIM всем клиентам GUI
//sendListTasksFIMofTraineetoClient(client, id_trainee);
emit sigStatusTasksFIMofTraineeChanged(id_trainee);
//Отправка списка задач FIM клиенту Юнити
if(ClientHandler* clientUnity = getUnityClientById(id_trainee))
{//Есть такой
//sendListTasksFIMofTraineetoClient(clientUnity, id_trainee);
QList<int> listID;
listID.append(id_new);
sendListTasksFIMofTraineeByIDtoClient(clientUnity, id_trainee, listID);
}
}
break;
}
case TypeQueryToDB::TYPE_QUERY_GET_TASKS_AMM_FOR_TRAINEE:
{
int id_trainee = id;
//Отправка списка задач AMM клиенту GUI
sendListTasksAMMofTraineetoClient(client, id_trainee);
break;
}
case TypeQueryToDB::TYPE_QUERY_GET_TASKS_FIM_FOR_TRAINEE:
{
int id_trainee = id;
//Отправка списка задач FIM клиенту GUI
sendListTasksFIMofTraineetoClient(client, id_trainee);
break;
}
case TypeQueryToDB::TYPE_QUERY_DEL_TASK_AMM_TO_TRAINEE:
{
int id_task = id;
TaskAmmFim task = providerDBLMS->getTaskAMMbyID(id_task);
if(int id_trainee = providerDBLMS->delTaskAMM(id_task))
{
task.status = "deleted";
//Отправка списка задач AMM всем клиентам GUI
//sendListTasksAMMofTraineetoClient(client, id_trainee);
emit sigStatusTasksAMMofTraineeChanged(id_trainee);
//Отправка списка задач AMM клиенту Юнити
if(ClientHandler* clientUnity = getUnityClientById(id_trainee))
{//Есть такой
//sendListTasksAMMofTraineetoClient(clientUnity, id_trainee);
sendTaskAMMToClient(clientUnity, id_trainee, task);
}
}
break;
}
case TypeQueryToDB::TYPE_QUERY_DEL_TASK_FIM_TO_TRAINEE:
{
int id_task = id;
TaskAmmFim task = providerDBLMS->getTaskFIMbyID(id_task);
if(int id_trainee = providerDBLMS->delTaskFIM(id))
{
task.status = "deleted";
//Отправка списка задач FIM клиенту GUI
//sendListTasksFIMofTraineetoClient(client, id_trainee);
emit sigStatusTasksFIMofTraineeChanged(id_trainee);
//Отправка списка задач FIM клиенту Юнити
if(ClientHandler* clientUnity = getUnityClientById(id_trainee))
{//Есть такой
//sendListTasksFIMofTraineetoClient(clientUnity, id_trainee);
sendTaskFIMToClient(clientUnity, id_trainee, task);
}
}
break;
}
case TypeQueryToDB::TYPE_QUERY_SET_REPORT_TASK_AMM_TO_TRAINEE:
{
TaskAmmFim* task = (TaskAmmFim*)data;
if(task->status == "completed")
if( int id_trainee = providerDBLMS->changeStatusTaskAMM(task->getID(), "completed") )
{
}
break;
}
case TypeQueryToDB::TYPE_QUERY_SET_REPORT_TASK_FIM_TO_TRAINEE:
{
TaskAmmFim* task = (TaskAmmFim*)data;
if(task->status == "checkup")
if(int id_report = providerDBLMS->replaceReportFIM(*task))
{
}
break;
}
case TypeQueryToDB::TYPE_QUERY_CHANGE_STATUS_REPORT_TASK_AMM_TO_TRAINEE:
{
QString* status = (QString*)data;
if(int id_trainee = providerDBLMS->changeStatusTaskAMM(id, *status))
{
//Отправка списка задач AMM всем клиентам GUI
//sendListTasksAMMofTraineetoClient(client, id_trainee);
emit sigStatusTasksAMMofTraineeChanged(id_trainee);
//Отправка списка задач AMM клиенту Юнити
if(ClientHandler* clientUnity = getUnityClientById(id_trainee))
{//Есть такой
//sendListTasksAMMofTraineetoClient(clientUnity, id_trainee);
QList<int> listID;
listID.append(id);
sendListTasksAMMofTraineeByIDtoClient(clientUnity, id_trainee, listID);
}
}
break;
}
case TypeQueryToDB::TYPE_QUERY_CHANGE_STATUS_REPORT_TASK_FIM_TO_TRAINEE:
{
QString* status = (QString*)data;
if(int id_trainee = providerDBLMS->changeStatusTaskFIM(id, *status))
{
//Отправка списка задач FIM всем клиентам GUI
//sendListTasksFIMofTraineetoClient(client, id_trainee);
emit sigStatusTasksFIMofTraineeChanged(id_trainee);
//Отправка списка задач FIM клиенту Юнити
if(ClientHandler* clientUnity = getUnityClientById(id_trainee))
{//Есть такой
//sendListTasksFIMofTraineetoClient(clientUnity, id_trainee);
QList<int> listID;
listID.append(id);
sendListTasksFIMofTraineeByIDtoClient(clientUnity, id_trainee, listID);
}
}
break;
}
case TypeQueryToDB::TYPE_QUERY_GET_CONTACT_LIST:
{
QList<ContactModel> entitylist;
QList<Instructor> listInstructor = providerDBLMS->GetListAllInstructors();
QList<Trainee> listTrainees = providerDBLMS->GetListAllTrainees();
for (Instructor instructor : listInstructor)
{
ContactModel model = ContactModel(instructor);
entitylist.append(model);
}
for (Trainee trainee : listTrainees)
{
ContactModel model = ContactModel(trainee);
entitylist.append(model);
}
QByteArray arrayAnswer;
arrayAnswer = dataParser->DbAnswer()->listContacts(true, &entitylist);
client->sendFileBlockByteArray(arrayAnswer,PacketType::TYPE_BIGXML);
}
}
}
void ProcessingSystem::processingClientQueryTasksXML(ClientHandler *client, ClientQueryTasksXML clientQueryTasksXML)
{
QByteArray arrayAnswer;
QString nameFile = "";
QString pathFile = "";
if(clientQueryTasksXML.Type == "fim")
{
nameFile = tasksFIMfileName;
pathFile = updateController->getPathAdditionalFile(nameFile);
Logger::instance().log(pathFile);
client->sendFileBlock(pathFile);
client->sendPacketType(PacketType::TYPE_XMLANSWER_QUERY_TASKS_XML_FIM);
}
else if(clientQueryTasksXML.Type == "amm")
{
nameFile = tasksAMMfileName;
pathFile = updateController->getPathAdditionalFile(nameFile);
docsUpdater->lockAccessToDocsXML();
client->sendFileBlock(pathFile);
client->sendPacketType(PacketType::TYPE_XMLANSWER_QUERY_TASKS_XML_AMM);
docsUpdater->unLockAccessToDocsXML();
}
}
void ProcessingSystem::processingClientQueryListSubProc(ClientHandler *client, QString dmCode)
{
QList<SubProc> list = docsUpdater->getListSubProcForDMcode(dmCode);
QByteArray arrayAnswer = dataParser->getDocsAnswerParser()->listSubProc(list, dmCode);
//client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_LIST_SUB_PROC_AMM);
client->sendFileBlockByteArray(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_LIST_SUB_PROC_AMM);
}
void ProcessingSystem::processingSendMessage(ClientMessage clientMessage)
{
chatSystem->sendMessage(clientMessage);
}
void ProcessingSystem::processingClientNotify(ClientHandler *client, ClientNotify clientNotify)
{
Client *clientData = client->getClient();
if(clientNotify.Code == commandReadyClient)
{//Клиент готов принять задания
client->setReady(true);
sendTaskListToUnity(client);
//client->getSocket()->flush();
}
else if(clientNotify.Code == commandStartTimerClient)
{
//Фиксируем время входа Юнити-клиента
if (clientData->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
processingEntryUnityClient(client);
}
}
else if(clientNotify.Code == commandDisableClient)
{
qDebug() << "processing thread: " << QThread::currentThreadId();
//Фиксируем время выхода Юнити-клиента
if (clientData->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
processingExitUnityClient(client);
}
client->sendDisable();
}
else if(clientNotify.Code == commandGetServerDataList)
{
client->sendHash();
}
else if(clientNotify.Code == commandCheckVersionList)
{
client->sendVersionList();
}
else if(clientNotify.Code == commandCanChangeVersion)
{
if (updateController->getCurrentVersion()->getIsChangeable())
{
client->sigSendNotify(commandChangable);
}
else
{
client->sigSendNotify(commandUnchangable);
}
}else if(clientNotify.Code == commandGetTasks)
{
sendTaskListToUnity(client);
}
else if (clientNotify.Code == commandeGetOfflineMessages)
{
chatSystem->sendOldMessages(clientData->getId());
}
}
void ProcessingSystem::setCurrentDataInfo(DataInfo *dataInfo)
{
emit sigSetData(dataInfo);
}
void ProcessingSystem::sendListTasksAMMofTraineetoClient(ClientHandler *client, int id_trainee)
{
QList<TaskAmmFim> listTasks = providerDBLMS->GetListTasksAMMofTrainee(id_trainee);
QByteArray arrayAnswer = dataParser->DbAnswer()->listTasksAMMofTrainee(true, &listTasks, id_trainee, true);
//client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_AMM_OF_TRAINEE);
client->sendFileBlockByteArray(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_AMM_OF_TRAINEE);
}
void ProcessingSystem::sendListTasksFIMofTraineetoClient(ClientHandler *client, int id_trainee)
{
QList<TaskAmmFim> listTasks = providerDBLMS->GetListTasksFIMofTrainee(id_trainee);
QByteArray arrayAnswer = dataParser->DbAnswer()->listTasksFIMofTrainee(true, &listTasks, id_trainee, true);
//client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_FIM_OF_TRAINEE);
client->sendFileBlockByteArray(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_FIM_OF_TRAINEE);
}
void ProcessingSystem::sendListTasksAMMofTraineeByIDtoClient(ClientHandler *client, int id_trainee, QList<int> listID)
{
QList<TaskAmmFim> listTasksNeed;
QList<TaskAmmFim> listTasks = providerDBLMS->GetListTasksAMMofTrainee(id_trainee);
for(int i = 0; i < listTasks.count(); i++)
{
TaskAmmFim task = listTasks.at(i);
bool flNeed = false;
for(int id : listID)
{
if(id == task.getID())
{
flNeed = true;
break;
}
}
if(flNeed)
listTasksNeed.append(listTasks.at(i));
}
QByteArray arrayAnswer = dataParser->DbAnswer()->listTasksAMMofTrainee(true, &listTasksNeed, id_trainee, false);
//client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_AMM_OF_TRAINEE);
client->sendFileBlockByteArray(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_AMM_OF_TRAINEE);
}
void ProcessingSystem::sendListTasksFIMofTraineeByIDtoClient(ClientHandler *client, int id_trainee, QList<int> listID)
{
QList<TaskAmmFim> listTasksNeed;
QList<TaskAmmFim> listTasks = providerDBLMS->GetListTasksFIMofTrainee(id_trainee);
for(int i = 0; i < listTasks.count(); i++)
{
TaskAmmFim task = listTasks.at(i);
bool flNeed = false;
for(int id : listID)
{
if(id == task.getID())
{
flNeed = true;
break;
}
}
if(flNeed)
listTasksNeed.append(listTasks.at(i));
}
QByteArray arrayAnswer = dataParser->DbAnswer()->listTasksFIMofTrainee(true, &listTasksNeed, id_trainee, false);
//client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_FIM_OF_TRAINEE);
client->sendFileBlockByteArray(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_FIM_OF_TRAINEE);
}
void ProcessingSystem::sendTaskAMMToClient(ClientHandler *client, int id_trainee, TaskAmmFim task)
{
QList<TaskAmmFim> listTasks;
listTasks.append(task);
QByteArray arrayAnswer = dataParser->DbAnswer()->listTasksAMMofTrainee(true, &listTasks, id_trainee, false);
//client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_AMM_OF_TRAINEE);
client->sendFileBlockByteArray(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_AMM_OF_TRAINEE);
}
void ProcessingSystem::sendTaskFIMToClient(ClientHandler *client, int id_trainee, TaskAmmFim task)
{
QList<TaskAmmFim> listTasks;
listTasks.append(task);
QByteArray arrayAnswer = dataParser->DbAnswer()->listTasksFIMofTrainee(true, &listTasks, id_trainee, false);
//client->sendXmlAnswer(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_FIM_OF_TRAINEE);
client->sendFileBlockByteArray(arrayAnswer, PacketType::TYPE_XMLANSWER_QUERY_TASKS_FIM_OF_TRAINEE);
}
void ProcessingSystem::sendTaskListToUnity(ClientHandler *client)
{
//Отправка списков задач клиенту Юнити
if(client->getClient()->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
QString login = client->getClient()->getLogin();
int id_trainee = providerDBLMS->getIdTraineeByLogin(login);
//AMM
QList<TaskAmmFim> listTasksAMM = providerDBLMS->GetListTasksAMMofTrainee(id_trainee);
QByteArray arrayAnswerTasksAMM = dataParser->DbAnswer()->listTasksAMMofTrainee(true, &listTasksAMM, id_trainee, true);
client->sendFileBlockByteArray(arrayAnswerTasksAMM, PacketType::TYPE_XMLANSWER_QUERY_TASKS_AMM_OF_TRAINEE);
//FIM
QList<TaskAmmFim> listTasksFIM = providerDBLMS->GetListTasksFIMofTrainee(id_trainee);
QByteArray arrayAnswerFIM = dataParser->DbAnswer()->listTasksFIMofTrainee(true, &listTasksFIM, id_trainee, true);
client->sendFileBlockByteArray(arrayAnswerFIM, PacketType::TYPE_XMLANSWER_QUERY_TASKS_FIM_OF_TRAINEE);
}
}
ClientHandler *ProcessingSystem::getUnityClientById(int id)
{
QString login = providerDBLMS->getLoginTraineeById(id);
//Проходим все открытые сокеты, ищем нужный
foreach(int idSocket, server->getClientsMap()->keys())
{
ClientHandler *handler = server->getClientsMap()->value(idSocket);
if(handler->getClient()->getLogin() == login)
{
if(handler->getClient()->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
return handler;
}
}
}
return nullptr;
}

View File

@@ -0,0 +1,81 @@
#ifndef PROCESSINGSYSTEM_H
#define PROCESSINGSYSTEM_H
#include <Systems/sendsystem.h>
#include <Data/typesDataServerClient.h>
#include <clienthandler.h>
#include <serverlmswidget.h>
#include "multithreadserver.h"
//#include "instructorsandtraineeswidget.h"
#include "chatsystem.h"
#include "providerdblms.h"
#include "docsupdater.h"
class SendSystem;
class ServerLMSWidget;
class InstructorsAndTrainees;
class Logger;
class DataParser;
class ClientHandler;
class CommonClientHandler;
class MultiThreadServer;
class ProcessingSystem : public QObject
{
Q_OBJECT
public:
explicit ProcessingSystem(ProviderDBLMS* providerDBLMS, UpdateController* updateController, DocsUpdater* docsUpdater, QObject *parent = nullptr);
void initialize(MultiThreadServer *server,
DataParser* dataParser,
CommonClientHandler *commonClientServer,
UpdateController *updateComtroller,
ChatSystem *chatSystem);
void processingClientAutorization(ClientHandler *client, ClientAutorization clientAutorization);
void processingClientDeAutorization(ClientHandler *client, ClientDeAutorization clientDeAutorization);
void processingClientBlockAuth(ClientHandler *client, bool block);
void processingClientQueryToDB(ClientHandler *client, ClientQueryToDB clientQueryToDB, int id = 0, void* data = nullptr);
void processingClientQueryTasksXML(ClientHandler *client, ClientQueryTasksXML clientQueryTasksXML);
void processingClientQueryListSubProc(ClientHandler *client, QString dmCode);
void processingSendMessage(ClientMessage clientMessage);
void processingClientNotify(ClientHandler *client, ClientNotify clientNotify);
void setCurrentDataInfo(DataInfo *dataInfo);
void sendListTasksAMMofTraineetoClient(ClientHandler* client, int id_trainee);
void sendListTasksFIMofTraineetoClient(ClientHandler* client, int id_trainee);
void sendListTasksAMMofTraineeByIDtoClient(ClientHandler* client, int id_trainee, QList<int> listID);
void sendListTasksFIMofTraineeByIDtoClient(ClientHandler* client, int id_trainee, QList<int> listID);
void sendTaskAMMToClient(ClientHandler* client, int id_trainee, TaskAmmFim task);
void sendTaskFIMToClient(ClientHandler* client, int id_trainee, TaskAmmFim task);
ClientHandler* getUnityClientById(int id);
void processingClientDeAutorization(QString login);
void processingEntryUnityClient(ClientHandler *client);
void processingExitUnityClient(ClientHandler *client);
signals:
void sigUpdateListClients();
void sigListsInstructorsTraineesChanged();
void sigStatusTasksAMMofTraineeChanged(int trainee_id);
void sigStatusTasksFIMofTraineeChanged(int trainee_id);
void sigAddToMessanger(QString login,QString text);
void sigSetData(DataInfo *dataInfo);
private:
CommonClientHandler *commonClientServer;
MultiThreadServer *server;
DataParser *dataParser;
UpdateController *updateController;
DocsUpdater* docsUpdater;
ProviderDBLMS* providerDBLMS;
ChatSystem *chatSystem;
void sendTaskListToUnity(ClientHandler *client);
};
#endif // PROCESSINGSYSTEM_H

View File

@@ -0,0 +1,527 @@
#include "recognizesystem.h"
RecognizeSystem::RecognizeSystem(QObject *parent):
QObject(parent)
{
packetType = PacketType::TYPE_NONE;
filePath.clear();
fileSize = 0;
sizeReceiveData = 0;
tmpBlock.clear();
countSend = 0;
mutex = new QMutex;
}
void RecognizeSystem::initialize(UpdateController *updateController,DataParser* dataParser,
ServerLMSWidget *server,SendSystem *sendSystem, ClientHandler *handler)
{
this->updateController = updateController;
this->dataParser = dataParser;
this->server = server;
this->clientHandler = handler;
this->sendSystem = sendSystem;
socket = handler->getSocket();
connect(this,&RecognizeSystem::sigCalculateHash,updateController,&UpdateController::calculateFullHashWithSetup,Qt::AutoConnection);
connect(this,&RecognizeSystem::sigChangeVersion,updateController,&UpdateController::changeAssetVersion,Qt::AutoConnection);
connect(this,&RecognizeSystem::sigDeleteVersion,updateController,&UpdateController::deleteAssetVersion,Qt::AutoConnection);
connect(this,&RecognizeSystem::sigCopyVersion,updateController,&UpdateController::createCopyVersion,Qt::AutoConnection);
connect(this,&RecognizeSystem::sigXmlParser,dataParser->getProcessParser(),&ProcessParser::slot_read,Qt::AutoConnection);
connect(this,&RecognizeSystem::sigRecalculateDocs,server,&ServerLMSWidget::slot_UpdateDocs,Qt::AutoConnection);
connect(this,&RecognizeSystem::sigSendDocs,sendSystem,&SendSystem::sendDocs,Qt::AutoConnection);
qDebug() << "Recognize init thread ID " << QThread::currentThreadId();
}
void RecognizeSystem::recognize()
{
QMutexLocker locker(mutex);
qDebug() << "Recognize thread ID " << QThread::currentThreadId();
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
QByteArray data;
Client *client = clientHandler->getClient();
while (socket->bytesAvailable() > 0)
{
if (packetType == PacketType::TYPE_NONE)
{
stream.startTransaction();
if(client->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
char *read = new char[4];
stream.readRawData(read,4);
int numPackage = *((int*)read);
packetType = static_cast<PacketType>(numPackage);
socket->peek(read,4);
if(!stream.commitTransaction()) continue;
continue;
}
else
{
stream >> packetType;
if(!stream.commitTransaction()) continue;
}
}
if (packetType != PacketType::TYPE_NONE)
{
QString result = enumToString(packetType);
Logger::instance().log("RECEIVE FROM: " + client->getLogin() + " " +
result ,LogLevel::DEBUG);
//секция на случай прихода неизвестного пакета
if(result == "Unknown")
{
qDebug() << " State:" << socket->state();
qDebug() << " Error:" << socket->error();
qDebug() << " Bytes to write:" << socket->bytesToWrite();
qDebug() << " Bytes available:" << socket->bytesAvailable();
if(client->getTypeClient() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
data = socket->readAll();
}
else
{
stream.startTransaction();
stream >> data;
}
QString dataText = QString::fromUtf8(data);
Logger::instance().log(QString::number(packetType) + " Unknown text " + dataText);
Logger::instance().log("Client error: " + client->getLogin(),LogLevel::ERROR);
clientHandler->sendDisable();
//mutex->unlock();
}
}
if (packetType == PacketType::TYPE_COMMAND) //TODO: надо переделать под какой то нормальный тип, который уже существует
{
stream.startTransaction();
stream >> command;
if (!stream.commitTransaction()) continue;
}
if (packetType == PacketType::TYPE_UPDATE)
{
QList<FileData> sendList = updateController->prepareRealPathList(client->getFileSendList());
sendSystem->updateFiles(sendList,
client->getFileDeleteList());
qDebug()<< "Call update no docs";
packetType = PacketType::TYPE_NONE;
}
if(packetType == PacketType::TYPE_CHECK_VERSION)
{
updateController->compareFiles(clientHandler,client->getClientHash());
}
if (packetType == PacketType::TYPE_XMLANSWER)
{
if(clientHandler->getClient()->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
data = socket->readAll();
}
else
{
stream.startTransaction();
stream >> data;
if(!stream.commitTransaction()) continue;
}
qDebug() << data;
emit sigXmlParser(clientHandler,data);
Logger::instance().log(" Text " + QString(data), LogLevel::DEBUG);
packetType = PacketType::TYPE_NONE;
continue;
}
if(packetType == PacketType::TYPE_BIGXML)
{
if (clientHandler->getClient()->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
char *readBuffer = new char[4];
socket->read(readBuffer,4);
fileSize = *((int*)readBuffer);
//if(!stream.commitTransaction()) continue;
//ПОЛУЧЕНИЕ САМОГО ФАЙЛА
Logger::instance().log("AfterRead size and path BytesAvailable: " + QString::number(socket->bytesAvailable()));
qint64 readSize = readFileBlockSize;
forever
{
if(fileSize < readSize)
{
readSize = fileSize;
Logger::instance().log("LastPackage: " + QString::number(readSize));
}
socket->waitForReadyRead(20);
tmpBlock = socket->read(readSize);
data.append(tmpBlock);
fileSize -= readSize;
sizeReceiveData += readSize;
countSend++;
tmpBlock.clear();
if(fileSize == 0) break;
}
Logger::instance().log("File loaded");
emit sigXmlParser(clientHandler,data);
//ОЧИСТКА ПОСЛЕ ПЕРЕДАЧИ
fileSize = 0;
tmpBlock.clear();
sizeReceiveData = 0;
countSend = 0;
packetType = PacketType::TYPE_NONE;
data.clear();
continue;
}
}
if(packetType == PacketType::TYPE_FOLDER) //создание папок
{
if(client->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
filePath = socket->readAll();
filePath = Tools::createSharedPath(filePath);
}
else
{
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) //выгрузка одного файла
{
if(client->getClientType() == TypeClientAutorization::TYPE_UNITY_CLIENT)
{
DataInfo *currentFileData = updateController->getCurrentDataInfo();
filePath = currentFileData->path;
filePath = Tools::createSharedPath(filePath);
QFile file(filePath);
if (file.exists())
{
file.remove(); //удаление файла, если он уже есть, но необходимо обновить
Logger::instance().log("Delete exist file: " + filePath);
}
if (!file.open(QFile::Append))
{
QString folderPath = Tools::createFolderPath(filePath);
qDebug() << "FULL PATH: " << folderPath;
QDir dir(folderPath);
if (!dir.exists()){
dir.mkpath(".");
}
file.open(QFile::Append);
}
//socket->waitForReadyRead(1000);
fileSize = currentFileData->size;
qint64 readSize = 65535;
forever
{
if(fileSize < readSize)
{
readSize = fileSize;
qDebug() << "LastPackage: " << readSize;
}
socket->waitForReadyRead(20);
tmpBlock = socket->read(readSize);
quint64 toFile = file.write(tmpBlock);
fileSize -= toFile;
sizeReceiveData += toFile;
countSend++;
tmpBlock.clear();
qDebug() << "Loading progress: " << fileSize << "/" << currentFileData->size;
if(fileSize == 0) break;
}
file.close();
filePath.clear();
updateController->clearCurrentDataInfo();
socket->waitForReadyRead(100);
packetType = PacketType::TYPE_NONE;
}
else
{
forever
{
stream.startTransaction();
stream >> filePath;
stream >> fileSize;
if(!stream.commitTransaction()) continue;
filePath = Tools::createFullPath(filePath);
socket->waitForReadyRead(100);
break;
}
QFile file(filePath);
QFileInfo fileInfo(file);
if(file.exists())
{
file.remove();
}
file.open(QFile::Append);
forever
{
stream.startTransaction();
stream >> tmpBlock;
if(!stream.commitTransaction()){
if(socket->state() == QAbstractSocket::UnconnectedState){
qDebug() << "UNCONNECT";
//mutex->unlock();
file.close();
return;
}
if(socket->waitForReadyRead(100)){
continue;
}
continue;
}
quint64 toFile = file.write(tmpBlock);
sizeReceiveData += toFile;
countSend++;
tmpBlock.clear();
if(sizeReceiveData == fileSize) break;
}
QString logMessage = "Load from " + client->getLogin() + " ";
logMessage.append(fileInfo.fileName());
Logger::instance().log(logMessage);
file.close();
filePath.clear();
fileSize = 0;
tmpBlock.clear();
sizeReceiveData = 0;
countSend = 0;
packetType = PacketType::TYPE_NONE;
}
}
if (packetType == PacketType::TYPE_FILESIZE)
{
fileSize = socket->readAll().toULong();
qDebug() << fileSize;
packetType = PacketType::TYPE_NONE;
continue;
}
if(packetType == PacketType::GET_VERSION)
{
clientHandler->sendVersion();
}
if(packetType == PacketType::CHANGE_DATA_VERSION)
{
stream.startTransaction();
QString versionName;
stream >> versionName;
if(!stream.commitTransaction()) continue;
qDebug() << "For change " + versionName;
emit sigChangeVersion(versionName);
}
if(packetType == PacketType::COPY_VERSION)
{
QString source;
QStringList result;
stream.startTransaction();
stream >> source;
if(!stream.commitTransaction()) continue;
result = source.split(";");
if (updateController->checkDuplicate(result[1]))
{
sendSystem->sendNotify(commandDuplicateVerName);
packetType = PacketType::TYPE_NONE;
break;
}
emit sigCopyVersion(result[0],result[1],result[2]);
sendSystem->sendPacketType(PacketType::BUSY);
}
if(packetType == PacketType::DELETE_DATA_VERSION)
{
stream.startTransaction();
QString versionName;
stream >> versionName;
if(!stream.commitTransaction()) continue;
qDebug() << "For delete " + versionName;
if (versionName == baseNameVersion)
{
sendSystem->sendNotify(commandTryBaseDelete);
}
else if (versionName == updateController->getCurrentVersionName())
{
sendSystem->sendNotify(commandTryActiveDelete);
}
else
{
emit sigDeleteVersion(versionName);
}
}
if(packetType == PacketType::TYPE_DISABLE)
{
clientHandler->sendDisable();
}
if(packetType == PacketType::RECALCULATE_DOCS)
{
emit sigCalculateHash();
emit sigRecalculateDocs();
}
if(packetType == PacketType::GET_DOCS)
{
emit sigSendDocs(updateController->getPathAdditionalFile(tasksAMMfileName));
}
if (packetType == PacketType::SEND_HASH)
{
QByteArray hash;
forever
{
stream.startTransaction();
stream >> fileSize;
if(!stream.commitTransaction()) continue;
socket->waitForReadyRead(100);
break;
}
forever
{
stream.startTransaction();
stream >> tmpBlock;
if(!stream.commitTransaction()){
if(socket->state() == QAbstractSocket::UnconnectedState){
qDebug() << "UNCONNECT";
//mutex->unlock();
return;
}
if(socket->waitForReadyRead(100)){
continue;
}
continue;
}
hash += tmpBlock;
sizeReceiveData += tmpBlock.length();
countSend++;
tmpBlock.clear();
if(sizeReceiveData == fileSize) break;
}
QString logMessage = "Load from " + client->getLogin() + " ";
filePath.clear();
fileSize = 0;
tmpBlock.clear();
sizeReceiveData = 0;
countSend = 0;
packetType = PacketType::TYPE_NONE;
client->setClientHash(hash);
}
packetType = PacketType::TYPE_NONE;
}
//mutex->unlock();
}
bool RecognizeSystem::checkIsChangeable()
{
return updateController->getCurrentVersion()->getIsChangeable();
}
RecognizeSystem::~RecognizeSystem()
{
}

View File

@@ -0,0 +1,65 @@
#ifndef RECOGNIZESYSTEM_H
#define RECOGNIZESYSTEM_H
#include <QDataStream>
#include <QTcpSocket>
#include <QMutex>
#include <Systems/updatecontroller.h>
#include <Systems/tools.h>
#include <Systems/Parsers/dataparser.h>
#include <Data/Client.h>
#include <Data/PacketType.h>
#include "serverlmswidget.h"
class UpdateController;
class ServerLMSWidget;
class ClientHandler;
class RecognizeSystem : public QObject
{
Q_OBJECT
public:
RecognizeSystem(QObject *parent = nullptr);
void initialize(UpdateController *updateController,DataParser *dataParser,
ServerLMSWidget *server,SendSystem *sendSystem, ClientHandler *handler);
void recognize();
~RecognizeSystem();
signals:
void sigCalculateHash();
void sigSendToLogger(QString string);
void sigXmlParser(ClientHandler *clientHandler,QByteArray data);
void sigChangeVersion(QString versionName);
void sigDeleteVersion(QString versionName);
void sigCopyVersion(QString versionName,QString newVersionName,QString author);
void sigRecalculateDocs();
void sigSendDocs(QString docsPath);
private:
UpdateController *updateController;
SendSystem *sendSystem;
DataParser *dataParser;
ServerLMSWidget *server;
QString command;
PacketType packetType;
QString filePath;
ClientHandler *clientHandler;
QMutex *mutex;
QTcpSocket *socket;
QByteArray tmpBlock;
qint64 sizeReceiveData;
qint64 fileSize;
int countSend;
void packetTypeInit(PacketType packet,Client *client);
bool checkIsChangeable();
};
#endif // RECOGNIZESYSTEM_H

View File

@@ -0,0 +1,347 @@
#include "sendsystem.h"
SendSystem::SendSystem(QObject *parent) : QObject(parent)
{
isSendStopped = false;
}
void SendSystem::initialize(DataParser *dataParser,QMutex *globalMutex)
{
this->dataParser = dataParser;
connect(this,&SendSystem::sigSendXMLmessage,dataParser->ClientAnswer(),&ClientAnswerParser::message,Qt::AutoConnection);
connect(this,&SendSystem::sigSendNotify,dataParser->ClientAnswer(),&ClientAnswerParser::notify,Qt::DirectConnection); //потому что возвращает значение
connect(this,&SendSystem::sigSendVersion,dataParser->ClientAnswer(),&ClientAnswerParser::currentVersion,Qt::AutoConnection);
qDebug() << "SendSystem thread: " << QThread::currentThreadId();
mutex = globalMutex;
}
void SendSystem::setClient(Client *client,QTcpSocket *socket)
{
this->socket = socket;
this->type = client->getClientType();
this->client = client;
isSendStopped = false;
}
void SendSystem::sendNotify(QString notify)
{
qDebug() << "SendNotify thread: " << QThread::currentThreadId();
auto answer = emit sigSendNotify(notify);
sendXmlAnswer(answer);
}
void SendSystem::sendFileBlock(QString path)
{
QFile file(path);
QFileInfo fileInfo(file);
if(isSendStopped)
{ //Поведение на случай отключения клиента
file.close();
Logger::instance().log("UNLOCK STOP MUTEX : " + client->getLogin(),LogLevel::ERROR);
return;
}
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
fileSize = file.size();
if (fileSize == 0)
{
Logger::instance().log("Client: " + client->getLogin() + " WARNING! Zero size " + fileInfo.fileName(),LogLevel::ERROR);
Logger::instance().log(path,LogLevel::ERROR);
return;
}
stream << PacketType::TYPE_FILE; //Отправляем тип блока
stream << path << fileSize;
if(file.open(QFile::ReadOnly))
{
while(!file.atEnd())
{
QByteArray data = file.read(sendFileBlockSize);
stream << data;
//socket->waitForBytesWritten(10);
if(socket->state() == QAbstractSocket::UnconnectedState) break;
countSend++;
}
//emit sigSendToLogger(Tools::getTime() + " send file " + fileInfo.fileName());
}
file.close();
countSend = 0;
}
void SendSystem::sendFileBlockByteArray(QByteArray array, PacketType packetType)
{
if(client->getClientType() == TypeClientAutorization::TYPE_QT_CLIENT ||
client->getClientType() == TypeClientAutorization::TYPE_GUI)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
quint64 size = array.size();
qint64 bytesSended = 0;
if (size == 0)
{
Logger::instance().log(" WARNING! Zero size ",LogLevel::ERROR);
return;
}
stream << packetType; //Отправляем тип блока
stream << size;
while (size > 0)
{
QByteArray chunk = array.mid(bytesSended,sendFileBlockSize);
stream << chunk;
bytesSended += chunk.length();
size -= bytesSended;
}
}
else
{
sendPacketType(packetType);
quint64 size = array.size();
qint64 bytesSended = 0;
if (size == 0)
{
Logger::instance().log(" WARNING! Zero size ",LogLevel::ERROR);
return;
}
QByteArray message;
message.append(reinterpret_cast<char*>(&size), sizeof(int));
socket->write(message);
while (size > 0)
{
QByteArray chunk = array.mid(bytesSended,sendFileBlockSize);
quint64 bytesSended = socket->write(chunk);
size -= bytesSended;
}
}
}
void SendSystem::sendVersion()
{
QByteArray data = dataParser->ClientAnswer()->currentVersion();
sendXmlAnswer(data);
}
void SendSystem::sendFileBlockWithRename(QString path, QString newName)
{
qDebug() << "sendFileBlockWithRename thread: " << QThread::currentThreadId();
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
QFile file(Tools::createRootPath(path));
QFileInfo fileInfo(file);
fileSize = fileInfo.size();
if(fileSize == 0){
Logger::instance().log("Client: " + client->getLogin() + " WARNING! Zero size " + fileInfo.fileName(),LogLevel::ERROR);
return;
}
QString pathForSend = Tools::createFolderPath(path) + "/" + staticDataFolderName + newName;
stream << PacketType::TYPE_FILE; //Отправляем тип блока
stream << pathForSend << fileSize;
if(isSendStopped) { //Поведение на случай отключения клиента
file.close();
return;
}
socket->waitForBytesWritten();
if(file.open(QFile::ReadOnly)){
while(!file.atEnd()){
QByteArray data = file.read(sendFileBlockSize);
stream << data;
socket->waitForBytesWritten();
countSend++;
}
Logger::instance().log("Send file " + fileInfo.fileName());
}
file.close();
countSend = 0;
socket->waitForBytesWritten();
socket->waitForReadyRead(100);
sendNotify(commandHashCompleteClient);
}
void SendSystem::sendFolderBlock(QString path)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
stream << PacketType::TYPE_FOLDER;
stream << path;
}
void SendSystem::sendDeleteBlock(QString path)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
stream << PacketType::TYPE_DELETE;
stream << path;
qDebug() << "DELETE: " + path;
socket->waitForReadyRead(10);
}
void SendSystem::sendPacketType(PacketType packetType)
{
Logger::instance().log(" SEND TO: " + client->getLogin() + " " + enumToString(packetType), LogLevel::DEBUG);
if (client->getClientType() == TypeClientAutorization::TYPE_QT_CLIENT ||
client->getClientType() == TypeClientAutorization::TYPE_GUI)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
stream << packetType;
socket->waitForReadyRead(100);
}
else
{
QByteArray message;
int type = (int)packetType;
message.append(reinterpret_cast<char*>(&type), sizeof(int));
socket->write(message);
}
}
void SendSystem::sendHello()
{
socket->write(SERVER_HELLO);
}
void SendSystem::sendXmlAnswer(QByteArray array, PacketType packetType)
{
qDebug() << "SendSystemThread: " << QThread::currentThreadId();
Logger::instance().log("SEND TO: "+ client->getLogin() + " " + enumToString(packetType) + "\n Text: " +
QString(array),LogLevel::DEBUG);
if (client->getClientType() == TypeClientAutorization::TYPE_QT_CLIENT ||
client->getClientType() == TypeClientAutorization::TYPE_GUI)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
stream << packetType;
stream << array;
socket->waitForBytesWritten();
}
else
{
sendPacketType(packetType);
QByteArray message;
int size = array.length();
message.append(reinterpret_cast<char*>(&size), sizeof(int));
socket->write(message);
socket->write(array);
}
}
void SendSystem::sendNeedUpdate(bool flag,quint64 size,quint64 fileCount,quint64 deleteCount)
{
QDataStream stream(socket);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
stream << PacketType::TYPE_NEEDUPDATE;
stream << flag;
stream << size;
stream << fileCount;
stream << deleteCount;
}
void SendSystem::updateFiles(QList<FileData> fileSendList, QList<FileData> deleteList){
QMutexLocker locker(mutex);
QListIterator<FileData> clientIterator(deleteList);
while(clientIterator.hasNext())
{
FileData data = clientIterator.next();
sendDeleteBlock(data.path);
if(getIsSendStopped())
{
return;
}
}
QListIterator<FileData> serverIterator(fileSendList);
while(serverIterator.hasNext())
{
FileData data = serverIterator.next();
if (data.hash == "FOLDER")
{
sendFolderBlock(data.path);
socket->waitForBytesWritten();
}
else
{
sendFileBlock(data.path);
socket->waitForBytesWritten();
}
if(isSendStopped)
{
return;
}
}
sendPacketType(PacketType::UPDATE_FILES_COMPLETE);
}
void SendSystem::socketClose()
{
socket->close();
}
bool SendSystem::socketFlush() //TODO: проверить использование
{
return socket->flush();
}
void SendSystem::sendStop()
{
isSendStopped = true;
}
void SendSystem::sendDocs(QString docsPath)
{
sendFileBlock(docsPath);
}
bool SendSystem::getIsSendStopped() const
{
return isSendStopped;
}
SendSystem::~SendSystem()
{
}

View File

@@ -0,0 +1,69 @@
#ifndef SENDSYSTEM_H
#define SENDSYSTEM_H
#include <QObject>
#include <QString>
#include <QtNetwork>
#include <QMutex>
#include <Systems/Parsers/dataparser.h>
#include <Systems/tools.h>
#include <Data/Client.h>
#include <Data/PacketType.h>
class DataParser;
class FileData;
class SendSystem : public QObject
{
Q_OBJECT
public:
explicit SendSystem(QObject* parent = nullptr);
void initialize(DataParser* dataParser,QMutex *globalMutex);
void setClient(Client* client,QTcpSocket *socket);
void sendMessageBlock(QString message);
void sendFileBlock(QString path);
void sendFileBlockByteArray(QByteArray array, PacketType packetType);
void sendFileBlockWithRename(QString path,QString newName);
void sendFolderBlock(QString path);
void sendDeleteBlock(QString path);
void sendPacketType(PacketType packet);
void sendHello();
void sendNotify(QString notify);
void sendStop();
void sendDocs(QString docPath);
void sendXmlAnswer(QByteArray array, PacketType packetType = PacketType::TYPE_XMLANSWER);
void sendNeedUpdate(bool flag,quint64 size,quint64 fileCount,quint64 deleteCount);
void updateFiles(QList<FileData> fileSendList, QList<FileData> deleteList);
bool socketFlush();
bool getIsSendStopped() const;
~SendSystem();
void updateFilesFULL(QList<FileData> fileSendList, QList<FileData> deleteList);
public slots:
void socketClose();
void sendVersion();
signals:
void sigLoadHash();
QByteArray sigSendXMLmessage(QString loginFrom, QString loginTo, QString text, QString userType);
QByteArray sigSendNotify(QString message);
QByteArray sigSendVersion();
private:
Client *client;
QTcpSocket* socket;
DataParser* dataParser;
quint64 fileSize;
QMutex *mutex;
QWaitCondition *waitCondition;
int countSend;
bool isSendStopped;
TypeClientAutorization type;
};
#endif // SENDSYSTEM_H

140
Server/Systems/tools.cpp Normal file
View File

@@ -0,0 +1,140 @@
#include "tools.h"
#include <QDir>
void Tools::printTime()
{
qDebug() << QTime::currentTime().toString("hh:mm:ss.zzz");
}
QString Tools::createLocalPath(QString path)
{
qint8 pos = path.indexOf(applicationFolderName);
QString localPath = path.remove(0,--pos);
//qDebug() << "Local path: " << localPath;
return localPath;
}
QString Tools::createRootPath(QString path)
{
return QDir::currentPath() + path;
}
QString Tools::createSharedPath(QString path){
return QDir::currentPath()+ "/" + sharedDataFolderName + path;
}
QString Tools::createRealPath(QString path,StreamingVersionData* currentVersionData)
{
QString resultPath;
int index = path.indexOf(currentVersionData->getViewName());
if(index != -1)
{
resultPath = path.remove(0,index + currentVersionData->getViewName().length());
resultPath.prepend(buildDataPath + streamingAssetsFolderName);
}
else
{
resultPath = Tools::createRootPath(path);
}
return resultPath;
}
QString Tools::createStreamingToRealPath(QString path,StreamingVersionData* streamingVersionData)
{
QString resultPath = path;
int index = path.indexOf(streamingAssetsFolderName);
if(index != -1)
{
resultPath = path.remove(0,index + streamingAssetsFolderName.length());
resultPath.prepend(QDir::currentPath() + "/" + sharedDataFolderName + "/" + streamingVersionData->getViewName());
}
return resultPath;
}
QString Tools::createVersionHashFilepath(QString fileName)
{
return staticDataFolderName + "/" + fileName + "Hash.xml";
}
QString Tools::createUpdateFilePath(QString path)
{
//qDebug() << "Full path: " << path;
qint8 pos = path.indexOf(streamingAssetsFolderName);
QString localPath = path.remove(0,--pos);
//qDebug() << "Local path: " << localPath;
return localPath;
}
QString Tools::createFolderPath(QString path)
{
quint8 pos = path.lastIndexOf("\\");
QString folderPath = path.remove(pos,path.length() - pos);
return folderPath;
}
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;
}
bool Tools::checkNonStaticData(QString path)
{
if(path.contains(sharedDataFolderName)) return true;
return false;
}
bool Tools::loadXMLtoDOM(QString pathNameFile, QDomDocument *commonDOM)
{
QFile xmlInFile(pathNameFile);
if (! xmlInFile.open(QFile::ReadOnly | QFile::Text)) {
qDebug() << "loadXMLtoDOM: Couldn't read the file: " + pathNameFile;
return false;
}
commonDOM->setContent(xmlInFile.readAll());
xmlInFile.close();
return true;
}
bool Tools::saveDOMtoXML(QString pathNameFile, QDomDocument *commonDOM)
{
QFile xmlOutFile(pathNameFile);
if (!xmlOutFile.open(QFile::WriteOnly | QFile::Text))
{
qDebug() << "saveDOMtoXML: Failed to write a file: " + pathNameFile;
return false;
}
else
{
QTextStream outFile(&xmlOutFile);
commonDOM->save(outFile, 4);
xmlOutFile.close();
}
return true;
}

83
Server/Systems/tools.h Normal file
View File

@@ -0,0 +1,83 @@
#ifndef TOOLS_H
#define TOOLS_H
#include "logger.h"
#include <QString>
#include <QDebug>
#include <QTime>
#include <QDir>
#include <QDomDocument>
#include <Data/StreamingVersionData.h>
#define TCP_READ_TIMEOUT 5000
static const QString staticDataFolderName = "StaticData";
static const QString applicationFolderName = "Application";
static const QString sharedDataFolderName = "SharedData";
static const QString projectFolderName = "RRJLoader";
static const QString additionalFilesFolderName = "RRJ-95NEW-100";
static const QString rusScensFolderName = "RUS/Scens";
static const QString streamingAssetsFolderName = "StreamingAssets";
static const QString versionFolderName = "StreamingVersion";
static const QString tempFile = staticDataFolderName + "/save.xml";
static const QString version = staticDataFolderName + "/version.xml";
static const QString versionListFile = staticDataFolderName + "/versionList.xml";
static const QString hashFileName = staticDataFolderName + "/serverHash.xml";
static const QString buildHashName = staticDataFolderName + "/buildHash.xml";
static const QString buildDataPath = "/Application/" + projectFolderName + "/RRJ_Data/";
static const QString tasksAMMfileName = "/docs.xml"; //"/tasksAmm.xml";
static const QString tasksFIMfileName = "/tasksFIM.xml";
//static const QString clientHash = staticDataFolderName + "/clientHash.xml";
static const QString logFolderPath = "log";
static const QString configFolderName = "config";
static const QString settingsName = configFolderName + "/settings.xml";
static const QString baseNameVersion = "base";//может вынести комманды куда нибудь?
static const QString commandTryBaseDelete = "BASEDELETETRY";
static const QString commandTryBaseChange = "TRYBASECHANGE";
static const QString commandTryActiveDelete = "TRYACTIVEDELETE";
static const QString commandTryCopyWithSameNames = "SAMENAMES";
static const QString commandGetServerDataList = "GETSERVERDATALIST";
static const QString commandCheckVersionList = "CHECKVERSIONLIST";
static const QString commandReadyClient = "READY";
static const QString commandDisableClient = "DISABLE";
static const QString commandStartTimerClient = "UNITYSTARTTIMER";
static const QString commandDuplicateVerName = "DUPLICATEVERNAME";
static const QString commandHashCompleteClient = "HASHSENDCOMPLETE";
static const QString commandCanChangeVersion = "CANCHANGE";
static const QString commandChangable = "CHANGEABLE";
static const QString commandUnchangable = "UNCHANGEABLE";
static const QString commandUpdateFilesClient = "update";
static const QString commandGetTasks = "GETTASKS";
static const QString commandeGetOfflineMessages = "GETOFFLINEMESSAGE";
//static quint64 fileBlockSize = 1460;
static quint64 sendFileBlockSize = 256000;
static quint64 readFileBlockSize = 65535;
//1025*250
class Tools {
public:
static void printTime();
static QString getTime();
static QString createLocalPath(QString path);
static QString createRootPath(QString path);
static QString createUpdateFilePath(QString path);
static QString createFolderPath(QString path);
static QString createSharedPath(QString path);
static QString createRealPath(QString path,StreamingVersionData* currentVersionData);
static QString createStreamingToRealPath(QString path, StreamingVersionData *streamingVersionData);
static QString createVersionHashFilepath(QString fileName);
static QString createFullPath(QString path);
static bool checkNonStaticData(QString path);
static bool loadXMLtoDOM(QString pathNameFile, QDomDocument* commonDOM);
static bool saveDOMtoXML(QString pathNameFile, QDomDocument* commonDOM);
};
#endif // TOOLS_H

View File

@@ -0,0 +1,601 @@
#include "updatecontroller.h"
UpdateController::UpdateController(QObject *parent) :
QObject(parent),
commonClientHandler(nullptr)
{
buildPath = QDir::currentPath() + "/" + applicationFolderName;
sharedDataPath = QDir::currentPath() + "/" + sharedDataFolderName;
Logger::instance().log(buildPath);
qDebug() << hashFileName;
}
void UpdateController::initialize(CommonClientHandler *commonClientHandler,DataParser *dataParser,AssetsManager *assetManager)
{
this->commonClientHandler = commonClientHandler;
this->dataParser = dataParser;
this->assetManager = assetManager;
hashCalculator = new FastHashCalculator;
if (!QDir(staticDataFolderName).exists())
{
QDir().mkdir(staticDataFolderName);
}
sizeToSend = 0;
assetManager->initialize(this,dataParser);
if (!checkRequiredFolder())
{
emit sigErrorRequired(100);
return;
}
calculateFullHash();
currentStreamingPath = assetManager->getLastVersion(); //TODO: сохрнаять предыдущую версию и загружать ее при включении
setUpCurrentServerHash();
mutex = new QMutex;
qDebug() << "UpdateController init thread ID " << QThread::currentThreadId();
emit sigInitializeFinished();
}
void UpdateController::changeAssetVersion(QString versionName)
{
commonClientHandler->slot_sendPacketToAllClients(PacketType::BUSY);
qDebug() << "UpdateController thread ID " << QThread::currentThreadId();
currentStreamingPath = assetManager->setVersion(versionName);
setUpCurrentServerHash();
emit sigUpdateDocs();
commonClientHandler->slot_sendPacketToAllClients(PacketType::HASH_READY);
commonClientHandler->sendCurrentVersionToAllClient();
commonClientHandler->slot_sendPacketToAllClients(PacketType::FREE);
}
void UpdateController::createCopyVersion(QString versionName,QString newVersionName,QString author)
{
commonClientHandler->slot_sendPacketToAllClients(PacketType::BUSY);
assetManager->createCopyVersion(versionName,newVersionName,author);
commonClientHandler->slot_sendPacketToAllClients(PacketType::FREE);
}
void UpdateController::deleteAssetVersion(QString versionName)
{
commonClientHandler->slot_sendPacketToAllClients(PacketType::BUSY);
assetManager->deleteVersion(versionName);
commonClientHandler->slot_sendPacketToAllClients(PacketType::FREE);
}
void UpdateController::compareFiles(ClientHandler* handler, QByteArray array)
{
mutex->lock();
serverDataList.clear();
serverDataList = *loadHash(hashFileName);
clientDataList.clear();
xmlFileDataParse(array);
checkNeedUpdate(handler);
mutex->unlock();
}
void UpdateController::showHash()
{
for(FileData& str : serverDataList){
Logger::instance().log(str.hash);
}
}
void UpdateController::calculateFullHash()
{
Logger::instance().log("Calculate hash...");
QElapsedTimer timer;
timer.start();
qDebug() << "Start calculate... ";
commonClientHandler->slot_sendPacketToAllClients(PacketType::BUSY);
//auto *list = calculateHash(buildPath);
hashCalculator->calculateHashes(buildPath);
auto* list = hashCalculator->getHashList();
qDebug() << "Hash count: " << list->count();
saveHash(buildHashName,list);
calculateSharedHash();
Logger::instance().log("Calculate hash complete");
qDebug() << "Calculate time " << timer.elapsed();
commonClientHandler->slot_sendPacketToAllClients(PacketType::FREE);
}
void UpdateController::calculateFullHashWithSetup()
{
commonClientHandler->slot_sendPacketToAllClients(PacketType::RECALCULATE_HASH);
calculateCurrentSharedHash();
setUpCurrentServerHash();
commonClientHandler->slot_sendPacketToAllClients(PacketType::HASH_READY);
}
void UpdateController::saveHash(QString fileName,QList<FileData> *fileList)
{
QFile hashFile(fileName);
hashFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
QXmlStreamWriter xmlWriter(&hashFile);
QListIterator<FileData> fileDataIterator(*fileList);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("FileDataList");
while (fileDataIterator.hasNext())
{
FileData data = fileDataIterator.next();
xmlWriter.writeStartElement("FileData");
xmlWriter.writeAttribute("Path",data.path);
xmlWriter.writeAttribute("Hash",data.hash);
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();
hashFile.close();
}
QList<FileData>* UpdateController::loadHash(QString filename)
{
QList<FileData> *files = new QList<FileData>();
QFile hashFile(filename);
QByteArray array;
if(hashFile.open(QIODevice::ReadOnly)){
array = hashFile.readAll();
hashFile.close();
}
QXmlStreamReader xmlReader(array);
while (!xmlReader.atEnd())
{
if(xmlReader.isStartElement())
{
if(xmlReader.name().toUtf8() == "FileData")
{
FileData data;
foreach(const QXmlStreamAttribute &attr,xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
if(name == "Path")
data.path = value;
else if(name == "Hash")
data.hash = value;
}
files->append(data);
}
}
xmlReader.readNextStartElement();
}
Logger::instance().log("Hash load from file ");
return files;
}
void UpdateController::calculateSize()
{
QDirIterator iterator(buildPath);
quint64 total = 0;
while(iterator.hasNext()){
if(iterator.fileInfo().isFile()){
total += iterator.fileInfo().size();
}
iterator.next();
}
Logger::instance().log("Full size: ");
Logger::instance().log(QString::number(total));
}
QString UpdateController::getCommands()
{
QString commandsText;
commandsText += "check - check version ";
commandsText += "update - update files ";
return commandsText;
}
void UpdateController::setUpCurrentServerHash()
{
QList<FileData> *fileList = new QList<FileData>;
fileList->append(*loadHash(buildHashName));
FileData *streamingFolder = new FileData;
streamingFolder->hash = "FOLDER";
streamingFolder->path = buildDataPath + streamingAssetsFolderName;
fileList->append(*streamingFolder);
QString streamingHashFileName = Tools::createVersionHashFilepath(assetManager->getCurrentVersionData()->getViewName());
fileList->append(*loadHash(streamingHashFileName));
assetManager->prepareLocalPathList(fileList);
saveHash(hashFileName,fileList);
}
void UpdateController::setDataInfo(DataInfo *value)
{
dataInfo = value;
}
QString UpdateController::getCurrentStreamingPath() const
{
return currentStreamingPath;
}
QList<FileData> UpdateController::prepareRealPathList(QList<FileData> fileData)
{
return *assetManager->prepareRealPathList(&fileData);
}
void UpdateController::setLocalFileData(QList<FileData> dataList)
{
serverDataList.append(dataList);
}
bool UpdateController::checkNeedUpdate(ClientHandler *handler)
{
QList<FileData> *forSend = new QList<FileData>;
QList<FileData> *forDelete = new QList<FileData>;
Client *client = handler->getClient();
sizeToSend = 0;
bool needUpdate = false;
for (auto &item:clientDataList) //проверка на недостающие файлы по адресам
{
if(item.path.contains("Temp")) continue;
if(item.path.contains("docs.xml")) continue;
if (!serverDataList.contains(item))
{
forDelete->append(item);
}
}
for (auto &item:serverDataList)
{
if(item.path.contains("Temp")) continue;
if(item.path.contains("docs.xml")) continue;
if (!clientDataList.contains(item))
{
forSend->append(item);
}
}
if(forSend->length() > 0) //формирование сообщения об обновлении
{
QString log;
log.append(" Client: " + client->getLogin());
log.append(" Need updates: ");
log.append(QString::number(forSend->length()));
log.append(" objects");
client->setFileSendList(*forSend);
Logger::instance().log(log);
needUpdate = true;
}
else
{
QString log;
log.append(" Client: " + client->getLogin());
log.append(" no update required");
Logger::instance().log(log);
}
if(forDelete->length() > 0){
QString log;
log.append(" Client: " + client->getLogin());
log.append(" Need delete: ");
log.append(QString::number(forDelete->length()));
log.append(" objects");
client->setFileDeleteList(*forDelete);
Logger::instance().log(log);
needUpdate = true;
}
else
{
QString log;
log.append(" Client: " + client->getLogin());
log.append(" no delete required");
Logger::instance().log(log);
//handler->sendMessageBlock(log);
}
CalculateSizeToSend(*forSend);
handler->sendNeedUpdate(needUpdate,sizeToSend,forSend->length(),forDelete->length());
return needUpdate;
}
QList<FileData>* UpdateController::calculateHash(QString path)
{
serverDataList.clear();
if(!QDir(path).exists()){
QDir().mkdir(path);
}
QString hashString;
QStringList filter;
filter << "*";
QList<FileData> *files = new QList<FileData>;
QDirIterator dirIterator(path,filter, QDir::AllEntries, QDirIterator::Subdirectories);
while (dirIterator.hasNext())
{
QFileInfo fileInfo(dirIterator.next());
FileData currentFile;
if(fileInfo.isDir() && !fileInfo.fileName().startsWith(".") && fileInfo.fileName() != projectFolderName)
{
currentFile.path = Tools::createLocalPath(fileInfo.absoluteFilePath());
currentFile.hash = "FOLDER";
if(!files->contains(currentFile))
{
files->push_back(currentFile);
}
}
}
QDirIterator fileIterator(path,filter,QDir::Files | QDir::NoDotAndDotDot,QDirIterator::Subdirectories);
while (fileIterator.hasNext())
{
fileIterator.next();
QFileInfo fileInfo = fileIterator.fileInfo();
FileData currentFile;
QFile file(fileInfo.absoluteFilePath());
quint64 fileSize = file.size(); //буффер для хэширования крупных файлов
const quint64 bufferSize = 1024;
if(fileInfo.isHidden()) continue;
if(fileInfo.isFile() && file.open(QIODevice::ReadOnly) && !fileInfo.fileName().contains(".meta"))
{
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);
file.close();
}
}
serverDataList.append(*files);
return files;
}
QString UpdateController::getPathAdditionalFile(QString name)
{
QString path = Tools::createSharedPath("/" + assetManager->getCurrentVersionData()->getViewName() + "/" + additionalFilesFolderName + name);
return path;
}
QString UpdateController::getPathScensFile(QString name)
{
QString path = Tools::createSharedPath("/" + assetManager->getCurrentVersionData()->getViewName() + "/" + rusScensFolderName + name);
return path;
}
QByteArray UpdateController::getLocalHash()
{
QFile hashFile(hashFileName);
QByteArray array;
if(hashFile.open(QIODevice::ReadOnly)){
array = hashFile.readAll();
hashFile.close();
}
return array;
}
QString UpdateController::getCurrentVersionName()
{
return assetManager->getCurrentVersionData()->getViewName();
}
void UpdateController::CalculateSizeToSend(QList<FileData> diffList)
{
QListIterator<FileData> serverDiffIterator(diffList);
while (serverDiffIterator.hasNext())
{
QString path;
FileData pathForUpdate = serverDiffIterator.next();
if(pathForUpdate.path.contains(streamingAssetsFolderName))
{
path = Tools::createStreamingToRealPath(pathForUpdate.path,assetManager->getCurrentVersionData());
}
else
{
path = Tools::createRootPath(pathForUpdate.path);
}
QFile file(path);
sizeToSend += file.size();
}
}
void UpdateController::calculateSharedHash()
{
QDir sharedDir(sharedDataPath);
if(!QDir(sharedDataPath).exists())
{
QDir().mkdir(sharedDataPath);
}
QDirIterator dirIterator(sharedDir);
QList<FileData> *fileList = new QList<FileData>;
QList<StreamingVersionData*> *versionList = new QList<StreamingVersionData*>;
while (dirIterator.hasNext())
{
fileList->clear();
dirIterator.next();
QFileInfo fileInfo = dirIterator.fileInfo();
if (fileInfo.fileName() == "." || fileInfo.fileName() == "..")
continue;
QString fileName = Tools::createVersionHashFilepath(fileInfo.fileName());
hashCalculator->calculateHashes(fileInfo.filePath());
fileList = hashCalculator->getHashList();
//fileList = calculateHash(fileInfo.absoluteFilePath());
qDebug() << "Hash count: " << fileList->count();
saveHash(fileName,fileList);
StreamingVersionData *version = new StreamingVersionData(
fileInfo.absoluteFilePath(),fileInfo.fileName(),
fileInfo.birthTime(),fileInfo.size());
versionList->append(version);
}
assetManager->createFirstVersionListXML(*versionList);
}
void UpdateController::calculateCurrentSharedHash()
{
QList<FileData> *fileList = new QList<FileData>;
QString fileName = Tools::createVersionHashFilepath(assetManager->getCurrentVersionData()->getViewName());
hashCalculator->calculateHashes(currentStreamingPath);
fileList = hashCalculator->getHashList();
//fileList = calculateHash(currentStreamingPath);
qDebug() << "Hash count: " << fileList->count();
saveHash(fileName,fileList);
}
void UpdateController::sendNewVersionList()
{
commonClientHandler->sendNewVersionListToAllClient();
}
bool UpdateController::checkDuplicate(QString versionName)
{
return assetManager->findDuplicate(versionName);
}
void UpdateController::xmlFileDataParse(QByteArray array)
{
QXmlStreamReader xmlReader(array);
xmlReader.readNext();
//Крутимся в цикле до тех пор, пока не достигнем конца документа
while(!xmlReader.atEnd())
{
//Проверяем, является ли элемент началом тега
if(xmlReader.isStartElement())
{
if(xmlReader.name() == "FileData")
{
FileData data;
foreach(const QXmlStreamAttribute &attr,xmlReader.attributes())
{
QString name = attr.name().toString();
QString value = attr.value().toString();
if(name == "Path")
data.path = value;
else if(name == "Hash")
data.hash = value;
}
clientDataList.append(data);
}
}
xmlReader.readNext();
}
}
StreamingVersionData* UpdateController::getCurrentVersion()
{
return assetManager->getCurrentVersionData();
}
void UpdateController::printFileList(QList<FileData> fileData)
{
QListIterator<FileData> iterator(fileData);
while (iterator.hasNext())
{
auto next = iterator.next();
Logger::instance().log(next.path);
}
}
QList<FileData> UpdateController::getClientDataList() const
{
return clientDataList;
}
DataInfo *UpdateController::getCurrentDataInfo()
{
return dataInfo;
}
void UpdateController::clearCurrentDataInfo()
{
delete dataInfo;
}
bool UpdateController::checkRequiredFolder()
{
bool required = true;
QDir buildDir(buildPath + "/" + projectFolderName);
if (!buildDir.exists()) required = false;
QDir baseSharedDir(sharedDataPath + "/" + baseNameVersion);
if (!baseSharedDir.exists()) required = false;
return required;
}
UpdateController::~UpdateController()
{
}

View File

@@ -0,0 +1,103 @@
#ifndef UPDATECONTROLLER_H
#define UPDATECONTROLLER_H
#include <QString>
#include <QObject>
#include <QCryptographicHash>
#include <QDirIterator>
#include <QDebug>
#include <QDataStream>
#include <QMutex>
#include <QApplication>
#include <QMessageBox>
#include <Systems/Parsers/dataparser.h>
#include <Data/typesDataServerClient.h>
#include <Data/StreamingVersionData.h>
#include "fasthashcalculator.h"
class TCPServer;
class SendSystem;
class DataParser;
class ClientHandler;
class AssetsManager;
class ServerLMSWidget;
class CommonClientHandler;
class Logger;
class UpdateController : public QObject
{
Q_OBJECT
public:
explicit UpdateController(QObject *parent = 0);
void initialize(CommonClientHandler* commonClientHandler,DataParser *dataParser,AssetsManager *assetManager);
void compareFiles(ClientHandler* handler, QByteArray array);
void showHash();
void calculateFullHash();
void calculateFullHashWithSetup();
void calculateSharedHash();
void sendNewVersionList();
void setCurrentStreamingPath(QString path);
bool checkDuplicate(QString versionName);
QList<FileData>* calculateHash(QString path);
QByteArray getLocalHash();
QString getCurrentVersionName();
QList<FileData> getClientDataList() const;
QString getCurrentStreamingPath() const;
QList<FileData> prepareRealPathList(QList<FileData> fileData);
~UpdateController();
DataInfo *getCurrentDataInfo();
void clearCurrentDataInfo();
void xmlFileDataParse(QByteArray array);
QString getPathAdditionalFile(QString name);
QString getPathScensFile(QString name);
StreamingVersionData *getCurrentVersion();
void setDataInfo(DataInfo *value);
public slots:
void changeAssetVersion(QString versionName);
void createCopyVersion(QString versionName,QString newVersionName,QString author);
void deleteAssetVersion(QString versionName);
void setUpCurrentServerHash();
signals:
void sigErrorRequired(int code);
void sigUpdateDocs();
void sigInitializeFinished();
private:
QList<FileData> clientDataList;
QList<FileData> serverDataList;
DataInfo *dataInfo;
QString buildPath;
QString currentStreamingPath;
QString sharedDataPath;
CommonClientHandler *commonClientHandler;
FastHashCalculator *hashCalculator;
DataParser *dataParser;
AssetsManager *assetManager;
quint64 sizeToSend;
QMutex *mutex;
QString getCommands();
void printFileList(QList<FileData> fileData);
bool checkNeedUpdate(ClientHandler* handler);
void setLocalFileData(QList<FileData> dataList);
void calculateSize();
void saveHash(QString fileName,QList<FileData> *fileList);
QList<FileData>* loadHash(QString fileName);
void CalculateSizeToSend(QList<FileData> diffList);
bool checkRequiredFolder();
void calculateCurrentSharedHash();
};
#endif // UPDATECONTROLLER_H