File indexing completed on 2024-12-01 13:09:12

0001 /*
0002    SPDX-FileCopyrightText: 2023-2024 Laurent Montel <montel.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "managelocaldatabase.h"
0008 #include "chat/syncmessagesjob.h"
0009 #include "connection.h"
0010 #include "localdatabase/localdatabasemanager.h"
0011 #include "manageloadhistoryparsesyncmessagesutils.h"
0012 #include "model/messagesmodel.h"
0013 #include "rocketchataccount.h"
0014 #include "rocketchatbackend.h"
0015 #include "ruqola_loadhistory_debug.h"
0016 #include "ruqolaglobalconfig.h"
0017 
0018 #define USE_LOCALDATABASE 1
0019 ManageLocalDatabase::ManageLocalDatabase(RocketChatAccount *account, QObject *parent)
0020     : QObject{parent}
0021     , mRocketChatAccount(account)
0022 {
0023 }
0024 
0025 ManageLocalDatabase::~ManageLocalDatabase() = default;
0026 
0027 void ManageLocalDatabase::loadAccountSettings()
0028 {
0029     qCWarning(RUQOLA_LOAD_HISTORY_LOG) << " loadAccountSettings ";
0030     qint64 timeStamp = -1;
0031 #ifdef USE_LOCALDATABASE
0032     const QString accountName{mRocketChatAccount->accountName()};
0033     const QByteArray ba = mRocketChatAccount->localDatabaseManager()->jsonAccount(accountName);
0034     if (!ba.isEmpty()) {
0035         qCWarning(RUQOLA_LOAD_HISTORY_LOG) << "Account info load from database";
0036         mRocketChatAccount->ruqolaServerConfig()->loadAccountSettingsFromLocalDataBase(ba);
0037         timeStamp = mRocketChatAccount->localDatabaseManager()->timeStamp(accountName, QString(), GlobalDatabase::TimeStampType::AccountTimeStamp);
0038         qCWarning(RUQOLA_LOAD_HISTORY_LOG) << " timeStamp: " << timeStamp;
0039     }
0040 #endif
0041     mRocketChatAccount->rocketChatBackend()->loadPublicSettings(timeStamp);
0042 }
0043 
0044 void ManageLocalDatabase::syncMessage(const QString &roomId, qint64 lastSeenAt)
0045 {
0046     auto job = new RocketChatRestApi::SyncMessagesJob(this);
0047     job->setRoomId(roomId);
0048     job->setLastUpdate(QDateTime::fromMSecsSinceEpoch(lastSeenAt));
0049     mRocketChatAccount->restApi()->initializeRestApiJob(job);
0050     connect(job, &RocketChatRestApi::SyncMessagesJob::syncMessagesDone, this, &ManageLocalDatabase::slotSyncMessages);
0051     if (!job->start()) {
0052         qCWarning(RUQOLA_LOAD_HISTORY_LOG) << "Impossible to start SyncMessagesJob job";
0053     }
0054 }
0055 
0056 void ManageLocalDatabase::slotSyncMessages(const QJsonObject &obj, const QString &roomId)
0057 {
0058     qCWarning(RUQOLA_LOAD_HISTORY_LOG) << " roomId " << roomId << " obj " << obj;
0059     ManageLoadHistoryParseSyncMessagesUtils utils(mRocketChatAccount);
0060     utils.parse(obj);
0061 
0062     mRocketChatAccount->rocketChatBackend()->addMessagesFromLocalDataBase(utils.updatesMessages());
0063     mRocketChatAccount->rocketChatBackend()->removeMessageFromLocalDatabase(utils.deletedMessages(), roomId);
0064 }
0065 
0066 void ManageLocalDatabase::loadMessagesHistory(const ManageLocalDatabase::ManageLoadHistoryInfo &info)
0067 {
0068     Q_ASSERT(info.roomModel);
0069 
0070     qint64 endDateTime = info.roomModel->lastTimestamp();
0071     QJsonArray params;
0072     params.append(QJsonValue(info.roomId));
0073     // Load history
0074     if (info.initial || info.roomModel->isEmpty()) {
0075         if (RuqolaGlobalConfig::self()->storeMessageInDataBase()) {
0076 #ifdef USE_LOCALDATABASE
0077             const QString accountName{mRocketChatAccount->accountName()};
0078             const QVector<Message> lstMessages =
0079                 mRocketChatAccount->localDatabaseManager()->loadMessages(accountName, info.roomName, -1, -1, 50, mRocketChatAccount->emojiManager());
0080             qCDebug(RUQOLA_LOAD_HISTORY_LOG) << " accountName " << accountName << " roomID " << info.roomId << " info.roomName " << info.roomName
0081                                              << " number of message " << lstMessages.count();
0082             if (lstMessages.count() == 50) {
0083                 // Check on network if message change. => we need to add timestamp.
0084                 qCDebug(RUQOLA_LOAD_HISTORY_LOG) << " load from database + update messages";
0085                 mRocketChatAccount->rocketChatBackend()->addMessagesFromLocalDataBase(lstMessages);
0086                 // FIXME: don't use  info.lastSeenAt until we store room information in database
0087                 // We need to use last message timeStamp
0088                 const qint64 endDateTime = info.roomModel->lastTimestamp();
0089                 syncMessage(info.roomId, /*info.lastSeenAt*/ endDateTime);
0090                 return;
0091             } else {
0092                 // Load more from network.
0093                 // TODO load missing messages from network
0094                 qCDebug(RUQOLA_LOAD_HISTORY_LOG) << " load from network";
0095             }
0096 #endif
0097         }
0098 
0099         params.append(QJsonValue(QJsonValue::Null));
0100         params.append(QJsonValue(50)); // Max number of messages to load;
0101         QJsonObject dateObject;
0102         // qCDebug(RUQOLA_LOAD_HISTORY_LOG) << "roomModel->lastTimestamp()" << roomModel->lastTimestamp() << " ROOMID " << roomID;
0103         dateObject[QLatin1String("$date")] = QJsonValue(info.lastSeenAt);
0104         params.append(dateObject);
0105     } else if (info.timeStamp != 0) {
0106         params.append(info.timeStamp);
0107 
0108         QJsonObject dateObjectEnd;
0109         dateObjectEnd[QLatin1String("$date")] = QJsonValue(endDateTime);
0110 
0111         // qCDebug(RUQOLA_LOAD_HISTORY_LOG) << " QDATE TIME END" << QDateTime::fromMSecsSinceEpoch(endDateTime) << " START "  <<
0112         // QDateTime::fromMSecsSinceEpoch(startDateTime) << " ROOMID" << roomID;
0113         params.append(dateObjectEnd);
0114 
0115         params.append(QJsonValue(175)); // Max number of messages to load;
0116         qDebug() << " params" << params;
0117     } else {
0118         const qint64 startDateTime = info.roomModel->generateNewStartTimeStamp(endDateTime);
0119         int downloadMessage = 50;
0120         if (RuqolaGlobalConfig::self()->storeMessageInDataBase()) {
0121 #ifdef USE_LOCALDATABASE
0122             const QString accountName{mRocketChatAccount->accountName()};
0123             const QVector<Message> lstMessages =
0124                 mRocketChatAccount->localDatabaseManager()->loadMessages(accountName, info.roomName, -1, startDateTime, 50, mRocketChatAccount->emojiManager());
0125             qCDebug(RUQOLA_LOAD_HISTORY_LOG) << " accountName " << accountName << " roomID " << info.roomId << " info.roomName " << info.roomName
0126                                              << " number of message " << lstMessages.count();
0127             if (lstMessages.count() == downloadMessage) {
0128                 qCDebug(RUQOLA_LOAD_HISTORY_LOG) << " load from database";
0129                 mRocketChatAccount->rocketChatBackend()->addMessagesFromLocalDataBase(lstMessages);
0130                 return;
0131             } else if (!lstMessages.isEmpty()) {
0132                 mRocketChatAccount->rocketChatBackend()->addMessagesFromLocalDataBase(lstMessages);
0133                 downloadMessage -= lstMessages.count();
0134                 // Update lastTimeStamp
0135                 endDateTime = info.roomModel->lastTimestamp();
0136                 // TODO load diff messages => 50 - lstMessages.count()
0137             } else {
0138                 qCDebug(RUQOLA_LOAD_HISTORY_LOG) << " load from network";
0139             }
0140 
0141 #endif
0142         }
0143         QJsonObject dateObjectEnd;
0144         dateObjectEnd[QLatin1String("$date")] = QJsonValue(endDateTime);
0145 
0146         // qCDebug(RUQOLA_LOAD_HISTORY_LOG) << " QDATE TIME END" << QDateTime::fromMSecsSinceEpoch(endDateTime) << " START "  <<
0147         // QDateTime::fromMSecsSinceEpoch(startDateTime) << " ROOMID" << roomID;
0148         params.append(dateObjectEnd);
0149 
0150         params.append(QJsonValue(downloadMessage)); // Max number of messages to load;
0151 
0152         QJsonObject dateObjectStart;
0153         // qCDebug(RUQOLA_LOAD_HISTORY_LOG) << "roomModel->lastTimestamp()" << endDateTime << " ROOMID " << roomID;
0154         dateObjectStart[QLatin1String("$date")] = QJsonValue(startDateTime);
0155         params.append(std::move(dateObjectStart));
0156     }
0157     qCDebug(RUQOLA_LOAD_HISTORY_LOG) << " load history ddp:" << params;
0158     mRocketChatAccount->ddp()->loadHistory(params);
0159 }
0160 
0161 QDebug operator<<(QDebug d, const ManageLocalDatabase::ManageLoadHistoryInfo &t)
0162 {
0163     d.space() << "roomName" << t.roomName;
0164     d.space() << "roomID" << t.roomId;
0165     d.space() << "initial" << t.initial;
0166     d.space() << "timeStamp" << t.timeStamp;
0167     d.space() << "lastSeenAt" << t.lastSeenAt;
0168     d.space() << "roomModel" << t.roomModel;
0169     return d;
0170 }
0171 
0172 #include "moc_managelocaldatabase.cpp"