File indexing completed on 2024-05-26 05:05:31

0001 /*
0002    SPDX-FileCopyrightText: 2020-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "administratorserverinfowidget.h"
0008 #include "connection.h"
0009 #include "license/licenseslistjob.h"
0010 #include "misc/statisticsjob.h"
0011 #include "rocketchataccount.h"
0012 #include "ruqolawidgets_debug.h"
0013 #include "serverinfojob.h"
0014 #include <KLineEditEventHandler>
0015 
0016 #include <KIO/Global>
0017 #include <KLocalizedString>
0018 #include <KTreeWidgetSearchLine>
0019 #include <KTreeWidgetSearchLineWidget>
0020 #include <QApplication>
0021 #include <QClipboard>
0022 #include <QHeaderView>
0023 #include <QMenu>
0024 #include <QPushButton>
0025 #include <QTreeWidget>
0026 #include <QVBoxLayout>
0027 
0028 AdministratorServerInfoWidget::AdministratorServerInfoWidget(RocketChatAccount *account, QWidget *parent)
0029     : QWidget(parent)
0030     , mTreeWidget(new QTreeWidget(this))
0031     , mSearchLineWidget(new KTreeWidgetSearchLineWidget(this, mTreeWidget))
0032     , mRefreshButton(new QPushButton(QIcon::fromTheme(QStringLiteral("view-refresh")), {}, this))
0033     , mRocketChatAccount(account)
0034 {
0035     auto mainLayout = new QVBoxLayout(this);
0036     mainLayout->setObjectName(QStringLiteral("mainLayout"));
0037     mainLayout->setContentsMargins({});
0038     mainLayout->setSpacing(0);
0039 
0040     auto hboxLayout = new QHBoxLayout;
0041     hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
0042     hboxLayout->setContentsMargins({});
0043     mainLayout->addLayout(hboxLayout);
0044     mSearchLineWidget->setObjectName(QStringLiteral("mSearchLineWidget"));
0045     KLineEditEventHandler::catchReturnKey(mSearchLineWidget->searchLine());
0046     hboxLayout->addWidget(mSearchLineWidget);
0047     mRefreshButton->setObjectName(QStringLiteral("mRefreshButton"));
0048     mRefreshButton->setToolTip(i18n("Refresh"));
0049     hboxLayout->addWidget(mRefreshButton);
0050     connect(mRefreshButton, &QPushButton::clicked, this, &AdministratorServerInfoWidget::slotRefreshInfo);
0051 
0052     mTreeWidget->setObjectName(QStringLiteral("mTreeWidget"));
0053     mTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
0054     connect(mTreeWidget, &QTreeWidget::customContextMenuRequested, this, &AdministratorServerInfoWidget::slotContextMenu);
0055 
0056     mainLayout->addWidget(mTreeWidget);
0057     mTreeWidget->header()->hide();
0058     mTreeWidget->setColumnCount(2);
0059 }
0060 
0061 AdministratorServerInfoWidget::~AdministratorServerInfoWidget() = default;
0062 
0063 void AdministratorServerInfoWidget::slotContextMenu(const QPoint &pos)
0064 {
0065     QMenu menu(this);
0066     const QModelIndex index = mTreeWidget->indexAt(pos);
0067     menu.addAction(QIcon::fromTheme(QStringLiteral("edit-copy")), i18n("Copy"), this, [index]() {
0068         const QString currentValue = index.data().toString();
0069         QClipboard *clip = QApplication::clipboard();
0070         clip->setText(currentValue, QClipboard::Clipboard);
0071         clip->setText(currentValue, QClipboard::Selection);
0072     });
0073     menu.exec(mTreeWidget->viewport()->mapToGlobal(pos));
0074 }
0075 
0076 void AdministratorServerInfoWidget::slotRefreshInfo()
0077 {
0078     loadStatisticInfo(true);
0079 }
0080 
0081 void AdministratorServerInfoWidget::initialize()
0082 {
0083     if (!mRocketChatAccount->ruqolaServerConfig()->hasAtLeastVersion(4, 0, 0)) {
0084         auto serverInfoJob = new RocketChatRestApi::ServerInfoJob(this);
0085         serverInfoJob->setForceRequiresAuthentication(true);
0086         mRocketChatAccount->restApi()->initializeRestApiJob(serverInfoJob);
0087         connect(serverInfoJob, &RocketChatRestApi::ServerInfoJob::serverInfoDone, this, &AdministratorServerInfoWidget::slotServerInfoDone);
0088         if (!serverInfoJob->start()) {
0089             qCDebug(RUQOLAWIDGETS_LOG) << "Impossible to start ServerInfoJob";
0090         }
0091     } else {
0092         loadLicensesInfo();
0093         loadStatisticInfo(false);
0094     }
0095 }
0096 
0097 void AdministratorServerInfoWidget::slotServerInfoDone(const QString &versionInfo, const QJsonObject &obj)
0098 {
0099     Q_UNUSED(versionInfo)
0100     // qDebug() << " obj " << obj;
0101     mServerInfo.parseServerInfo(obj);
0102     // qDebug() << " info " << mServerInfo;
0103     loadStatisticInfo(false);
0104     loadServerInfo();
0105 }
0106 
0107 void AdministratorServerInfoWidget::loadLicensesInfo()
0108 {
0109     auto licenseInfoJob = new RocketChatRestApi::LicensesListJob(this);
0110     mRocketChatAccount->restApi()->initializeRestApiJob(licenseInfoJob);
0111     connect(licenseInfoJob, &RocketChatRestApi::LicensesListJob::licensesListDone, this, &AdministratorServerInfoWidget::slotLicensesListDone);
0112     if (!licenseInfoJob->start()) {
0113         qCDebug(RUQOLAWIDGETS_LOG) << "Impossible to start LicensesListJob";
0114     }
0115 }
0116 
0117 void AdministratorServerInfoWidget::slotLicensesListDone(const QJsonObject &obj)
0118 {
0119     // Load Statistic after loading licenses info
0120     fillLicenses(obj);
0121     loadStatisticInfo(false);
0122 }
0123 
0124 void AdministratorServerInfoWidget::fillLicenses(const QJsonObject &obj)
0125 {
0126     QStringList listLicences;
0127     const QJsonArray licenses = obj.value(QStringLiteral("licenses")).toArray();
0128     for (const auto &a : licenses) {
0129         listLicences.append(a.toString());
0130     }
0131     auto licenseItem = new QTreeWidgetItem(mTreeWidget);
0132     licenseItem->setText(0, i18n("Licenses"));
0133     createItemFromLicense(licenseItem, i18n("Omnichannel"), listLicences.contains(QStringLiteral("livechat-enterprise")));
0134     createItemFromLicense(licenseItem, i18n("Auditing"), listLicences.contains(QStringLiteral("auditing")));
0135     createItemFromLicense(licenseItem, i18n("Canned Responses"), listLicences.contains(QStringLiteral("canned-responses")));
0136     createItemFromLicense(licenseItem, i18n("Engagement Dashboard"), listLicences.contains(QStringLiteral("engagement-dashboard")));
0137     createItemFromLicense(licenseItem, i18n("Read Receipts"), listLicences.contains(QStringLiteral("message-read-receipt")));
0138 }
0139 
0140 void AdministratorServerInfoWidget::createItemFromLicense(QTreeWidgetItem *licenseInfoItem, const QString &name, bool valid)
0141 {
0142     auto item = new QTreeWidgetItem(licenseInfoItem);
0143     item->setText(0, name);
0144     item->setIcon(0, valid ? QIcon::fromTheme(QStringLiteral("dialog-ok-apply")) : QIcon::fromTheme(QStringLiteral("dialog-cancel")));
0145     licenseInfoItem->addChild(item);
0146 }
0147 
0148 void AdministratorServerInfoWidget::loadStatisticInfo(bool refresh)
0149 {
0150     auto statisticJob = new RocketChatRestApi::StatisticsJob(this);
0151     statisticJob->setRefresh(refresh);
0152     mRocketChatAccount->restApi()->initializeRestApiJob(statisticJob);
0153     connect(statisticJob, &RocketChatRestApi::StatisticsJob::statisticDone, this, &AdministratorServerInfoWidget::slotStatisticDone);
0154     if (!statisticJob->start()) {
0155         qCDebug(RUQOLAWIDGETS_LOG) << "Impossible to start StatisticsJob";
0156     }
0157 }
0158 
0159 void AdministratorServerInfoWidget::parseServerInfo(QTreeWidgetItem *serverInfoItem, const QJsonObject &obj)
0160 {
0161     createItemFromStringValue(serverInfoItem, obj, i18n("Version"), QStringLiteral("version"));
0162     createItemFromStringValue(serverInfoItem, obj, i18n("Deployment ID"), QStringLiteral("uniqueId"));
0163 }
0164 
0165 void AdministratorServerInfoWidget::createItemFromStringValue(QTreeWidgetItem *parentItem,
0166                                                               const QJsonObject &obj,
0167                                                               const QString &label,
0168                                                               const QString &identifier)
0169 {
0170     const QJsonValue objValue = obj.value(identifier);
0171     if (!objValue.isUndefined()) {
0172         auto item = new QTreeWidgetItem(parentItem);
0173         item->setText(0, label);
0174         item->setText(1, objValue.toString());
0175         item->addChild(item);
0176     }
0177 }
0178 
0179 void AdministratorServerInfoWidget::parseUsageInfo(QTreeWidgetItem *usageInfoItem, const QJsonObject &obj)
0180 {
0181     // qDebug() << " obj " << obj;
0182     createItemFromIntValue(usageInfoItem, obj, i18n("Rocket.Chat App Users"), QStringLiteral("appUsers"));
0183     createItemDisplayFormat(usageInfoItem, obj, i18n("Total Uploads Size"), QStringLiteral("uploadsTotalSize"));
0184     createItemFromIntValue(usageInfoItem, obj, i18n("Total Uploads"), QStringLiteral("uploadsTotal"));
0185 
0186     createItemFromIntValue(usageInfoItem, obj, i18n("Online Users"), QStringLiteral("onlineUsers"));
0187     createItemFromIntValue(usageInfoItem, obj, i18n("Away Users"), QStringLiteral("awayUsers"));
0188     createItemFromIntValue(usageInfoItem, obj, i18n("Offline Users"), QStringLiteral("offlineUsers"));
0189     createItemFromIntValue(usageInfoItem, obj, i18n("Busy Users"), QStringLiteral("busyUsers"));
0190 
0191     createItemFromIntValue(usageInfoItem, obj, i18n("Activated Users"), QStringLiteral("activeUsers"));
0192     createItemFromIntValue(usageInfoItem, obj, i18n("Activated Guests"), QStringLiteral("activeGuests"));
0193     createItemFromIntValue(usageInfoItem, obj, i18n("Deactivated Users"), QStringLiteral("nonActiveUsers"));
0194 
0195     createItemFromIntValue(usageInfoItem, obj, i18n("Total Channels"), QStringLiteral("totalChannels"));
0196     createItemFromIntValue(usageInfoItem, obj, i18n("Total Rooms"), QStringLiteral("totalRooms"));
0197     createItemFromIntValue(usageInfoItem, obj, i18n("Total Private Groups"), QStringLiteral("totalPrivateGroups"));
0198     createItemFromIntValue(usageInfoItem, obj, i18n("Total Direct Message Rooms"), QStringLiteral("totalDirect"));
0199     createItemFromIntValue(usageInfoItem, obj, i18n("Total Threads"), QStringLiteral("totalThreads"));
0200     createItemFromIntValue(usageInfoItem, obj, i18n("Total Users"), QStringLiteral("totalUsers"));
0201     createItemFromIntValue(usageInfoItem, obj, i18n("Total Discussions"), QStringLiteral("totalDiscussions"));
0202     createItemFromIntValue(usageInfoItem, obj, i18n("Total Omnichannel Rooms"), QStringLiteral("totalLivechat"));
0203 
0204     createItemFromIntValue(usageInfoItem, obj, i18n("Total Messages"), QStringLiteral("totalMessages"));
0205     createItemFromIntValue(usageInfoItem, obj, i18n("Total Messages in Channels"), QStringLiteral("totalChannelMessages"));
0206     createItemFromIntValue(usageInfoItem, obj, i18n("Total Messages in Private Groups"), QStringLiteral("totalPrivateGroupMessages"));
0207     createItemFromIntValue(usageInfoItem, obj, i18n("Total Messages in Direct Messages"), QStringLiteral("totalDirectMessages"));
0208     createItemFromIntValue(usageInfoItem, obj, i18n("Total Connected Users"), QStringLiteral("totalConnectedUsers"));
0209 }
0210 
0211 void AdministratorServerInfoWidget::createItemFromIntValue(QTreeWidgetItem *usageInfoItem,
0212                                                            const QJsonObject &obj,
0213                                                            const QString &label,
0214                                                            const QString &identifier)
0215 {
0216     const QJsonValue totalDirectMessages = obj.value(identifier);
0217     if (!totalDirectMessages.isUndefined()) {
0218         auto item = new QTreeWidgetItem(usageInfoItem);
0219         item->setText(0, label);
0220         item->setText(1, QString::number(totalDirectMessages.toInt()));
0221         usageInfoItem->addChild(item);
0222     }
0223 }
0224 
0225 void AdministratorServerInfoWidget::createItemDisplayFormat(QTreeWidgetItem *parentItem,
0226                                                             const QJsonObject &obj,
0227                                                             const QString &label,
0228                                                             const QString &identifier)
0229 {
0230     const QJsonValue objValue = obj.value(identifier);
0231     if (!objValue.isUndefined()) {
0232         auto item = new QTreeWidgetItem(parentItem);
0233         item->setText(0, label);
0234         item->setText(1, KIO::convertSize(objValue.toDouble()));
0235         item->addChild(item);
0236     }
0237 }
0238 
0239 void AdministratorServerInfoWidget::parseRuntimeInfo(QTreeWidgetItem *runtimeInfoItem, const QJsonObject &obj)
0240 {
0241     const QJsonObject runtimeObj = obj.value(QLatin1String("os")).toObject();
0242     createItemFromStringValue(runtimeInfoItem, runtimeObj, i18n("OS Release"), QStringLiteral("release"));
0243     createItemFromStringValue(runtimeInfoItem, runtimeObj, i18n("OS Type"), QStringLiteral("type"));
0244     createItemFromStringValue(runtimeInfoItem, runtimeObj, i18n("OS Platform"), QStringLiteral("platform"));
0245     createItemDisplayFormat(runtimeInfoItem, runtimeObj, i18n("OS Total Memory"), QStringLiteral("totalmem"));
0246     createItemDisplayFormat(runtimeInfoItem, runtimeObj, i18n("OS Free Memory"), QStringLiteral("freemem"));
0247 }
0248 
0249 void AdministratorServerInfoWidget::parseCommitInfo(QTreeWidgetItem *commitInfoItem)
0250 {
0251     {
0252         auto item = new QTreeWidgetItem(commitInfoItem);
0253         item->setText(0, i18n("Hash"));
0254         item->setText(1, mServerInfo.commitHash());
0255         item->addChild(item);
0256     }
0257     {
0258         auto item = new QTreeWidgetItem(commitInfoItem);
0259         item->setText(0, i18n("Branch"));
0260         item->setText(1, mServerInfo.commitBranch());
0261         item->addChild(item);
0262     }
0263     {
0264         auto item = new QTreeWidgetItem(commitInfoItem);
0265         item->setText(0, i18n("Tag"));
0266         item->setText(1, mServerInfo.commitTag());
0267         item->addChild(item);
0268     }
0269     {
0270         auto item = new QTreeWidgetItem(commitInfoItem);
0271         item->setText(0, i18n("Author"));
0272         item->setText(1, mServerInfo.commitAuthor());
0273         item->addChild(item);
0274     }
0275     {
0276         auto item = new QTreeWidgetItem(commitInfoItem);
0277         item->setText(0, i18n("Subject"));
0278         item->setText(1, mServerInfo.commitSubject());
0279         item->addChild(item);
0280     }
0281 }
0282 
0283 void AdministratorServerInfoWidget::parseBuildInfo(QTreeWidgetItem *buildInfoItem)
0284 {
0285     {
0286         auto item = new QTreeWidgetItem(buildInfoItem);
0287         item->setText(0, i18n("OS Release"));
0288         item->setText(1, mServerInfo.osRelease());
0289         item->addChild(item);
0290     }
0291     {
0292         auto item = new QTreeWidgetItem(buildInfoItem);
0293         item->setText(0, i18n("Node Version"));
0294         item->setText(1, mServerInfo.nodeVersion());
0295         item->addChild(item);
0296     }
0297     {
0298         auto item = new QTreeWidgetItem(buildInfoItem);
0299         item->setText(0, i18n("Arch"));
0300         item->setText(1, mServerInfo.arch());
0301         item->addChild(item);
0302     }
0303     {
0304         auto item = new QTreeWidgetItem(buildInfoItem);
0305         item->setText(0, i18n("OS Platform"));
0306         item->setText(1, mServerInfo.platform());
0307         item->addChild(item);
0308     }
0309 }
0310 
0311 void AdministratorServerInfoWidget::slotStatisticDone(const QJsonObject &obj)
0312 {
0313     delete mServerInfoItem;
0314     mServerInfoItem = new QTreeWidgetItem(mTreeWidget);
0315     mServerInfoItem->setText(0, i18n("Server Info"));
0316     parseServerInfo(mServerInfoItem, obj);
0317 
0318     delete mUsageInfoItem;
0319     mUsageInfoItem = new QTreeWidgetItem(mTreeWidget);
0320     mUsageInfoItem->setText(0, i18n("Usage"));
0321     parseUsageInfo(mUsageInfoItem, obj);
0322 
0323     delete mRuntimeInfoItem;
0324     mRuntimeInfoItem = new QTreeWidgetItem(mTreeWidget);
0325     mRuntimeInfoItem->setText(0, i18n("Runtime Environment"));
0326     parseRuntimeInfo(mRuntimeInfoItem, obj);
0327     mTreeWidget->expandAll();
0328     mTreeWidget->resizeColumnToContents(1);
0329     mTreeWidget->resizeColumnToContents(0);
0330 }
0331 
0332 void AdministratorServerInfoWidget::loadServerInfo()
0333 {
0334     auto commitItem = new QTreeWidgetItem(mTreeWidget);
0335     commitItem->setText(0, i18n("Commit"));
0336     parseCommitInfo(commitItem);
0337 
0338     auto buildItem = new QTreeWidgetItem(mTreeWidget);
0339     buildItem->setText(0, i18n("Build Environment"));
0340     parseBuildInfo(buildItem);
0341 }
0342 
0343 #include "moc_administratorserverinfowidget.cpp"