279 lines
9.8 KiB
C++
Executable File
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
|