Files
qt5-legatus-legacy/Lts/Proxies/TrainingAreaBase/Plugins/AdlerJson/flm_handler.cpp
T
2026-08-13 18:33:10 +02:00

279 lines
9.8 KiB
C++
Executable File

/**
* @RDE_HEADER@
* FlmHandler for AdlerJson Plugin
* $Id: pdm_handler.cpp 62304 2024-03-21 08:17:45Z ewert_j $
* $HeadURL: svn://slssvn/TDS/branches/product/features/ufom/Lts/Proxies/TrainingAreaBase/Plugins/UFomHlaJson/pdm_handler.cpp $
* $Author: ewert_j $
* Created by Hanna E. Rathje, 2025-11-18
*/
#include "flm_handler.h"
#include "FileManagement/flm_operator_rights.h"
#include "main_dispatcher.h"
#include "nglsettings/nglsettings_settings.h"
#include "ngltools/ngltools_filesystem.h"
#include <QJsonArray>
#include <QJsonDocument>
#include <FileManagement/flm_dtc.h>
#include <LtsUtilsCore/dds_vector.h>
namespace AdlerJson
{
FlmHandler::FlmHandler(QObject *parent)
: QObject(parent)
, m_exerciseId(-1)
, m_parentFolderId(-1)
, m_partyId(-1)
, m_folderHXMessagesId(-1)
, m_dtcFlm(nullptr)
, m_ftcFlm(nullptr)
, m_ftcNom(nullptr)
, m_opmDtc(nullptr)
, m_logger(getLogger("FlmHandler"))
{
}
bool FlmHandler::init(MainDispatcher *mainDispatcher)
{
m_mainDispatcher = mainDispatcher;
m_exerciseId = mainDispatcher->exerciseId();
m_dtcFlm = FileManagement::Interface::Dtc::create(mainDispatcher->ddsHandler()->ddsConnector());
m_ftcFlm = FileManagement::Interface::Ftc::create(mainDispatcher->ddsHandler()->ddsConnector());
m_dtcFlm->enableFileContent();
m_dtcFlm->enableFolder();
m_ftcFlm->enableFileContentModify();
m_ftcFlm->enablePathCreate();
m_ftcNom = NotificationManagement::Interface::Ftc::create(mainDispatcher->ddsHandler()->ddsConnector());
m_ftcNom->enableAll();
m_opmDtc = OperatorManagement::Interface::Dtc::create(mainDispatcher->ddsHandler()->ddsConnector());
m_opmDtc->enableUser();
return true;
}
bool FlmHandler::processHQMessage(int partyId, const QString &name, int meldungsnummer, const QJsonObject &obj)
{
ERROR_LOG(m_logger) << "exerciseId: " << m_exerciseId << ", partyId: " << partyId
<< ", name: " << name
<< ", meldungsnummer: " << meldungsnummer;
// get FolderId for PartyId
int partyFolderId = m_dtcFlm->getPartyFolderId(m_exerciseId, partyId);
const QString folderName = QStringLiteral("Messages");
int folderHXMessagesId = m_dtcFlm->findFolder(partyFolderId, folderName);
ERROR_LOG(m_logger) << "folderHXMessagesId: " << folderHXMessagesId;
if (folderHXMessagesId <= 0)
{
ERROR_LOG(m_logger) << "Folder Messages does not exist for exerciseId: " << m_exerciseId << ", partyId: " << partyId;
return false;
}
FileManagement::FileContentModifyRequest fileContentReq;
fileContentReq.isTemplate(false);
fileContentReq.isHidden(true);
fileContentReq.folderId(folderHXMessagesId);
const QVector<int> fldPath = LtsUtils::convert<QVector<int>>(m_dtcFlm->folder(folderHXMessagesId).path());
fileContentReq.fileCategory(FileManagement::FileCategory::Exercise);
fileContentReq.fileType(FileManagement::FileType::AdlerJson);
fileContentReq.fileStatus(FileManagement::FileStatus::Valid);
QByteArray content = QJsonDocument(obj).toJson(QJsonDocument::Compact).constData();
fileContentReq.content(LtsUtils::convert<std::vector<uint8_t>>(content));
fileContentReq.isUsedBy(false);
fileContentReq.usedBy(0);
fileContentReq.lastModified(m_mainDispatcher->ddsHandler()->partitionTime());
fileContentReq.exerciseId(m_exerciseId);
fileContentReq.operatorId(99); // organizer
DEBUG_LOG(m_logger) << "HQ: name: " << fileContentReq.name() << ", folderId: " << folderHXMessagesId << ", exerciseId: " << m_exerciseId << ", partyId: " << partyId;
// Check if Filename already exists
QRegularExpression re(QStringLiteral("_\\d+$"));
QString baseName = name + QStringLiteral(" (") + QString::number(meldungsnummer) + QStringLiteral(")");
baseName.remove(re);
// nornalized (important for Umlaute in baseName)
baseName = baseName.normalized(QString::NormalizationForm_C);
ERROR_LOG(m_logger) << "BaseName: " << baseName << "|";
QStringList fileNames;
if (!m_dtcFlm->getAllFiles(fileContentReq.fileType(), folderHXMessagesId, fileNames, true))
{
ERROR_LOG(m_logger) << "Error while reading fileNames for folderId: " << folderHXMessagesId;
return false;
}
int maxNumber = 0;
for (const QString &fileName : qAsConst(fileNames))
{
QString normalizedName = fileName.normalized(QString::NormalizationForm_C);
DEBUG_LOG(m_logger) << "normalized fileName: " << normalizedName << "|";
if (!normalizedName.startsWith(baseName))
continue;
QString rest = fileName.mid(baseName.length());
DEBUG_LOG(m_logger) << "rest: " << rest;
if (rest.contains(QStringLiteral(".")))
rest = rest.section(QStringLiteral("."), 0, 0);
if (rest.startsWith(QStringLiteral("_")))
rest = rest.mid(1);
if (rest.isEmpty())
maxNumber = std::max(maxNumber, 0);
else
{
bool ok;
int currentNum = rest.toInt(&ok);
if (ok)
maxNumber = std::max(maxNumber, currentNum);
}
DEBUG_LOG(m_logger) << " maxNumber: " << maxNumber;
}
const QString newName = baseName
+ QStringLiteral("_") + QString::number(++maxNumber);
DEBUG_LOG(m_logger) << "newName : " << newName;
fileContentReq.name(newName.toStdString());
// fileId will be in reply
m_partyId = partyId;
m_folderHXMessagesId = folderHXMessagesId;
m_ftcFlm->fileContentModifyRequest(fileContentReq, this);
return true;
}
void FlmHandler::createHQNotification(const int partyId, const int folderId, const int fileId)
{
qint64 currentTime = m_mainDispatcher->ddsHandler()->partitionTime();
QScopedPointer<NGL::Settings> s(new NGL::Settings(NGL::findProjectConfigFile()));
qint64 expiryTime = currentTime + s->getInteger(QStringLiteral("NOM/expiryIntervalMSec"), 2 * 24 * 60 * 60 * 1000); // default 2 day
NotificationManagement::NomNotification notif;
notif.title(tr("HQ Report").toStdString());
/// for more see in nom_test.cpp
QString linkName = tr("Open HQ Report Dialog");
QString content = QStringLiteral("[%1](//flmHQReport/?party=%2&folder=%3&file=%4)").arg(linkName).arg(partyId).arg(folderId).arg(fileId);
QMap<QString, QString> linkMap;
parseContent(content, linkMap);
// now replace the strings
QMapIterator<QString, QString> it(linkMap);
while (it.hasNext())
{
it.next();
content = content.replace(QStringLiteral("[%1](%2)").arg(it.value(), it.key()), QStringLiteral("<a href='%1'>%2</a>").arg(it.key(), it.value()));
}
notif.content(content.toStdString());
notif.timeStamp(currentTime);
notif.expiryTime(expiryTime);
int prio = s->getInteger(QStringLiteral("NOM/notificationPriority"), 3); // default prio 3: normal
DEBUG_LOG(m_logger) << " Setting: NotificationPriority: " << prio;
notif.priority(static_cast<NotificationManagement::Priority_def::type>(prio));
notif.processedPriority(NotificationManagement::Priority_def::Low);
notif.exerciseId(m_exerciseId);
for (const auto &userId : m_opmDtc->getOperatorsByOperatorRight(OperatorRights::FileManagementFilesEdit))
{
NotificationManagement::Address addr;
addr.addressId(userId);
addr.isRead(false);
addr.name(m_opmDtc->user(userId).name());
addr.addressType(NotificationManagement::AddressType_def::Operator);
notif.recipientIds().push_back(addr);
}
NotificationManagement::CreateNotificationRequest notifReq;
notifReq.notification(notif);
if (!m_ftcNom->createNotificationRequest(notifReq, this))
ERROR_LOG(m_logger) << "Error requesting create Notification data";
}
void FlmHandler::initHQFolders(int partyId)
{
// get FolderId for Exercise
int exerciseFolderId = m_dtcFlm->getExerciseFolderId(m_exerciseId);
if (exerciseFolderId <= 0)
{
ERROR_LOG(m_logger) << "No exercise Folder for exerciseId: " << m_exerciseId;
return;
}
const QString &partyName = m_dtcFlm->getPartyFolderName(partyId);
std::vector<std::string> vecFolderNames = {"HQ Data", partyName.toStdString(), "Messages"};
FileManagement::PathCreateRequest req;
req.path(vecFolderNames);
req.parentId(exerciseFolderId);
req.isEditable(false);
req.operatorId(99); // Organizer
m_ftcFlm->pathCreateRequest(req, this);
}
void FlmHandler::onFileContentModifyReply(const Core::FunctionReplyObject &reply)
{
DEBUG_LOG(m_logger) << "Got Function Reply: " << reply.translated();
if (reply.error())
ERROR_LOG(m_logger) << "Error while insert HX Message: " << reply.translated() << ", error: " << reply.error();
else
createHQNotification(m_partyId, m_folderHXMessagesId, reply.id());
}
void FlmHandler::onPathCreateReply(const Core::FunctionReplyObject &reply)
{
DEBUG_LOG(m_logger) << "Got Function Reply: " << reply.translated();
if (reply.error())
{
ERROR_LOG(m_logger) << "Error while creating folders: " << reply.translated() << ", error: " << reply.error();
}
}
void FlmHandler::onCreateNotificationReply(const Core::FunctionReplyObject &replyObject)
{
INFO_LOG(m_logger) << "FlmHandler: Got createReply with id " << replyObject.id() << " and errorString " << replyObject.translated();
}
bool FlmHandler::parseContent(const QString &contentString, QMap<QString, QString> &retMap)
{
if (contentString.isEmpty())
return false;
// Mark Down Regex lookig for String between ]( and ) eg: TestLingk "[LinkName](http::blahblah)"
QRegularExpression regLink(QStringLiteral("(?<=\\]\\()(.*?)(?=\\))"));
QRegularExpressionMatch matchLink = regLink.match(contentString);
QRegularExpression regDesc(QStringLiteral("(?<=\\[)(.*?)(?=\\]\\()"));
QRegularExpressionMatch matchDesc = regDesc.match(contentString);
QRegularExpressionMatchIterator itLink = regLink.globalMatch(contentString);
QRegularExpressionMatchIterator itDesc = regDesc.globalMatch(contentString);
while (itLink.hasNext() && itDesc.hasNext())
{
QString linkRef = itLink.next().captured();
QString linkDesc = itDesc.next().captured();
if (!linkRef.isEmpty() && !linkDesc.isEmpty())
{
retMap.insert(linkRef, linkDesc);
}
}
return retMap.size();
}
} // namespace AdlerJson