Verified Commit 39d39044 authored by Phobos D'thorga's avatar Phobos D'thorga 🐲
Browse files

* Additional changes to the QXmpp sub-system, further improving how the Small...

* Additional changes to the QXmpp sub-system, further improving how the Small World Deluxe client interacts with the XMPP server in question, with particular regard to message archiving.
parent 25ee8500
Pipeline #997 passed with stages
in 44 minutes and 35 seconds
......@@ -676,7 +676,7 @@ set(GALAXY_UI_CPP
src/gk_audio_encoding.cpp
src/gk_audio_decoding.cpp
src/gk_xmpp_client.cpp
src/gk_xmpp_chat.cpp
src/gk_xmpp_msg_handler.cpp
src/gk_cli.cpp
src/gk_modem.cpp
src/gk_frequency_list.cpp
......@@ -777,7 +777,7 @@ set(GALAXY_OBJ_HEADERS
src/gk_audio_encoding.hpp
src/gk_audio_decoding.hpp
src/gk_xmpp_client.hpp
src/gk_xmpp_chat.hpp
src/gk_xmpp_msg_handler.hpp
src/gk_cli.hpp
src/gk_modem.hpp
src/gk_frequency_list.hpp
......
......@@ -49,6 +49,7 @@
#include <QFile>
#include <QImage>
#include <QBuffer>
#include <QSysInfo>
#include <QMessageBox>
#include <QFileDialog>
#include <QImageReader>
......@@ -209,8 +210,12 @@ GkXmppClient::GkXmppClient(const GkUserConn &connection_details, QPointer<GekkoF
m_presence = std::make_shared<QXmppPresence>();
if (m_versionMgr) {
QSysInfo sysInfo;
m_versionMgr->setClientName(General::companyNameMin);
m_versionMgr->setClientVersion(General::appVersion);
m_versionMgr->setClientOs(sysInfo.prettyProductName());
gkEventLogger->publishEvent(tr("Client O/S configured as, \"%1\", with regard to XMPP settings.").arg(sysInfo.prettyProductName()), GkSeverity::Debug,
"", false, true, false, false, false);
QObject::connect(m_versionMgr.get(), SIGNAL(versionReceived(const QXmppVersionIq &)),
this, SLOT(versionReceivedSlot(const QXmppVersionIq &)));
}
......@@ -964,46 +969,84 @@ QString GkXmppClient::obtainAvatarFilePath()
}
/**
* @brief GkXmppClient::getArchivedMessages retrieves archived messages. For each received message, the
* @brief GkXmppClient::getArchivedMessagesBulk retrieves archived messages. For each received message, the
* `m_xmppMamMgr->archiveMessageReceived()` signal is emitted. Once all messages are received, the `m_xmppMamMgr->resultsRecieved()`
* signal is emitted. It returns a result set that can be used to page through the results. The number of results may
* be limited by the server.
* be limited by the server. This function in particular tries to receive all of the archived messages in question via
* a bulk manner, grabbing what it can and as much of it as possible, quite unlike its cousin function which is much
* more fine-tuned, GkXmppClient::getArchivedMessagesFine().
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
* @param to
* @param node
* @param jid
* @param from
* @param start
* @param end
* @param resultSetQuery
* @see GkXmppClient::getArchivedMessagesFine().
*/
void GkXmppClient::getArchivedMessages(const QString &to, const QString &node, const QString &jid, const QDateTime &start,
const QDateTime &end, const QXmppResultSetQuery &resultSetQuery)
void GkXmppClient::getArchivedMessagesBulk(const QString &to, const QString &node, const QString &from, const QDateTime &start,
const QDateTime &end, const QXmppResultSetQuery &resultSetQuery)
{
Q_UNUSED(node);
Q_UNUSED(end);
Q_UNUSED(start);
Q_UNUSED(end);
try {
if (!m_rosterList.isEmpty()) {
for (const auto &roster: m_rosterList) {
updateRecordedMsgHistory(roster.bareJid);
if (!start.isValid()) {
if (to == roster.bareJid && jid != m_connDetails.jid) {
if (!roster.messages.isEmpty()) {
const auto min_timestamp = calcMinTimestampForXmppMsgHistory(to, m_rosterList);
gkEventLogger->publishEvent(tr("Minimum date required for message archive retrieval is: %1").arg(QDateTime(min_timestamp).toString("dd MMM yyyy @ hh:mm:ss.zzz")),
GkSeverity::Debug, "", false, true, false, false);
m_xmppMamMgr->retrieveArchivedMessages(roster.bareJid, "", m_connDetails.jid, min_timestamp, QDateTime(), resultSetQuery);
return;
}
//
// It is VERY IMPORTANT that we execute this particular function!
updateRecordedMsgHistory(to);
updateRecordedMsgHistory(from);
break;
}
}
//
// Retrieve any archived messages from the given XMPP server as according to the specification, XEP-0313!
m_xmppMamMgr->retrieveArchivedMessages(to, "", from, QDateTime::currentDateTime().addDays(-5), QDateTime::currentDateTime(), resultSetQuery);
} catch (const std::exception &e) {
gkEventLogger->publishEvent(QString::fromStdString(e.what()), GkSeverity::Fatal, "", false, true, false, true, false);
}
return;
}
/**
* @brief GkXmppClient::getArchivedMessagesFine retrieves archived messages. For each received message, the
* `m_xmppMamMgr->archiveMessageReceived()` signal is emitted. Once all messages are received, the `m_xmppMamMgr->resultsRecieved()`
* signal is emitted. It returns a result set that can be used to page through the results. The number of results may
* be limited by the server. This particular function tries to selectively receive only a few archived messages at a
* time, quite unlike its cousin function, GkXmppClient::getArchivedMessagesBulk().
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
* @param to
* @param node
* @param from
* @param start
* @param end
* @param resultSetQuery
* @see GkXmppClient::getArchivedMessagesBulk().
*/
void GkXmppClient::getArchivedMessagesFine(const QString &to, const QString &node, const QString &from,
const QDateTime &start, const QDateTime &end,
const QXmppResultSetQuery &resultSetQuery)
{
Q_UNUSED(node);
Q_UNUSED(end);
try {
if (!m_rosterList.isEmpty()) {
updateRecordedMsgHistory(from); // It is VERY IMPORTANT that we execute this function!
QDateTime min_timestamp;
if (start.isValid()) {
min_timestamp = start;
} else {
min_timestamp = calcMinTimestampForXmppMsgHistory(from, m_rosterList);
}
}
m_xmppMamMgr->retrieveArchivedMessages(to, "", jid, QDateTime::currentDateTime().addDays(-28), QDateTime::currentDateTime(), resultSetQuery);
gkEventLogger->publishEvent(tr("Minimum date required for message archive retrieval is: %1").arg(QDateTime(min_timestamp).toString("dd MMM yyyy @ hh:mm:ss.zzz")),
GkSeverity::Debug, "", false, true, false, false);
//
// Retrieve any archived messages from the given XMPP server as according to the specification, XEP-0313!
m_xmppMamMgr->retrieveArchivedMessages(to, "", from, min_timestamp, QDateTime::currentDateTime(), resultSetQuery);
}
} catch (const std::exception &e) {
gkEventLogger->publishEvent(QString::fromStdString(e.what()), GkSeverity::Fatal, "", false, true, false, true, false);
}
......@@ -1499,7 +1542,7 @@ void GkXmppClient::updateClientVCardForm(const QString &first_name, const QStrin
void GkXmppClient::sendXmppMsg(const QXmppMessage &msg)
{
if (msg.isXmppStanza()) {
sendPacket(msg);
const bool msg_sent_succ = sendPacket(msg);
}
return;
......@@ -2179,6 +2222,9 @@ void GkXmppClient::archivedMessageReceived(const QString &queryId, const QXmppMe
}
}
//
// NOTE: DO NOT DELETE THIS WITHOUT analyzing the differences in the two code blocks CAREFULLY, firstly!
//
QList<GkXmppMamMsg> mam_msg_list;
for (auto iter = m_rosterList.begin(); iter != m_rosterList.end(); ++iter) {
if (iter->bareJid == message.to()) {
......@@ -2219,7 +2265,8 @@ void GkXmppClient::resultsRecieved(const QString &queryId, const QXmppResultSetR
/**
* @brief GkXmppClient::updateRecordedMsgHistory will update the recorded message history for all users on the variable,
* `m_rosterList`, and is designed to be run only just once.
* `m_rosterList`. Originally designed to be only executed once, it has now been refactored to be run multiple times as
* required.
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
* @param bareJid The user identity to update in question with regard to message history.
*/
......
......@@ -46,6 +46,7 @@
#include "src/file_io.hpp"
#include "src/gk_logger.hpp"
#include "src/gk_string_funcs.hpp"
#include "src/gk_xmpp_msg_handler.hpp"
#include "src/models/system/gk_network_ping_model.hpp"
#include <boost/exception/all.hpp>
#include <boost/filesystem.hpp>
......@@ -179,9 +180,12 @@ public slots:
//
// QXmppMamManager handling
void getArchivedMessages(const QString &to = QString(), const QString &node = QString(), const QString &jid = QString(),
const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime(),
const QXmppResultSetQuery &resultSetQuery = QXmppResultSetQuery());
void getArchivedMessagesBulk(const QString &to = QString(), const QString &node = QString(), const QString &from = QString(),
const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime(),
const QXmppResultSetQuery &resultSetQuery = QXmppResultSetQuery());
void getArchivedMessagesFine(const QString &to = QString(), const QString &node = QString(), const QString &from = QString(),
const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime(),
const QXmppResultSetQuery &resultSetQuery = QXmppResultSetQuery());
//
// Message handling
......
......@@ -39,8 +39,7 @@
**
****************************************************************************************************/
#include "src/gk_xmpp_chat.hpp"
#include <utility>
#include "src/gk_xmpp_msg_handler.hpp"
#include <exception>
#include <QMessageBox>
......@@ -57,37 +56,23 @@ using namespace Events;
using namespace Logging;
using namespace Network;
using namespace GkXmpp;
GkXmppChat::GkXmppChat(QPointer<GekkoFyre::GkXmppClient> xmppClient, const GekkoFyre::Network::GkXmpp::GkUserConn &connection_details,
QPointer<GekkoFyre::GkEventLogger> eventLogger, QObject *parent) : QThread(parent)
{
setParent(parent);
gkEventLogger = std::move(eventLogger);
//
// QXmpp and XMPP related
//
gkConnDetails = connection_details;
m_xmppClient = std::move(xmppClient);
start();
// Move event processing of GkXmppChat to this thread
QObject::moveToThread(this);
}
GkXmppChat::~GkXmppChat()
{
quit();
wait();
}
using namespace Security;
/**
* @brief GkXmppClient::run
* @brief GkXmppMsgHandler::GkXmppMsgHandler
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
* @param parent The parent object.
*/
void GkXmppChat::run()
GkXmppMsgHandler::GkXmppMsgHandler(QObject *parent) : QObject(parent)
{
exec();
try {
setParent(parent);
} catch (const std::exception &e) {
std::throw_with_nested(std::runtime_error(tr("An issue has occurred within the XMPP subsystem. Error: %1").arg(QString::fromStdString(e.what())).toStdString()));
}
return;
}
GkXmppMsgHandler::~GkXmppMsgHandler()
{}
......@@ -42,34 +42,21 @@
#pragma once
#include "src/defines.hpp"
#include "src/gk_logger.hpp"
#include "src/gk_xmpp_client.hpp"
#include <string>
#include <vector>
#include <QObject>
#include <memory>
#include <QString>
#include <QThread>
#include <QObject>
#include <QPointer>
#include <QCoreApplication>
namespace GekkoFyre {
class GkXmppChat : public QThread {
class GkXmppMsgHandler : public QObject {
Q_OBJECT
public:
explicit GkXmppChat(QPointer<GekkoFyre::GkXmppClient> xmppClient, const GekkoFyre::Network::GkXmpp::GkUserConn &connection_details,
QPointer<GekkoFyre::GkEventLogger> eventLogger, QObject *parent = nullptr);
~GkXmppChat() override;
void run() Q_DECL_OVERRIDE;
private:
QPointer<GekkoFyre::GkEventLogger> gkEventLogger;
//
// QXmpp and XMPP related
//
GekkoFyre::Network::GkXmpp::GkUserConn gkConnDetails;
QPointer<GekkoFyre::GkXmppClient> m_xmppClient;
explicit GkXmppMsgHandler(QObject *parent = nullptr);
~GkXmppMsgHandler() override;
};
};
......@@ -51,6 +51,8 @@
#include <QIcon>
#include <QPixmap>
#include <QKeyEvent>
#include <QFileDialog>
#include <QStandardPaths>
using namespace GekkoFyre;
using namespace GkAudioFramework;
......@@ -187,75 +189,91 @@ GkXmppMessageDialog::~GkXmppMessageDialog()
}
/**
* @brief GkXmppMessageDialog::on_toolButton_font_clicked
* @brief GkXmppMessageDialog::on_tableView_recv_msg_dlg_customContextMenuRequested
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
* @param pos
*/
void GkXmppMessageDialog::on_toolButton_font_clicked()
void GkXmppMessageDialog::on_tableView_recv_msg_dlg_customContextMenuRequested(const QPoint &pos)
{
return;
}
/**
* @brief GkXmppMessageDialog::on_toolButton_font_reset_clicked
* @brief GkXmppMessageDialog::on_textEdit_tx_msg_dialog_textChanged
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
*/
void GkXmppMessageDialog::on_toolButton_font_reset_clicked()
void GkXmppMessageDialog::on_textEdit_tx_msg_dialog_textChanged()
{
return;
}
/**
* @brief GkXmppMessageDialog::on_toolButton_insert_clicked
* @brief GkXmppMessageDialog::on_lineEdit_message_search_returnPressed
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
*/
void GkXmppMessageDialog::on_toolButton_insert_clicked()
void GkXmppMessageDialog::on_lineEdit_message_search_returnPressed()
{
return;
}
/**
* @brief GkXmppMessageDialog::on_toolButton_attach_file_clicked
* @brief GkXmppMessageDialog::on_toolButton_view_roster_triggered
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
* @param arg1
*/
void GkXmppMessageDialog::on_toolButton_attach_file_clicked()
void GkXmppMessageDialog::on_toolButton_view_roster_triggered(QAction *arg1)
{
QMessageBox::information(nullptr, tr("Information..."), tr("Apologies, but this function does not work yet."), QMessageBox::Ok);
return;
}
/**
* @brief GkXmppMessageDialog::on_toolButton_view_roster_clicked
* @brief GkXmppMessageDialog::on_toolButton_font_triggered
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
* @param arg1
*/
void GkXmppMessageDialog::on_toolButton_view_roster_clicked()
void GkXmppMessageDialog::on_toolButton_font_triggered(QAction *arg1)
{
QMessageBox::information(nullptr, tr("Information..."), tr("Apologies, but this function does not work yet."), QMessageBox::Ok);
return;
}
/**
* @brief GkXmppMessageDialog::on_tableView_recv_msg_dlg_customContextMenuRequested
* @brief GkXmppMessageDialog::on_toolButton_font_reset_triggered
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
* @param pos
* @param arg1
*/
void GkXmppMessageDialog::on_tableView_recv_msg_dlg_customContextMenuRequested(const QPoint &pos)
void GkXmppMessageDialog::on_toolButton_font_reset_triggered(QAction *arg1)
{
QMessageBox::information(nullptr, tr("Information..."), tr("Apologies, but this function does not work yet."), QMessageBox::Ok);
return;
}
/**
* @brief GkXmppMessageDialog::on_textEdit_tx_msg_dialog_textChanged
* @brief GkXmppMessageDialog::on_toolButton_insert_triggered
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
* @param arg1
*/
void GkXmppMessageDialog::on_textEdit_tx_msg_dialog_textChanged()
void GkXmppMessageDialog::on_toolButton_insert_triggered(QAction *arg1)
{
QMessageBox::information(nullptr, tr("Information..."), tr("Apologies, but this function does not work yet."), QMessageBox::Ok);
return;
}
/**
* @brief GkXmppMessageDialog::on_lineEdit_message_search_returnPressed
* @brief GkXmppMessageDialog::on_toolButton_attach_file_triggered
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
* @param arg1
*/
void GkXmppMessageDialog::on_lineEdit_message_search_returnPressed()
void GkXmppMessageDialog::on_toolButton_attach_file_triggered(QAction *arg1)
{
QString filePath = QFileDialog::getOpenFileName(nullptr, tr("Open Image"), QStandardPaths::writableLocation(QStandardPaths::PicturesLocation),
tr("All Image Files (*.png *.jpg *.jpeg *.jpe *.jfif *.exif *.bmp *.gif);;PNG (*.png);;JPEG (*.jpg *.jpeg *.jpe *.jfif *.exif);;Bitmap (*.bmp);;GIF (*.gif);;All Files (*.*)"));
if (!filePath.isEmpty()) {
// TODO: Implement this function!
return;
}
return;
}
......@@ -351,6 +369,7 @@ void GkXmppMessageDialog::submitMsgEnterKey()
const auto toMsg = createXmppMessageIq(bareJid, gkConnDetails.jid, plaintext);
if (toMsg.isXmppStanza()) {
emit sendXmppMsg(toMsg);
m_xmppClient->getArchivedMessagesFine(gkConnDetails.jid, QString(), bareJid);
}
}
}
......@@ -519,13 +538,13 @@ void GkXmppMessageDialog::procMamArchive(const bool &wipeExistingHistory, const
}
/**
* @brief GkXmppMessageDialog::getArchivedMessages
* @brief GkXmppMessageDialog::getArchivedMessagesBulk
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
*/
void GkXmppMessageDialog::getArchivedMessages()
{
for (const auto &bareJid: m_bareJids) {
m_xmppClient->getArchivedMessages(gkConnDetails.jid, QString(), bareJid); // Get archived messages sent by the Jid in question!
m_xmppClient->getArchivedMessagesBulk(gkConnDetails.jid, QString(), bareJid); // Get archived messages sent by the Jid in question!
}
return;
......
......@@ -86,14 +86,14 @@ public:
~GkXmppMessageDialog();
private slots:
void on_toolButton_font_clicked();
void on_toolButton_font_reset_clicked();
void on_toolButton_insert_clicked();
void on_toolButton_attach_file_clicked();
void on_toolButton_view_roster_clicked();
void on_tableView_recv_msg_dlg_customContextMenuRequested(const QPoint &pos);
void on_textEdit_tx_msg_dialog_textChanged();
void on_lineEdit_message_search_returnPressed();
void on_toolButton_view_roster_triggered(QAction *arg1);
void on_toolButton_font_triggered(QAction *arg1);
void on_toolButton_font_reset_triggered(QAction *arg1);
void on_toolButton_insert_triggered(QAction *arg1);
void on_toolButton_attach_file_triggered(QAction *arg1);
void updateInterface(const QStringList &bareJids);
void determineNickname();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment