diff --git a/DOCS/.obsidian/workspace.json b/DOCS/.obsidian/workspace.json index a09a908..c1eaf4e 100644 --- a/DOCS/.obsidian/workspace.json +++ b/DOCS/.obsidian/workspace.json @@ -11,15 +11,58 @@ "id": "24c44b1390af655a", "type": "leaf", "state": { - "type": "excalidraw", + "type": "kanban", "state": { - "file": "Алексей/AssetManagerScheme.md" + "file": "Алексей/Board.md", + "kanbanViewState": { + "kanban-plugin": "board", + "list-collapse": [ + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + } }, - "icon": "excalidraw-icon", - "title": "AssetManagerScheme" + "icon": "lucide-trello", + "title": "Board" + } + }, + { + "id": "1aa07d1707bb3761", + "type": "leaf", + "state": { + "type": "markdown", + "state": { + "file": "Что умеем отправлять Server - Client QT.md", + "mode": "source", + "source": false + }, + "icon": "lucide-file", + "title": "Что умеем отправлять Server - Client QT" + } + }, + { + "id": "77886c7575d9bc97", + "type": "leaf", + "state": { + "type": "markdown", + "state": { + "file": "Что умеем отправлять Server - Client QT.md", + "mode": "source", + "source": false + }, + "icon": "lucide-file", + "title": "Что умеем отправлять Server - Client QT" } } - ] + ], + "currentTab": 2 } ], "direction": "vertical" @@ -162,9 +205,15 @@ "obsidian-kanban:Создать новую доску": false } }, - "active": "24c44b1390af655a", + "active": "77886c7575d9bc97", "lastOpenFiles": [ "Алексей/Board.md", + "Алексей/Чек лист по переносу.md", + "Алексей/ТЕСТ-КЕЙСЫ.md", + "Алексей/Рефакторинг.md", + "Без названия.md", + "Как умеем принимать на Server.md", + "Что умеем отправлять Server - Client QT.md", "Алексей/AssetManagerScheme.md", "Desk.md", "CLIENT SERVER.canvas", @@ -172,7 +221,6 @@ "Андрей/ВАЖНАЯ ЗАМЕТКА.md", "Образец отправки сообщения с маркером.md", "Порядок сборки Unity билда под сервер.md", - "Алексей/ТЕСТ-КЕЙСЫ.md", "Алексей", "AssetManagerScheme.md", "SERVER/UpdateController.md", diff --git a/DOCS/Алексей/Board.md b/DOCS/Алексей/Board.md index 6038471..b7a24e8 100644 --- a/DOCS/Алексей/Board.md +++ b/DOCS/Алексей/Board.md @@ -6,6 +6,8 @@ kanban-plugin: board ## backLog +- [ ] выписать все варианты взаимодействия между всеми клиентами и сервером +- [ ] sendSystem::sendXmlAnswer новый вариант отпарвки XML пакетов ## bugs @@ -29,6 +31,7 @@ kanban-plugin: board - [ ] Прибраться в Server - [ ] рефакторинг +- [ ] добавить генерацию пустых файлов, если shared не найден ## NOW diff --git a/DOCS/Алексей/Рефакторинг.md b/DOCS/Алексей/Рефакторинг.md new file mode 100644 index 0000000..bef373d --- /dev/null +++ b/DOCS/Алексей/Рефакторинг.md @@ -0,0 +1,2 @@ +1. DataParser разделить на подклассы, придумать как скомпоновать. Возможно разделить на формирование ответов и парсинг входящих данных. +2. \ No newline at end of file diff --git a/DOCS/Алексей/Чек лист по переносу.md b/DOCS/Алексей/Чек лист по переносу.md new file mode 100644 index 0000000..49c92db --- /dev/null +++ b/DOCS/Алексей/Чек лист по переносу.md @@ -0,0 +1,11 @@ +- [x] AssetManager +- [x] DataParser +- [x] Logger +- [x] ProcessingSystem +- [x] RecognizeSystem +- [x] SendSystem +- [x] Tools +- [x] UpdateController +- [x] ClientHandler +- [x] MultiThreadServer +- [x] ServerLMSWidget \ No newline at end of file diff --git a/DOCS/Как умеем принимать на Server.md b/DOCS/Как умеем принимать на Server.md new file mode 100644 index 0000000..33c4ca5 --- /dev/null +++ b/DOCS/Как умеем принимать на Server.md @@ -0,0 +1 @@ +- XML файлы с поиском по тегу (DataParser::xmlParser) \ No newline at end of file diff --git a/DOCS/Что умеем отправлять Server - Client QT.md b/DOCS/Что умеем отправлять Server - Client QT.md new file mode 100644 index 0000000..e69de29 diff --git a/ServerLMS/ServerLMS/CMakeLists.txt b/ServerLMS/ServerLMS/CMakeLists.txt index 02c7e74..492cb4d 100644 --- a/ServerLMS/ServerLMS/CMakeLists.txt +++ b/ServerLMS/ServerLMS/CMakeLists.txt @@ -33,12 +33,16 @@ add_library(ServerLMS SHARED serverlmswidget.cpp serverlmswidget.h serverlmswidget.ui - typesDataServerClient.h - Client.h clienthandler.cpp clienthandler.h multithreadserver.cpp multithreadserver.h + Data/typesDataServerClient.h + Data/Client.h + Data/PacketType.h + Data/StreamingVersionData.h + Systems/assetsmanager.cpp + Systems/assetsmanager.h Systems/recognizesystem.cpp Systems/recognizesystem.h Systems/updatecontroller.cpp diff --git a/ServerLMS/ServerLMS/Client.h b/ServerLMS/ServerLMS/Data/Client.h similarity index 87% rename from ServerLMS/ServerLMS/Client.h rename to ServerLMS/ServerLMS/Data/Client.h index 35771c9..32246cb 100644 --- a/ServerLMS/ServerLMS/Client.h +++ b/ServerLMS/ServerLMS/Data/Client.h @@ -50,13 +50,17 @@ public: { return ready; } + void setReady(bool ready) { this->ready = ready; } - void setUnity(bool flag){ + + void setUnity(bool flag) + { isUnity = flag; } + bool getIsUnity() { return isUnity; @@ -75,10 +79,22 @@ public: { isUnity = !isUnity; } - bool operator == (Client* right){ + + bool operator == (Client* right) + { return this->address == right->address; } + bool getIsLoggedIn() + { + return isLoggedIn; + } + + void setIsLoggedIn(bool value) + { + isLoggedIn = value; + } + private: QString name; @@ -88,6 +104,7 @@ private: QString login; bool ready; + bool isLoggedIn; bool isUnity = false; TypeClientAutorization TypeClient; diff --git a/ServerLMS/ServerLMS/Data/PacketType.h b/ServerLMS/ServerLMS/Data/PacketType.h new file mode 100644 index 0000000..2b54672 --- /dev/null +++ b/ServerLMS/ServerLMS/Data/PacketType.h @@ -0,0 +1,39 @@ +#ifndef PACKETTYPE_H +#define PACKETTYPE_H + +enum PacketType +{ + TYPE_NONE = 0, + TYPE_UNITY = 1, + TYPE_FILE = 2, + TYPE_COMMAND =3, + TYPE_FOLDER = 4, + TYPE_DELETE = 5, + TYPE_FINISH = 6, + TYPE_NEEDUPDATE = 7, + TYPE_XMLANSWER = 8, + TYPE_QT = 9, + TYPE_DISABLE = 11, + TYPE_FILESIZE = 20, + + TYPE_XMLANSWER_MESSAGE_FOR_GUI = 90, + + //xml-ответы на запросы к БД + TYPE_XMLANSWER_QUERY_DB__LIST_INSTRUCTORS = 100, + TYPE_XMLANSWER_QUERY_DB__LIST_GROUPS = 101, + TYPE_XMLANSWER_QUERY_DB__LIST_TRAINEES = 102, + TYPE_XMLANSWER_QUERY_DB__LIST_COMPUTERS = 103, + TYPE_XMLANSWER_QUERY_DB__LIST_CLASSROOMS = 104, + TYPE_XMLANSWER_QUERY_DB__LIST_TASKS = 105, + + //ответы по обновлениям + HASH_READY = 150, + CHANGE_DATA_VERSION = 151, + COPY_VERSION = 152, + DELETE_DATA_VERSION = 153, + BUSY = 154, + FREE = 155 +}; + + +#endif // PACKETTYPE_H diff --git a/ServerLMS/ServerLMS/Data/StreamingVersionData.h b/ServerLMS/ServerLMS/Data/StreamingVersionData.h new file mode 100644 index 0000000..3746bd7 --- /dev/null +++ b/ServerLMS/ServerLMS/Data/StreamingVersionData.h @@ -0,0 +1,46 @@ +#ifndef STREAMINGVERSIONDATA_H +#define STREAMINGVERSIONDATA_H + +#include +#include + +class StreamingVersionData +{ +public: + StreamingVersionData(QString absoltePath,QString viewName,QDateTime data,qint32 size) + { + this->absolutePath = absoltePath; + this->viewName = viewName; + this->createData = data; + this->size = size; + } + ~StreamingVersionData(); + + QString getAbsolutPath() const + { + return absolutePath; + } + + QString getViewName() const + { + return viewName; + } + + QDateTime getCreateData() const + { + return createData; + } + + qint32 getSize() const + { + return size; + } + +private: + QString absolutePath; + QString viewName; + QDateTime createData; + qint32 size; +}; + +#endif // STREAMINGVERSIONDATA_H diff --git a/ServerLMS/ServerLMS/typesDataServerClient.h b/ServerLMS/ServerLMS/Data/typesDataServerClient.h similarity index 93% rename from ServerLMS/ServerLMS/typesDataServerClient.h rename to ServerLMS/ServerLMS/Data/typesDataServerClient.h index 5df49a4..32a19ab 100644 --- a/ServerLMS/ServerLMS/typesDataServerClient.h +++ b/ServerLMS/ServerLMS/Data/typesDataServerClient.h @@ -22,6 +22,11 @@ struct FileData return false; } + bool operator<(const FileData& data2) const + { + return this->hash == "FOLDER" && data2.hash !="FOLDER"; + } + }; struct SAttribute diff --git a/ServerLMS/ServerLMS/Systems/assetsmanager.cpp b/ServerLMS/ServerLMS/Systems/assetsmanager.cpp new file mode 100644 index 0000000..d81e9ce --- /dev/null +++ b/ServerLMS/ServerLMS/Systems/assetsmanager.cpp @@ -0,0 +1,220 @@ +#include "assetsmanager.h" + +AssetsManager::AssetsManager(QObject *parent) : QObject(parent) +{ + +} + +void AssetsManager::initialize(UpdateController* updateContoller,DataParser *dataParser) +{ + this->updateController = updateContoller; + connect(this,&AssetsManager::sigSaveVersion,dataParser,&DataParser::saveVersionToFile); + datas = new QList; +} + +void AssetsManager::setVersionList(QList *streamingVersion) +{ + datas->clear(); + datas = streamingVersion; +} + +bool AssetsManager::findDuplicate(QString name) +{ + QListIterator iterator(*datas); + + while (iterator.hasNext()) + { + if (iterator.next()->getViewName() == name) return true; + } + + return false; +} + +QString AssetsManager::setVersion(QString versionName) +{ + QListIterator iterator(*datas); + + while (iterator.hasNext()) + { + StreamingVersionData *version = iterator.next(); + + if (version->getViewName() == versionName) + { + currentVersionData = version; + emit sigSaveVersion(currentVersionData); + + return version->getAbsolutPath(); + } + } + + return "none"; +} + +QList *AssetsManager::prepareLocalPathList(QList *fileData) +{ + QList *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 *AssetsManager::prepareRealPathList(QList *fileData) +{ + QList *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) +{ + qDebug() << "assetManager thread ID " << QThread::currentThreadId(); + QListIterator iterator(*datas); + StreamingVersionData* data; + + while (iterator.hasNext()) + { + StreamingVersionData *version = iterator.next(); + + if (version->getViewName() == versionName) + { + data = version; + } + } + + 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 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); + } +} + +AssetsManager::~AssetsManager() +{ + +} + +StreamingVersionData *AssetsManager::getCurrentVersionData() const +{ + return currentVersionData; +} + diff --git a/ServerLMS/ServerLMS/Systems/assetsmanager.h b/ServerLMS/ServerLMS/Systems/assetsmanager.h new file mode 100644 index 0000000..559a0f7 --- /dev/null +++ b/ServerLMS/ServerLMS/Systems/assetsmanager.h @@ -0,0 +1,41 @@ +#ifndef ASSETSMANAGER_H +#define ASSETSMANAGER_H + +#include +#include +#include + + +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); + void deleteVersion(QString version); + void setVersionList(QList *streamingVersion); + bool findDuplicate(QString name); + QString setVersion(QString versionName); + + QList *prepareLocalPathList(QList*fileData); + QList *prepareRealPathList(QList *fileData); + QList *getRealPathList(); + + ~AssetsManager(); + + StreamingVersionData *getCurrentVersionData() const; + +signals: + void sigSaveVersion(StreamingVersionData *versionData); + +private: + UpdateController *updateController; + QList *datas; + StreamingVersionData* currentVersionData; + + void copyAllRecurse(QString source, QString destination); +}; + +#endif // ASSETSMANAGER_H diff --git a/ServerLMS/ServerLMS/Systems/dataparser.cpp b/ServerLMS/ServerLMS/Systems/dataparser.cpp index b5eb646..c090aad 100644 --- a/ServerLMS/ServerLMS/Systems/dataparser.cpp +++ b/ServerLMS/ServerLMS/Systems/dataparser.cpp @@ -3,10 +3,11 @@ #include #include -DataParser::DataParser(ProcessingSystem *processingSystem,QObject *parent) : +DataParser::DataParser(AssetsManager *assetManager,ProcessingSystem *processingSystem,QObject *parent) : QObject(parent) { this->processingSystem = processingSystem; + this->assetsManager = assetManager; mutex = new QMutex; if (!QDir(staticDataFolderName).exists()){ @@ -285,7 +286,6 @@ void DataParser::xmlFileDataParse(QByteArray array) } } - QByteArray DataParser::xmlAnswer(QList listTag, QString elemUp1, QString elemUp2) { try { @@ -333,18 +333,7 @@ QByteArray DataParser::xmlAnswer(QList listTag, QString elemUp1, QByteArray array; - /* Открываем файл для Чтения*/ - QFile fileR(tempFile); - if (!fileR.open(QFile::ReadOnly | QFile::Text)) - { - QString str = "Не удалось открыть файл"; - qDebug() << "xmlAnswer: " << str; - } - else - { - array = fileR.readAll(); - fileR.close(); // Закрываем файл - } + array = readTempFile(); mutex->unlock(); return array; @@ -584,6 +573,102 @@ QByteArray DataParser::xmlAnswer_tasks(QStringList listTasks) return xmlAnswer(listTag, "TaskArray", "Tasks"); } +QByteArray DataParser::xmlAnswer_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; +} + +void DataParser::createVersionListXmlAnswer(QList version) +{ + QList listTag; + + foreach(StreamingVersionData* ver,version) + { + SAttribute attribute1 = {"Version", ver->getViewName()}; + SAttribute attribute2 = {"Created", ver->getCreateData().toString()}; + + QList listAttr = {attribute1, attribute2}; + SXmlAnswerTag tag = {"VersionData", listAttr}; + + listTag.append(tag); + } + + + QFile file(versionListFile); + 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(); +} + +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; +} + +void DataParser::saveVersionToFile(StreamingVersionData *streamingVersion) +{ + 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.writeEndElement(); + xmlWriter.writeEndDocument(); + + file.close(); +} + DataInfo *DataParser::getCurrentDataInfo() { return dataInfo; diff --git a/ServerLMS/ServerLMS/Systems/dataparser.h b/ServerLMS/ServerLMS/Systems/dataparser.h index c292ac6..1294594 100644 --- a/ServerLMS/ServerLMS/Systems/dataparser.h +++ b/ServerLMS/ServerLMS/Systems/dataparser.h @@ -1,27 +1,30 @@ #ifndef DATAPARSER_H #define DATAPARSER_H - #include "Systems/processingsystem.h" #include "Systems/tools.h" +#include "Systems/assetsmanager.h" #include "logger.h" #include "serverlmswidget.h" -#include "typesDataServerClient.h" #include #include #include #include +#include +#include + class ProcessingSystem; class ClientHandler; +class AssetsManager; class DataParser : public QObject { Q_OBJECT public: - DataParser(ProcessingSystem *processingSystem,QObject* parent = nullptr); + DataParser(AssetsManager *assetManager,ProcessingSystem *processingSystem,QObject* parent = nullptr); void xmlParser(ClientHandler *client, QByteArray array); void xmlFileDataParse(QByteArray array); @@ -42,6 +45,9 @@ public: QByteArray xmlAnswer_task(QString text); QByteArray xmlAnswer_notify(QString code); QByteArray xmlAnswer_tasks(QStringList listTasks); + + QByteArray xmlAnswer_currentVersion(); + void createVersionListXmlAnswer(QList version); DataInfo *getCurrentDataInfo(); void clearCurrentDataInfo(); ~DataParser(); @@ -52,11 +58,17 @@ public: signals: void sigLogMessage(QString log); +public slots: + void saveVersionToFile(StreamingVersionData *streamingVersion); + private: QMutex *mutex; QList *datas; ProcessingSystem *processingSystem; + AssetsManager *assetsManager; DataInfo *dataInfo; + + QByteArray readTempFile(); }; #endif // DATAPARSER_H diff --git a/ServerLMS/ServerLMS/Systems/processingsystem.cpp b/ServerLMS/ServerLMS/Systems/processingsystem.cpp index 7b5fbf7..6813cc9 100644 --- a/ServerLMS/ServerLMS/Systems/processingsystem.cpp +++ b/ServerLMS/ServerLMS/Systems/processingsystem.cpp @@ -12,6 +12,12 @@ void ProcessingSystem::initialize(DataParser *dataParser, ServerLMSWidget *serve { this->server = server; this->dataParser = dataParser; + + connect(this,&ProcessingSystem::sigAuthChanged,server, &ServerLMSWidget::slot_AuthChanged,Qt::AutoConnection); + connect(this,&ProcessingSystem::sigUpdateListClients,server, &ServerLMSWidget::slotUpdateListClients,Qt::AutoConnection); + connect(this,&ProcessingSystem::sigLogMessage,server->getLogger(),&Logger::addTextToLogger,Qt::QueuedConnection); + connect(this,&ProcessingSystem::signal_msgToClientReady,server, &ServerLMSWidget::slot_msgToClientFromGUI); + connect(this,&ProcessingSystem::signal_msgFromClientReady,server, &ServerLMSWidget::slot_msgToGUIfromClient); } void ProcessingSystem::processingClientAutorization(ClientHandler *client, ClientAutorization clientAutorization) @@ -60,6 +66,7 @@ void ProcessingSystem::processingClientAutorization(ClientHandler *client, Clien arrayAnswer = dataParser->xmlAnswer_authorization(false, "", "", "", ""); } client->sendXmlAnswer(arrayAnswer); + client->sendVersion(); QString str = QString(arrayAnswer); //logger->addTextToLogger("To Client: " + str); @@ -238,7 +245,7 @@ void ProcessingSystem::processingFromClientMessage(ClientHandler *client, Client void ProcessingSystem::processingClientNotify(ClientHandler *client, ClientNotify clientNotify) { - if(clientNotify.Code == "READY") + if(clientNotify.Code == commandReadyClient) {//Клиент готов принять задания client->getClient()->setReady(true); //скорее всего функции будут внутри хэндлера @@ -256,15 +263,19 @@ void ProcessingSystem::processingClientNotify(ClientHandler *client, ClientNotif QString str = QString(arrayAnswer); emit sigLogMessage("To Client: " + str); } - else if(clientNotify.Code == "DISABLE") + else if(clientNotify.Code == commandDisableClient) { + qDebug() << "processing thread: " << QThread::currentThreadId(); client->sendDisable(); - //server->slotDisconnectClient(client->getClient()->getAddress(),client->getClient()->getPort()); } - else if(clientNotify.Code == "GETSERVERDATALIST") + else if(clientNotify.Code == commandGetServerDataList) { client->sendHash(); } + else if(clientNotify.Code == commandCheckVersionList) + { + client->sendVersionList(); + } } diff --git a/ServerLMS/ServerLMS/Systems/processingsystem.h b/ServerLMS/ServerLMS/Systems/processingsystem.h index 7264930..3a82519 100644 --- a/ServerLMS/ServerLMS/Systems/processingsystem.h +++ b/ServerLMS/ServerLMS/Systems/processingsystem.h @@ -1,8 +1,8 @@ #ifndef PROCESSINGSYSTEM_H #define PROCESSINGSYSTEM_H -#include "sendsystem.h" -#include "typesDataServerClient.h" +#include +#include #include #include @@ -22,7 +22,7 @@ class ProcessingSystem : public QObject public: explicit ProcessingSystem(ProviderDBLMS* providerDBLMS, QObject *parent = nullptr); - void initialize(DataParser* dataParser,ServerLMSWidget *server); + void initialize(DataParser* dataParser,ServerLMSWidget *server); //TODO: проверить необходимость зависимости на ServerLMS void processingClientAutorization(ClientHandler *client, ClientAutorization clientAutorization); void processingClientDeAutorization(ClientHandler *client, ClientDeAutorization clientDeAutorization); void processingClientQueryToDB(ClientHandler *client, ClientQueryToDB clientQueryToDB, int id = 0, void* data = nullptr); diff --git a/ServerLMS/ServerLMS/Systems/recognizesystem.cpp b/ServerLMS/ServerLMS/Systems/recognizesystem.cpp index 3dc77ff..21b9131 100644 --- a/ServerLMS/ServerLMS/Systems/recognizesystem.cpp +++ b/ServerLMS/ServerLMS/Systems/recognizesystem.cpp @@ -1,4 +1,3 @@ -#include "Client.h" #include "recognizesystem.h" RecognizeSystem::RecognizeSystem(QObject *parent): @@ -24,8 +23,13 @@ void RecognizeSystem::initialize(UpdateController *updateController,DataParser* this->sendSystem = sendSystem; socket = handler->getSocket(); - connect(this,&RecognizeSystem::sigCalculateHash,updateController,&UpdateController::calculateHash,Qt::DirectConnection); + connect(this,&RecognizeSystem::sigCalculateHash,updateController,&UpdateController::calculateFullHash,Qt::AutoConnection); + connect(this,&RecognizeSystem::sigCalculateHash,updateController,&UpdateController::setUpCurrentServerHash,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,&DataParser::xmlParser,Qt::DirectConnection); + qDebug() << "Recognize init thread ID " << QThread::currentThreadId(); } @@ -75,7 +79,7 @@ void RecognizeSystem::recognize() } - if (packetType == PacketType::TYPE_COMMAND) + if (packetType == PacketType::TYPE_COMMAND) //TODO: надо переделать под какой то нормальный тип, который уже существует { stream.startTransaction(); stream >> command; @@ -83,7 +87,7 @@ void RecognizeSystem::recognize() if (!stream.commitTransaction()) continue; } - if (command == "update") //запускает процесс оновления + if (command == commandUpdateFilesClient) //запускает процесс оновления { sendSystem->updateFiles(updateController->getFileSendList(), updateController->getClientDataList()); @@ -110,18 +114,16 @@ void RecognizeSystem::recognize() qDebug() << data; emit sigXmlParser(clientHandler,data); - //dataParser->xmlParser(clientHandler,data); packetType = PacketType::TYPE_NONE; continue; } if(packetType == PacketType::TYPE_FOLDER) //создание папок - { if(client->getIsUnity()) { filePath = socket->readAll(); - filePath = Tools::createRootScenario(filePath); + filePath = Tools::createSharedPath(filePath); } else { @@ -154,12 +156,7 @@ void RecognizeSystem::recognize() { DataInfo *currentFileData = dataParser->getCurrentDataInfo(); filePath = currentFileData->path; - - filePath = Tools::createLocalPath(filePath); - - filePath = Tools::createUpdateFilePath(filePath); - - filePath = Tools::createRootScenario(filePath); + filePath = Tools::createSharedPath(filePath); QFile file(filePath); @@ -315,6 +312,69 @@ void RecognizeSystem::recognize() packetType = PacketType::TYPE_NONE; } + 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]); + 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); + } + + } + packetType = PacketType::TYPE_NONE; } diff --git a/ServerLMS/ServerLMS/Systems/recognizesystem.h b/ServerLMS/ServerLMS/Systems/recognizesystem.h index 07b649a..8478139 100644 --- a/ServerLMS/ServerLMS/Systems/recognizesystem.h +++ b/ServerLMS/ServerLMS/Systems/recognizesystem.h @@ -1,16 +1,19 @@ #ifndef RECOGNIZESYSTEM_H #define RECOGNIZESYSTEM_H -#include "client.h" -#include "updatecontroller.h" - #include #include -#include "Systems/tools.h" -#include "Systems/dataparser.h" -#include "serverlmswidget.h" #include +#include +#include +#include + +#include +#include + +#include "serverlmswidget.h" + class UpdateController; class ServerLMSWidget; class ClientHandler; @@ -31,6 +34,9 @@ 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); private: UpdateController *updateController; diff --git a/ServerLMS/ServerLMS/Systems/sendsystem.cpp b/ServerLMS/ServerLMS/Systems/sendsystem.cpp index b1f8908..fec9774 100644 --- a/ServerLMS/ServerLMS/Systems/sendsystem.cpp +++ b/ServerLMS/ServerLMS/Systems/sendsystem.cpp @@ -11,9 +11,10 @@ void SendSystem::initialize(DataParser *dataParser,Logger *logger) this->dataParser = dataParser; this->logger = logger; - connect(this,&SendSystem::sigSendToLogger,logger,&Logger::addTextToLogger); - connect(this,&SendSystem::sigSendXMLmessage,dataParser,&DataParser::xmlAnswer_message,Qt::BlockingQueuedConnection); - connect(this,&SendSystem::sigSendNotify,dataParser,&DataParser::xmlAnswer_notify,Qt::BlockingQueuedConnection); + connect(this,&SendSystem::sigSendToLogger,logger,&Logger::addTextToLogger,Qt::AutoConnection); + connect(this,&SendSystem::sigSendXMLmessage,dataParser,&DataParser::xmlAnswer_message,Qt::AutoConnection); + connect(this,&SendSystem::sigSendNotify,dataParser,&DataParser::xmlAnswer_notify,Qt::DirectConnection); //потому что возвращает значение + connect(this,&SendSystem::sigSendVersion,dataParser,&DataParser::xmlAnswer_currentVersion,Qt::AutoConnection); qDebug() << "SendSystem thread: " << QThread::currentThreadId(); } @@ -41,7 +42,7 @@ void SendSystem::sendFileBlock(QString path) QDataStream stream(socket); stream.setVersion(QDataStream::Qt_DefaultCompiledVersion); - QFile file(Tools::createRootPath(path)); + QFile file(path); QFileInfo fileInfo(file); fileSize = fileInfo.size(); @@ -81,15 +82,10 @@ void SendSystem::sendFileBlock(QString path) socket->waitForReadyRead(100); } -void SendSystem::socketWrite(QByteArray array) +void SendSystem::sendVersion() { - socket->write(array); - socket->waitForBytesWritten(100); -} - -void SendSystem::socketClose() -{ - socket->close(); + QByteArray data = dataParser->xmlAnswer_currentVersion(); + sendXmlAnswer(data); } void SendSystem::sendFileBlockWithRename(QString path, QString newName) @@ -139,7 +135,7 @@ void SendSystem::sendFileBlockWithRename(QString path, QString newName) socket->waitForBytesWritten(); socket->waitForReadyRead(100); - sendNotify("HASHSENDCOMPLETE"); + sendNotify(commandHashCompleteClient); } void SendSystem::sendFolderBlock(QString path) @@ -162,19 +158,19 @@ void SendSystem::sendDeleteBlock(QString path) socket->waitForReadyRead(100); } -void SendSystem::sendHello() -{ - socket->write(SERVER_HELLO); -} - -void SendSystem::sendFinish() +void SendSystem::sendPacketType(PacketType packetType) { QDataStream stream(socket); stream.setVersion(QDataStream::Qt_DefaultCompiledVersion); - stream << PacketType::TYPE_FINISH; + stream << packetType; socket->waitForReadyRead(100); } +void SendSystem::sendHello() +{ + socket->write(SERVER_HELLO); +} + void SendSystem::sendNotify(QString notify) { qDebug() << "SendNotify thread: " << QThread::currentThreadId(); @@ -202,7 +198,7 @@ void SendSystem::sendXmlAnswer(QByteArray array, PacketType packetType) socket->waitForReadyRead(1000); } -void SendSystem::sendNeedUpdate(bool flag,quint64 size,quint64 fileCount) +void SendSystem::sendNeedUpdate(bool flag,quint64 size,quint64 fileCount,quint64 deleteCount) { QDataStream stream(socket); stream.setVersion(QDataStream::Qt_DefaultCompiledVersion); @@ -210,9 +206,20 @@ void SendSystem::sendNeedUpdate(bool flag,quint64 size,quint64 fileCount) stream << flag; stream << size; stream << fileCount; + stream << deleteCount; } -void SendSystem::updateFiles(QList fileSendList, QList clientDataList){ +void SendSystem::updateFiles(QList fileSendList, QList deleteList){ + + QListIterator clientIterator(deleteList); + + while(clientIterator.hasNext()) + { + FileData data = clientIterator.next(); + + sendDeleteBlock(data.path); + if(getIsSendStopped()) return; + } QListIterator serverIterator(fileSendList); @@ -234,21 +241,28 @@ void SendSystem::updateFiles(QList fileSendList, QList clien if(getIsSendStopped()) return; } - QListIterator clientIterator(clientDataList); - while(clientIterator.hasNext()){ - FileData data = clientIterator.next(); - - sendDeleteBlock(data.path); - if(getIsSendStopped()) return; - } emit sigLoadHash(); - sendFinish(); + sendPacketType(PacketType::TYPE_FINISH); } +void SendSystem::socketWrite(QByteArray array) +{ + socket->write(array); + socket->waitForBytesWritten(100); +} +void SendSystem::socketClose() +{ + socket->close(); +} + +bool SendSystem::socketFlush() //TODO: проверить использование +{ + return socket->flush(); +} void SendSystem::sendStop() { diff --git a/ServerLMS/ServerLMS/Systems/sendsystem.h b/ServerLMS/ServerLMS/Systems/sendsystem.h index 011b053..0f08878 100644 --- a/ServerLMS/ServerLMS/Systems/sendsystem.h +++ b/ServerLMS/ServerLMS/Systems/sendsystem.h @@ -1,13 +1,15 @@ #ifndef SENDSYSTEM_H #define SENDSYSTEM_H -#include "dataparser.h" -#include "Systems/Tools.h" -#include "Client.h" #include #include #include +#include +#include +#include +#include + class DataParser; class FileData; class SendSystem : public QObject @@ -24,13 +26,15 @@ public: void sendFileBlockWithRename(QString path,QString newName); void sendFolderBlock(QString path); void sendDeleteBlock(QString path); + void sendPacketType(PacketType packet); void sendHello(); - void sendFinish(); void sendNotify(QString notify); void sendStop(); void sendXmlAnswer(QByteArray array, PacketType packetType = PacketType::TYPE_XMLANSWER); - void sendNeedUpdate(bool flag,quint64 size,quint64 fileCount); - void updateFiles(QList fileSendList, QList clientDataList); + void sendNeedUpdate(bool flag,quint64 size,quint64 fileCount,quint64 deleteCount); + void updateFiles(QList fileSendList, QList deleteList); + bool socketFlush(); + bool getIsSendStopped() const; ~SendSystem(); @@ -39,11 +43,14 @@ public: public slots: void socketWrite(QByteArray array); void socketClose(); + void sendVersion(); + signals: void sigLoadHash(); void sigSendToLogger(QString message); QByteArray sigSendXMLmessage(QString message, QString login = ""); QByteArray sigSendNotify(QString message); + QByteArray sigSendVersion(); private: Client *client; diff --git a/ServerLMS/ServerLMS/Systems/tools.cpp b/ServerLMS/ServerLMS/Systems/tools.cpp index 436dc1b..3b55145 100644 --- a/ServerLMS/ServerLMS/Systems/tools.cpp +++ b/ServerLMS/ServerLMS/Systems/tools.cpp @@ -15,7 +15,6 @@ QString Tools::getTime() QString Tools::createLocalPath(QString path) { - //qDebug() << "Full path: " << path; qint8 pos = path.indexOf(applicationFolderName); QString localPath = path.remove(0,--pos); @@ -29,10 +28,43 @@ QString Tools::createRootPath(QString path) return QDir::currentPath() + path; } -QString Tools::createRootScenario(QString path){ - return QDir::currentPath() + scenarioRootPath + 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::createUpdateFilePath(QString path) { diff --git a/ServerLMS/ServerLMS/Systems/tools.h b/ServerLMS/ServerLMS/Systems/tools.h index 748ec54..4a8eb54 100644 --- a/ServerLMS/ServerLMS/Systems/tools.h +++ b/ServerLMS/ServerLMS/Systems/tools.h @@ -8,42 +8,33 @@ #include #include +#include + #define TCP_READ_TIMEOUT 5000 static QString staticDataFolderName = "StaticData"; static QString applicationFolderName = "Application"; +static QString sharedDataFolderName = "SharedData"; static QString streamingAssetsFolderName = "StreamingAssets"; static QString tempFile = staticDataFolderName + "/save.xml"; +static QString version = staticDataFolderName + "/version.xml"; +static QString versionListFile = staticDataFolderName + "/versionList.xml"; static QString hashFileName = staticDataFolderName + "/serverHash.xml"; -static QString scenarioRootPath = "\\Application\\RRJLoader\\RRJ_Data"; +static QString buildHashName = staticDataFolderName + "/buildHash.xml"; +static QString buildDataPath = "/Application/RRJLoader/RRJ_Data/"; -enum PacketType -{ - TYPE_NONE = 0, - TYPE_UNITY = 1, - TYPE_FILE = 2, - TYPE_COMMAND =3, - TYPE_FOLDER = 4, - TYPE_DELETE = 5, - TYPE_FINISH = 6, - TYPE_NEEDUPDATE = 7, - TYPE_XMLANSWER = 8, - TYPE_QT = 9, - TYPE_DISABLE = 11, - TYPE_FILESIZE = 20, +static QString baseNameVersion = "base";//может вынести комманды куда нибудь? - TYPE_XMLANSWER_MESSAGE_FOR_GUI = 90, - - //xml-ответы на запросы к БД - TYPE_XMLANSWER_QUERY_DB__LIST_INSTRUCTORS = 100, - TYPE_XMLANSWER_QUERY_DB__LIST_GROUPS = 101, - TYPE_XMLANSWER_QUERY_DB__LIST_TRAINEES = 102, - TYPE_XMLANSWER_QUERY_DB__LIST_COMPUTERS = 103, - TYPE_XMLANSWER_QUERY_DB__LIST_CLASSROOMS = 104, - TYPE_XMLANSWER_QUERY_DB__LIST_TASKS = 105 -}; - -Q_DECLARE_METATYPE(PacketType) +static QString commandTryBaseDelete = "BASEDELETETRY"; +static QString commandTryActiveDelete = "TRYACTIVEDELETE"; +static QString commandTryCopyWithSameNames = "SAMENAMES"; +static QString commandGetServerDataList = "GETSERVERDATALIST"; +static QString commandCheckVersionList = "CHECKVERSIONLIST"; +static QString commandReadyClient = "READY"; +static QString commandDisableClient = "DISABLE"; +static QString commandDuplicateVerName = "DUPLICATEVERNAME"; +static QString commandHashCompleteClient = "HASHSENDCOMPLETE"; +static QString commandUpdateFilesClient = "update"; class Tools { public: @@ -53,7 +44,9 @@ public: static QString createRootPath(QString path); static QString createUpdateFilePath(QString path); static QString createFolderPath(QString path); - static QString createRootScenario(QString path); + static QString createSharedPath(QString path); + static QString createRealPath(QString path,StreamingVersionData* currentVersionData); + static QString createStreamingToRealPath(QString path, StreamingVersionData *streamingVersionData); }; diff --git a/ServerLMS/ServerLMS/Systems/updatecontroller.cpp b/ServerLMS/ServerLMS/Systems/updatecontroller.cpp index 1c2eb0b..c9e5105 100644 --- a/ServerLMS/ServerLMS/Systems/updatecontroller.cpp +++ b/ServerLMS/ServerLMS/Systems/updatecontroller.cpp @@ -1,25 +1,54 @@ #include "updatecontroller.h" -void UpdateController::initialize(TCPServer *server,DataParser *dataParser) +UpdateController::UpdateController(QObject *parent) : + QObject(parent), + server(nullptr) +{ + buildPath = QDir::currentPath() + "/" + applicationFolderName; + sharedDataPath = QDir::currentPath() + "/" + sharedDataFolderName; + emit sigLogMessage(buildPath); + qDebug() << hashFileName; +} + +void UpdateController::initialize(ServerLMSWidget *server,DataParser *dataParser,AssetsManager *assetManager) { this->server = server; this->dataParser = dataParser; + this->assetManager = assetManager; + sizeToSend = 0; + assetManager->initialize(this,dataParser); + + calculateFullHash(); + currentStreamingPath = assetManager->setVersion("base"); + setUpCurrentServerHash(); + mutex = new QMutex; + qDebug() << "UpdateController init thread ID " << QThread::currentThreadId(); } -UpdateController::UpdateController(QObject *parent) : QObject(parent) +void UpdateController::changeAssetVersion(QString versionName) { - sourcePath = QDir::currentPath() + "/" + applicationFolderName; - emit sigLogMessage(sourcePath); - qDebug() << hashFileName; + server->slot_sendPacketToAllClients(PacketType::BUSY); + qDebug() << "UpdateController thread ID " << QThread::currentThreadId(); + currentStreamingPath = assetManager->setVersion(versionName); + setUpCurrentServerHash(); + server->slot_sendPacketToAllClients(PacketType::HASH_READY); + server->sendCurrentVersionToAllClient(); - if(!QFile::exists(hashFileName)){ - calculateHash(); - }else{ - loadHash(); - } + server->slot_sendPacketToAllClients(PacketType::FREE); +} +void UpdateController::createCopyVersion(QString versionName,QString newVersionName) +{ + server->slot_sendPacketToAllClients(PacketType::BUSY); + assetManager->createCopyVersion(versionName,newVersionName); + server->slot_sendPacketToAllClients(PacketType::FREE); +} + +void UpdateController::deleteAssetVersion(QString versionName) +{ + assetManager->deleteVersion(versionName); } void UpdateController::compareFiles(ClientHandler* handler, QByteArray array) @@ -29,16 +58,6 @@ void UpdateController::compareFiles(ClientHandler* handler, QByteArray array) clientDataList.clear(); dataParser->xmlFileDataParse(array); clientDataList.append(*dataParser->getDatas()); - - //Вывод информации о доступных файлов/* - // QListIterator iterator(clientDataList); - // while(iterator.hasNext()){ - // auto data = iterator.next(); - // emit sigLogMessage(data.path); - // emit sigLogMessage(data.hash); - // emit sigLogMessage("____________"); - // }*/ - checkNeedUpdate(handler); mutex->unlock(); } @@ -51,18 +70,30 @@ void UpdateController::showHash() } } -void UpdateController::saveHash() +void UpdateController::calculateFullHash() { - QFile hashFile(hashFileName); + server->slot_sendPacketToAllClients(PacketType::BUSY); + auto *list = calculateHash(buildPath); + saveHash(buildHashName,list); + calculateSharedHash(); + emit sigLogMessage("Calculate hash complete"); + server->slot_sendPacketToAllClients(PacketType::FREE); +} + +void UpdateController::saveHash(QString fileName,QList *fileList) +{ + QFile hashFile(fileName); hashFile.open(QIODevice::WriteOnly); QXmlStreamWriter xmlWriter(&hashFile); + QListIterator fileDataIterator(*fileList); xmlWriter.setAutoFormatting(true); xmlWriter.writeStartDocument(); xmlWriter.writeStartElement("FileDataList"); - foreach (FileData data,serverDataList) + while (fileDataIterator.hasNext()) { + FileData data = fileDataIterator.next(); xmlWriter.writeStartElement("FileData"); xmlWriter.writeAttribute("Path",data.path); @@ -124,7 +155,7 @@ void UpdateController::loadHash() void UpdateController::calculateSize() { - QDirIterator iterator(sourcePath); + QDirIterator iterator(buildPath); quint64 total = 0; while(iterator.hasNext()){ @@ -149,6 +180,23 @@ QString UpdateController::getCommands() } + + +void UpdateController::setUpCurrentServerHash() +{ + QList *fileList = new QList; + fileList->append(*calculateHash(buildPath)); + fileList->append(*calculateHash(currentStreamingPath)); + assetManager->prepareLocalPathList(fileList); + + saveHash(hashFileName,fileList); +} + +QString UpdateController::getCurrentStreamingPath() const +{ + return currentStreamingPath; +} + void UpdateController::setLocalFileData(QList dataList) { serverDataList.append(dataList); @@ -184,32 +232,6 @@ bool UpdateController::checkNeedUpdate(ClientHandler *handler) forSend->append(item); } } -// for (auto &item:clientDataList) //проверка на недостающие файлы по адресам -// { -// if (!serverDataList.contains(item)) -// { -// serverDataList.removeOne(item); -// clientDataList.removeOne(item); -// } -// } - -// for (auto &item:clientDataList) //проверка на недостающие файлы по адресам -// { -// if(item.path.contains("Temp")){ -// clientDataList.removeOne(item); -// } -// } - -// QListIterator serverDiffIterator(serverDataList); - -// while (serverDiffIterator.hasNext()) //добавление недостающих файлов в список для отправки -// { -// auto fileForUpdate = serverDiffIterator.next(); - -// if(fileForUpdate.path.contains("Temp")) continue; - -// fileSendList.append(fileForUpdate); -// } if(forSend->length() > 0) //формирование сообщения об обновлении { @@ -220,7 +242,10 @@ bool UpdateController::checkNeedUpdate(ClientHandler *handler) log.append(QString::number(forSend->length())); log.append(" objects"); fileSendList = *forSend; + emit sigLogMessage(log); + printFileList(*forSend); + handler->sendMessageBlock(log); needUpdate = true; } @@ -242,10 +267,10 @@ bool UpdateController::checkNeedUpdate(ClientHandler *handler) log.append(" Need delete: "); log.append(QString::number(forDelete->length())); log.append(" objects"); - //ОПАСНОСТЬ С РУКИ! УДАЛИТЬ И ПРИВЕСТИ В ПОРЯДОК - clientDataList = *forDelete; - // + fileDeleteList = *forDelete; + emit sigLogMessage(log); + printFileList(*forDelete); handler->sendMessageBlock(log); needUpdate = true; } @@ -255,33 +280,27 @@ bool UpdateController::checkNeedUpdate(ClientHandler *handler) log.append(Tools::getTime()); log.append(" Client: " + handler->getClient()->getLogin()); log.append(" no delete required"); + emit sigLogMessage(log); handler->sendMessageBlock(log); } CalculateSizeToSend(*forSend); - handler->sendNeedUpdate(needUpdate,sizeToSend,forSend->length()); - + handler->sendNeedUpdate(needUpdate,sizeToSend,forSend->length(),forDelete->length()); return needUpdate; } -void UpdateController::calculateHash() +QList* UpdateController::calculateHash(QString path) { - - QFile file(hashFileName); serverDataList.clear(); - if(file.exists()){ - file.remove(); + QDirIterator iterator(path,QDirIterator::Subdirectories); + if(!QDir(path).exists()){ + QDir().mkdir(path); } - QDirIterator iterator(sourcePath,QDirIterator::Subdirectories); - - if(!QDir(applicationFolderName).exists()){ - QDir().mkdir(applicationFolderName); - } - - QDir dir(sourcePath); + QDir dir(path); + dir.setFilter(QDir::NoDotAndDotDot); QString hashString; QList *files = new QList; @@ -323,21 +342,15 @@ void UpdateController::calculateHash() currentFile.hash = "FOLDER"; currentFile.path = Tools::createLocalPath(fileInfo.path()); - if(!folderDataList.contains(currentFile)){ - folderDataList.push_back(currentFile); + if(!files->contains(currentFile)){ + files->push_back(currentFile); } - } } - emit sigLogMessage("Calculate hash complete"); - serverDataList.append(folderDataList); + std::sort(files->begin(),files->end()); serverDataList.append(*files); - - saveHash(); - - qDebug() << "Recalculate complete"; - delete files; + return files; } QByteArray UpdateController::getLocalHash() @@ -352,28 +365,96 @@ QByteArray UpdateController::getLocalHash() return array; } +QString UpdateController::getCurrentVersionName() +{ + return assetManager->getCurrentVersionData()->getViewName(); +} + void UpdateController::CalculateSizeToSend(QList diffList) { QListIterator serverDiffIterator(diffList); - while (serverDiffIterator.hasNext()) //добавление недостающих файлов в список для отправки + while (serverDiffIterator.hasNext()) { - auto pathForUpdate = serverDiffIterator.next(); - QString path = Tools::createRootPath(pathForUpdate.path); + 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(); } } -UpdateController::~UpdateController() +void UpdateController::calculateSharedHash() { + QDir sharedDir(sharedDataPath); + QDirIterator dirIterator(sharedDir); + QList *fileList = new QList; + QList *versionList = new QList; + while (dirIterator.hasNext()) + { + dirIterator.next(); + QFileInfo fileInfo = dirIterator.fileInfo(); + if (fileInfo.fileName() == "." || fileInfo.fileName() == "..") + continue; + + QString fileName = staticDataFolderName + "/" + fileInfo.fileName() + "Hash.xml"; + + fileList = calculateHash(fileInfo.absoluteFilePath()); + saveHash(fileName,fileList); + + StreamingVersionData *version = new StreamingVersionData( + fileInfo.absoluteFilePath(),fileInfo.fileName(), + fileInfo.birthTime(),fileInfo.size()); + + versionList->append(version); + + } + + dataParser->createVersionListXmlAnswer(*versionList); + assetManager->setVersionList(versionList); } -QList UpdateController::getFileSendList() const +void UpdateController::sendNewVersionList() { - return fileSendList; + server->sendNewVersionListToAllClient(); +} + +bool UpdateController::checkDuplicate(QString versionName) +{ + return assetManager->findDuplicate(versionName); +} + +void UpdateController::printFileList(QList fileData) +{ + QListIterator iterator(fileData); + + while (iterator.hasNext()) + { + auto next = iterator.next(); + emit sigLogMessage(next.path); + } +} + +QList UpdateController::getFileDeleteList() const +{ + return fileDeleteList; +} + +QList UpdateController::getFileSendList() +{ + + QList sendList = *assetManager->prepareRealPathList(&fileSendList); + return sendList; } @@ -382,3 +463,8 @@ QList UpdateController::getClientDataList() const return clientDataList; } +UpdateController::~UpdateController() +{ + +} + diff --git a/ServerLMS/ServerLMS/Systems/updatecontroller.h b/ServerLMS/ServerLMS/Systems/updatecontroller.h index a3b3457..5bbaa02 100644 --- a/ServerLMS/ServerLMS/Systems/updatecontroller.h +++ b/ServerLMS/ServerLMS/Systems/updatecontroller.h @@ -9,13 +9,16 @@ #include #include #include -#include "Systems/dataparser.h" -#include "typesDataServerClient.h" + +#include +#include class TCPServer; class SendSystem; class DataParser; class ClientHandler; +class AssetsManager; +class ServerLMSWidget; class UpdateController : public QObject { @@ -24,39 +27,57 @@ class UpdateController : public QObject public: explicit UpdateController(QObject *parent = 0); - void initialize(TCPServer* server,DataParser *dataParser); + void initialize(ServerLMSWidget* server,DataParser *dataParser,AssetsManager *assetManager); void compareFiles(ClientHandler* handler, QByteArray array); void showHash(); - void calculateHash(); + void calculateFullHash(); + void calculateSharedHash(); + void sendNewVersionList(); + void setCurrentStreamingPath(QString path); + bool checkDuplicate(QString versionName); + QList* calculateHash(QString path); QByteArray getLocalHash(); - QList getFileSendList() const; + QString getCurrentVersionName(); + QList getFileSendList(); QList getClientDataList() const; + QList getFileDeleteList() const; + QString getCurrentStreamingPath() const; ~UpdateController(); +public slots: + void changeAssetVersion(QString versionName); + void createCopyVersion(QString versionName,QString newVersionName); + void deleteAssetVersion(QString versionName); + void setUpCurrentServerHash(); signals: void sigLogMessage(QString message); + //void sigSendPackege(PacketType packetType); private: QList clientDataList; QList serverDataList; - QList folderDataList; QList fileSendList; QList fileDeleteList; - QString sourcePath; - TCPServer *server; + QString buildPath; + QString currentStreamingPath; + QString sharedDataPath; + ServerLMSWidget *server; DataParser *dataParser; + AssetsManager *assetManager; quint64 sizeToSend; QMutex *mutex; QString getCommands(); + void printFileList(QList fileData); + bool checkNeedUpdate(ClientHandler* handler); void setLocalFileData(QList dataList); void calculateSize(); - void saveHash(); + void saveHash(QString fileName,QList *fileList); void loadHash(); void CalculateSizeToSend(QList diffList); }; diff --git a/ServerLMS/ServerLMS/clienthandler.cpp b/ServerLMS/ServerLMS/clienthandler.cpp index 34a1813..2ab918e 100644 --- a/ServerLMS/ServerLMS/clienthandler.cpp +++ b/ServerLMS/ServerLMS/clienthandler.cpp @@ -44,16 +44,19 @@ void ClientHandler::initialize(int descriptor,ServerLMSWidget *serverWidget, connect(this,&ClientHandler::sigFolderBlock,sendSystem,&SendSystem::sendFolderBlock,Qt::AutoConnection); connect(this,&ClientHandler::sigGetIsSendStopped,sendSystem,&SendSystem::getIsSendStopped,Qt::AutoConnection); connect(this,&ClientHandler::sigSendDeleteBlock,sendSystem,&SendSystem::sendDeleteBlock,Qt::AutoConnection); - connect(this,&ClientHandler::sigSendFinish,sendSystem,&SendSystem::sendFinish,Qt::AutoConnection); + connect(this,&ClientHandler::sigSendFinish,sendSystem,&SendSystem::sendPacketType,Qt::AutoConnection); connect(this,&ClientHandler::sigSendMessageBlock,sendSystem,&SendSystem::sendMessageBlock,Qt::AutoConnection); connect(this,&ClientHandler::sigNeedUpdate,sendSystem,&SendSystem::sendNeedUpdate,Qt::AutoConnection); connect(this,&ClientHandler::sigSendNotify,sendSystem,&SendSystem::sendNotify,Qt::AutoConnection); connect(this,&ClientHandler::sigSendFileBlockWithRename,sendSystem,&SendSystem::sendFileBlockWithRename,Qt::AutoConnection); - connect(socket,&QTcpSocket::readyRead,recognizeSystem,&RecognizeSystem::recognize,Qt::AutoConnection); - connect(socket, &QTcpSocket::disconnected, this, &ClientHandler::sendDisable,Qt::AutoConnection); + connect(this,&ClientHandler::sigSendVersion,sendSystem,&SendSystem::sendVersion,Qt::AutoConnection); connect(this,&ClientHandler::sigSocketWrite,sendSystem,&SendSystem::socketWrite,Qt::AutoConnection); connect(this,&ClientHandler::sigSocketClose,sendSystem,&SendSystem::socketClose,Qt::AutoConnection); + connect(this,&ClientHandler::sigSocketFlush,sendSystem,&SendSystem::socketFlush,Qt::AutoConnection); + connect(this,&ClientHandler::sigSendPacketType,sendSystem,&SendSystem::sendPacketType,Qt::AutoConnection); + connect(socket,&QTcpSocket::readyRead,recognizeSystem,&RecognizeSystem::recognize,Qt::AutoConnection); + connect(socket, &QTcpSocket::disconnected, this, &ClientHandler::sendDisable,Qt::AutoConnection); recognizeSystem->initialize(updateController,dataParser,serverWidget,sendSystem, this); sendSystem->setClient(client,socket); @@ -62,6 +65,11 @@ void ClientHandler::initialize(int descriptor,ServerLMSWidget *serverWidget, emit sigInitSender(dataParser,logger); } +void ClientHandler::setClient(Client *value) +{ + client = value; +} + void ClientHandler::sendHash() { QString path = "\\" + hashFileName; @@ -69,21 +77,31 @@ void ClientHandler::sendHash() //emit sigSendNotify("HASHSENDCOMPLETE"); } +void ClientHandler::sendVersion() +{ + emit sigSendVersion(); +} + +void ClientHandler::sendVersionList() +{ + QFile file(versionListFile); + file.open(QFile::ReadOnly); + + QByteArray array = file.readAll(); + file.close(); + emit sendXmlAnswer(array); +} + +void ClientHandler::sendPacketType(PacketType packetType) +{ + emit sigSendPacketType(packetType); +} + void ClientHandler::sendXmlAnswer(QByteArray array, PacketType packetType) { emit sigSendXmlAnswer(array, packetType); } -void ClientHandler::sendFolderBlock(QString path) -{ - emit sigFolderBlock(path); -} - -void ClientHandler::sendFileBlock(QString path) -{ - emit sigFileBlock(path); -} - bool ClientHandler::getIsSendStopped() { return emit sigGetIsSendStopped(); @@ -96,7 +114,7 @@ void ClientHandler::sendDeleteBlock(QString path) void ClientHandler::sendFinish() { - emit sigSendFinish(); + emit sigSendFinish(PacketType::TYPE_FINISH); } void ClientHandler::sendMessageBlock(QString text) @@ -104,9 +122,9 @@ void ClientHandler::sendMessageBlock(QString text) emit sigSendMessageBlock(text); } -void ClientHandler::sendNeedUpdate(bool flag, quint64 size, quint64 fileCount) +void ClientHandler::sendNeedUpdate(bool flag, quint64 size, quint64 fileCount,quint64 deleteCount) { - emit sigNeedUpdate(flag,size,fileCount); + emit sigNeedUpdate(flag,size,fileCount,deleteCount); } void ClientHandler::sendDisable() diff --git a/ServerLMS/ServerLMS/clienthandler.h b/ServerLMS/ServerLMS/clienthandler.h index f28cfce..8b2f478 100644 --- a/ServerLMS/ServerLMS/clienthandler.h +++ b/ServerLMS/ServerLMS/clienthandler.h @@ -2,11 +2,13 @@ #define CLIENTHANDLER_H #include -#include -#include "Client.h" #include #include -#include "Systems/tools.h" + +#include +#include +#include +#include class SendSystem; class DataParser; @@ -29,10 +31,13 @@ public: void sendDeleteBlock(QString path); void sendFinish(); void sendMessageBlock(QString text); - void sendNeedUpdate(bool flag, quint64 size,quint64 fileCount); + void sendNeedUpdate(bool flag, quint64 size,quint64 fileCount,quint64 deleteCount); void sendDisable(); void recognize(); void sendHash(); + void sendVersionList(); + void sendPacketType(PacketType packetType); + void sendVersion(); ~ClientHandler(); @@ -48,9 +53,9 @@ signals: void sigFileBlock(QString path); bool sigGetIsSendStopped(); void sigSendDeleteBlock(QString path); - void sigSendFinish(); + void sigSendFinish(PacketType packetType); void sigSendMessageBlock(QString text); - void sigNeedUpdate(bool flag,quint64 size,quint64 fileCount); + void sigNeedUpdate(bool flag,quint64 size,quint64 fileCount,quint64 deleteCount); void sigClientDisconnected(QString address,QString port); void sigSendHash(); void sigRecognize(ClientHandler *handler); @@ -59,13 +64,16 @@ signals: void sigSocketWrite(QByteArray array); void sigSocketClose(); bool sigSocketFlush(); + void sigSendVersion(); + void sigSendPacketType(PacketType packetType); public : QThread *thread; QTcpSocket *socket; void initialize(int descriptor, ServerLMSWidget *serverWidget, - UpdateController *updateController, DataParser *dataParser,Logger *logger); + UpdateController *updateController, DataParser *dataParser,Logger *logger); + void setClient(Client *value); private: UpdateController *updateController; RecognizeSystem *recognizeSystem; diff --git a/ServerLMS/ServerLMS/serverlmswidget.cpp b/ServerLMS/ServerLMS/serverlmswidget.cpp index 66685e0..a72233e 100644 --- a/ServerLMS/ServerLMS/serverlmswidget.cpp +++ b/ServerLMS/ServerLMS/serverlmswidget.cpp @@ -51,8 +51,12 @@ ServerLMSWidget::ServerLMSWidget(QWidget *parent) : connect(logger,&Logger::sigSendTextToLogger,this,&ServerLMSWidget::slotAddToLog,Qt::QueuedConnection); logger->moveToThread(loggerThread); + assetsManager = new AssetsManager; + assetsManager->moveToThread(updateThread); + processingSystem = new ProcessingSystem(providerDBLMS); - dataParser = new DataParser(processingSystem); + processingSystem->moveToThread(updateThread); + dataParser = new DataParser(assetsManager,processingSystem); updateController = new UpdateController; updateController->moveToThread(updateThread); @@ -60,21 +64,19 @@ ServerLMSWidget::ServerLMSWidget(QWidget *parent) : loggerThread->start(); updateThread->start(); - updateController->initialize(nullptr,dataParser); + processingSystem->initialize(dataParser,this); logger->setTypeLog("widget"); - connect(processingSystem,&ProcessingSystem::sigUpdateListClients,this, &ServerLMSWidget::slotUpdateListClients); connect(updateController,&UpdateController::sigLogMessage,logger,&Logger::addTextToLogger); connect(dataParser,&DataParser::sigLogMessage,logger,&Logger::addTextToLogger); - connect(processingSystem,&ProcessingSystem::sigLogMessage,logger,&Logger::addTextToLogger); - connect(this,&ServerLMSWidget::sigLog,logger,&Logger::addTextToLogger); - connect(processingSystem,&ProcessingSystem::sigAuthChanged,this, &ServerLMSWidget::slot_AuthChanged); - connect(processingSystem,&ProcessingSystem::signal_msgToClientReady,this, &ServerLMSWidget::slot_msgToClientFromGUI); - connect(processingSystem,&ProcessingSystem::signal_msgFromClientReady,this, &ServerLMSWidget::slot_msgToGUIfromClient); + connect(this,&ServerLMSWidget::sigUpdateController,updateController,&UpdateController::initialize,Qt::DirectConnection); + connect(this,&ServerLMSWidget::sigLog,logger,&Logger::addTextToLogger,Qt::AutoConnection); + connect(this,&ServerLMSWidget::sigCalculateFullHash,updateController,&UpdateController::calculateFullHash,Qt::AutoConnection); + emit sigUpdateController(this,dataParser,assetsManager); on_btnStartServer_clicked(); first = true; @@ -95,6 +97,30 @@ void ServerLMSWidget::autorizationHandler(QString login) } } +void ServerLMSWidget::sendNewVersionListToAllClient() +{ + foreach(int idSocket,clientsMap.keys()) + { + ClientHandler *handler = clientsMap[idSocket]; + + if (!handler->getClient()->getIsLoggedIn()) continue; + + handler->sendVersionList(); + } +} + +void ServerLMSWidget::sendCurrentVersionToAllClient() +{ + foreach(int idSocket,clientsMap.keys()) + { + ClientHandler *handler = clientsMap[idSocket]; + + if (!handler->getClient()->getIsLoggedIn()) continue; + handler->sendVersion(); + + } +} + ServerLMSWidget::~ServerLMSWidget() { stopServer(); @@ -162,6 +188,11 @@ bool ServerLMSWidget::stopServer() return false; } +Logger *ServerLMSWidget::getLogger() const +{ + return logger; +} + QMap ServerLMSWidget::getClientsMap() const { return clientsMap; @@ -210,6 +241,18 @@ void ServerLMSWidget::slot_AuthChanged() } } +void ServerLMSWidget::slot_sendPacketToAllClients(PacketType packetType) +{ + foreach(int idSocket, clientsMap.keys()) + { + ClientHandler *handler = clientsMap[idSocket]; + + if (!handler->getClient()->getIsLoggedIn()) continue; + + handler->sendPacketType(packetType); + } +} + void ServerLMSWidget::removeClient(int idSocket) { clientsMap.remove(idSocket); @@ -293,7 +336,7 @@ void ServerLMSWidget::on_btnStartServer_clicked() if(startServer()) { QApplication::setOverrideCursor(Qt::WaitCursor); - updateController->calculateHash(); + emit sigCalculateFullHash(); QApplication::restoreOverrideCursor(); ui->btnStartServer->setEnabled(false); diff --git a/ServerLMS/ServerLMS/serverlmswidget.h b/ServerLMS/ServerLMS/serverlmswidget.h index af1090d..6935fab 100644 --- a/ServerLMS/ServerLMS/serverlmswidget.h +++ b/ServerLMS/ServerLMS/serverlmswidget.h @@ -1,23 +1,26 @@ #ifndef SERVERLMSWIDGET_H #define SERVERLMSWIDGET_H +#include "ServerLMS_global.h" + #include #include #include #include #include #include +#include + #include #include #include #include +#include #include #include -#include -#include "ServerLMS_global.h" -#include "typesDataServerClient.h" -#include "Client.h" +#include +#include #include "multithreadserver.h" #include "providerdblms.h" @@ -33,6 +36,7 @@ class UpdateController; class RecognizeSystem; class ClientHandler; class MultiThreadServer; +class AssetsManager; class SERVERLMS_EXPORT ServerLMSWidget : public QWidget { @@ -43,6 +47,8 @@ public: ~ServerLMSWidget(); void autorizationHandler(QString login); + void sendNewVersionListToAllClient(); + void sendCurrentVersionToAllClient(); protected: // Метод получения событий @@ -51,8 +57,11 @@ protected: signals: void sigRecognize(); - QTcpSocket* sigGetSocket(); void sigLog(QString log); + void sigCalculateFullHash(); + void sigUpdateController(ServerLMSWidget* server,DataParser *dataParser,AssetsManager *assetManager); + + QTcpSocket* sigGetSocket(); public slots: void slot_LanguageChanged(QString language); @@ -60,8 +69,7 @@ public slots: void slotUpdateListClients(); void slot_BlockAutorization(bool block); void slot_AuthChanged(); - -private slots: + void slot_sendPacketToAllClients(PacketType packetType); //слот обработки сигнала о готовности нового сообщения на отправку клиенту от мессенджера void slot_msgToClientFromGUI(QString login, QString text); void slot_msgToGUIfromClient(QString login, QString text); @@ -90,6 +98,8 @@ public: QMap getClientsMap() const; + Logger *getLogger() const; + private slots: void on_btnStartServer_clicked(); void on_btnStopServer_clicked(); @@ -115,6 +125,7 @@ private: DataParser *dataParser; ProcessingSystem *processingSystem; UpdateController *updateController; + AssetsManager *assetsManager; Logger *logger; ProviderDBLMS* providerDBLMS;