Commit dbe220c8 authored by Martin Straka's avatar Martin Straka

Added send message transaction

parent 41c5a343
......@@ -125,6 +125,7 @@ SOURCES += \
src/sqlite/message_db_container.cpp \
src/sqlite/message_db.cpp \
src/sqlite/zfo_db.cpp \
src/utility/rand_string.cpp \
src/worker/emitter.cpp \
src/worker/pool.cpp \
src/worker/task.cpp \
......@@ -184,6 +185,7 @@ HEADERS += \
src/sqlite/message_db_container.h \
src/sqlite/message_db.h \
src/sqlite/zfo_db.h \
src/utility/rand_string.h \
src/worker/emitter.h \
src/worker/pool.h \
src/worker/task.h \
......
......@@ -751,4 +751,11 @@ Item {
} // Item
} //StackLayout
} // Pane
Connections {
// Connection is activated when message sending was successful.
target: isds
onCloseSendPage: {
pageView.pop(StackView.Immediate)
}
} // Connections
} // Item
......@@ -34,6 +34,7 @@
#include "src/qml_interaction/message_envelope.h"
#include "src/settings.h"
#include "src/sqlite/zfo_db.h"
#include "src/utility/rand_string.h"
#include "src/worker/emitter.h"
#include "src/worker/task_change_password.h"
#include "src/worker/task_download_account_info.h"
......@@ -43,12 +44,12 @@
#include "src/worker/task_find_databox.h"
#include "src/worker/task_find_databox_fulltext.h"
#include "src/worker/task_keep_alive.h"
#include "src/worker/task_send_message.h"
#include "src/worker/task_send_sms.h"
IsdsWrapper::IsdsWrapper(QObject *parent)
: QObject(parent),
m_workPool(1)
m_workPool(1),
m_transactIds()
/*
* TODO -- To be able to run multiple therads in the pool a locking mechanism
* over libisds context structures must be implemented.
......@@ -80,9 +81,9 @@ IsdsWrapper::IsdsWrapper(QObject *parent)
SLOT(downloadMessageListFinished(QString, bool, QString, QString, bool)));
connect(&globMsgProcEmitter,
SIGNAL(sendMessageFinishedSignal(QString, QString, QString, qint64, bool, QString)),
SIGNAL(sendMessageFinishedSignal(QString, QString, QString, QString, qint64, bool, QString)),
this,
SLOT(sendMessageFinished(QString, QString, QString, qint64, bool, QString)));
SLOT(sendMessageFinished(QString, QString, QString, QString, qint64, bool, QString)));
}
IsdsWrapper::~IsdsWrapper(void)
......@@ -576,18 +577,38 @@ void IsdsWrapper::sendMessage(const QString &userName, qint64 dmID,
msg.setDmAttachmentSize(totalAttachmentSizeKBs);
const QList<DataboxModelEntry> dbList = databoxModel->allEntries();
/* List of unique identifiers. */
QStringList taskIdentifiers;
const QDateTime currentTime(QDateTime::currentDateTimeUtc());
/*
* Generate unique identifiers.
* These must be complete before creating first task.
*/
foreach (const DataboxModelEntry &db, dbList) {
taskIdentifiers.append(userName + "_" + db.dbID() + "_" +
currentTime.toString() + "_" +
RandString::generateRandomString(6));
}
m_transactIds = taskIdentifiers.toSet();
m_sentMsgResultList.clear();
emit statusBarTextChanged(tr("%1: sending message").arg(userName),
true, true);
/* Send message to all recipients */
foreach (const DataboxModelEntry &db, databoxModel->allEntries()) {
/* Send message to all recipients. */
for (int i = 0; i < dbList.size(); ++i) {
const DataboxModelEntry &db(dbList.at(i));
msg.setDbIDRecipient(db.dbID());
msg.setDmRecipient(db.dbName());
msg.setDmRecipientAddress(db.dbAddress());
TaskSendMessage *task;
task = new (std::nothrow) TaskSendMessage(
m_isdsSession.isdsCtxMap[userName], &m_netLayer,
&m_dbWrapper, msg, attachList, dmOVM, dmPublishOwnID);
&m_dbWrapper, msg, attachList, dmOVM, dmPublishOwnID,
taskIdentifiers.at(i));
task->setAutoDelete(true);
m_workPool.assignHi(task);
}
......@@ -767,22 +788,66 @@ void IsdsWrapper::downloadMessageListFinished(const QString &userName,
}
void IsdsWrapper::sendMessageFinished(const QString &userName,
const QString &dbIDRecipient, const QString &dmRecipient, qint64 msgId,
bool success, const QString &errTxt)
const QString &transactId, const QString &dbIDRecipient,
const QString &dmRecipient, qint64 msgId, bool success,
const QString &errTxt)
{
emit statusBarTextChanged(errTxt, false, true);
if (m_transactIds.end() == m_transactIds.find(transactId)) {
/* Nothing found. */
return;
}
/* Show result dialogue */
if (!success) {
Dialogues::errorMessage(Dialogues::CRITICAL,
tr("Send message error: %1").arg(userName),
tr("Failed to send mesasge to recipient '%1' (%2)'.").arg(dmRecipient).arg(dbIDRecipient),
tr("ISDS returns: %1").arg(errTxt));
} else {
/* Gather data. */
m_sentMsgResultList.append(TaskSendMessage::ResultData(
success, errTxt, dbIDRecipient, dmRecipient, msgId));
if (!m_transactIds.remove(transactId)) {
qDebug() << "Was not able to remove a transaction identifier from list of unfinished transactions.";
}
if (!m_transactIds.isEmpty()) {
/* Still has some pending transactions. */
return;
}
/* All transactions finished. */
int sentErrCnt = 0;
QString dialogueInfoText;
foreach (const TaskSendMessage::ResultData &rData, m_sentMsgResultList) {
if (rData.result) {
dialogueInfoText += tr(
"Message was successfully sent to "
"<i>'%1' (%2)</i> as message number "
"<i>%3</i>.").
arg(rData.dmRecipient).
arg(rData.dbIDRecipient).
arg(rData.dmId) + "<br/>";
} else {
++sentErrCnt;
dialogueInfoText += tr("Message was NOT sent to "
"<i>'%1' (%2)</i>. ISDS says: %3").
arg(rData.dmRecipient).
arg(rData.dbIDRecipient).
arg(rData.errInfo) + "<br/>";
}
}
m_sentMsgResultList.clear();
emit statusBarTextChanged(tr("Sending finished"), false, true);
if (0 == sentErrCnt) {
Dialogues::errorMessage(Dialogues::INFORMATION,
tr("Send message: %1").arg(userName),
tr("Message has sent to recipient '%1' (%2) as message id '%3'.").arg(dmRecipient).arg(dbIDRecipient).arg(msgId),
tr("ISDS returns: %1").arg(errTxt));
tr("Message was successfully sent to all recipients."),
dialogueInfoText);
emit closeSendPage();
} else {
Dialogues::errorMessage(Dialogues::WARNING,
tr("Send message: %1").arg(userName),
tr("Message was NOT sent to all recipients."),
dialogueInfoText);
}
}
......
......@@ -32,6 +32,7 @@
#include "src/net/isds_const.h"
#include "src/net/isds_session.h"
#include "src/worker/pool.h"
#include "src/worker/task_send_message.h"
class MessageListModel; /* Forward declaration. */
......@@ -274,6 +275,11 @@ public:
signals:
/*!
* @brief Send close send message page request to QML.
*/
void closeSendPage(void);
/*!
* @brief Send open QML input dialog request to QML.
*
......@@ -451,6 +457,7 @@ public slots:
* @brief Do post actions when send message finished.
*
* @param[in] userName Account username string.
* @param[in] transactId Unique transaction identifier.
* @param[in] dbIDRecipient Message recipient databox ID string.
* @param[in] dmRecipient Recipient full name.
* @param[in] msgId Send message ID.
......@@ -458,8 +465,9 @@ public slots:
* @param[in] errTxt Errot description.
*/
void sendMessageFinished(const QString &userName,
const QString &dbIDRecipient, const QString &dmRecipient,
qint64 msgId, bool success, const QString &errTxt);
const QString &transactId, const QString &dbIDRecipient,
const QString &dmRecipient, qint64 msgId, bool success,
const QString &errTxt);
/*!
* @brief Removed ISDS context of account. Run this slot
......@@ -578,6 +586,10 @@ private:
* @brief Worker pool instance.
*/
WorkerPool m_workPool;
/* Used to collect sending results. */
QSet<QString> m_transactIds; /*!< Temporary transaction identifiers. */
QList<TaskSendMessage::ResultData> m_sentMsgResultList; /*!< Send status list. */
};
#endif // _ISDS_WRAPPER_H_
/*
* Copyright (C) 2014-2017 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#include "src/utility/rand_string.h"
QString RandString::generateRandomString(int length)
{
static const QString possibleCharacters(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"!#$%&()*+,-.:=?@[]_{|}~");
QString randomString;
for (int i = 0; i < length; ++i) {
int index = qrand() % possibleCharacters.length();
QChar nextChar = possibleCharacters.at(index);
randomString.append(nextChar);
}
return randomString;
}
/*
* Copyright (C) 2014-2017 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#ifndef _RAND_STRING_H_
#define _RAND_STRING_H_
#include <QString>
/*
* This class provides helper random string methods.
*/
class RandString {
public:
/*!
* @brief Returns Randomly generated string composed of predefined
* characters.
*
* @param[in] length String length.
* @return Randomly generated string.
*/
static
QString generateRandomString(int length);
};
#endif /* _RAND_STRING_H_ */
......@@ -83,6 +83,7 @@ signals:
* @brief Do some actions when send message finished.
*
* @param[in] userName Account username string.
* @param[in] transactId Unique transaction identifier.
* @param[in] dbIDRecipient Message recipient databox ID string.
* @param[in] dmRecipient Recipient full name.
* @param[in] msgId Send message ID.
......@@ -90,8 +91,9 @@ signals:
* @param[in] errTxt Errot description.
*/
void sendMessageFinishedSignal(const QString &userName,
const QString &dbIDRecipient, const QString &dmRecipient,
qint64 msgId, bool success, const QString &errTxt);
const QString &transactId, const QString &dbIDRecipient,
const QString &dmRecipient, qint64 msgId, bool success,
const QString &errTxt);
};
/*!
......
......@@ -29,9 +29,29 @@
#include "src/worker/pool.h" /* List with whole messages. */
#include "src/worker/task_send_message.h"
TaskSendMessage::ResultData::ResultData(void)
: result(false),
errInfo(),
dbIDRecipient(),
dmRecipient(),
dmId(-1)
{
}
TaskSendMessage::ResultData::ResultData(bool res, const QString &eInfo,
const QString &recId, const QString &recName, qint64 mId)
: result(res),
errInfo(eInfo),
dbIDRecipient(recId),
dmRecipient(recName),
dmId(mId)
{
}
TaskSendMessage::TaskSendMessage(IsdsSession::IsdsContext &ctx,
NetLayer *netLayer, DbWrapper *dbWrapper, MsgEnvelope &msg,
QList<AttachmentData> &fileList, bool dmOVM, bool dmPublishOwnID)
QList<AttachmentData> &fileList, bool dmOVM, bool dmPublishOwnID,
const QString &transactId)
: m_result(DL_ERR),
m_msgID(0),
m_lastError(),
......@@ -41,7 +61,8 @@ TaskSendMessage::TaskSendMessage(IsdsSession::IsdsContext &ctx,
m_msg(msg),
m_fileList(fileList),
m_dmOVM(dmOVM),
m_dmPublishOwnID(dmPublishOwnID)
m_dmPublishOwnID(dmPublishOwnID),
m_transactId(transactId)
{
}
......@@ -68,7 +89,7 @@ void TaskSendMessage::run(void)
/* ### Worker task end. ### */
emit globMsgProcEmitter.sendMessageFinishedSignal(m_ctx.username,
m_msg.dbIDRecipient(), m_msg.dmRecipient(), m_msgID,
m_transactId, m_msg.dbIDRecipient(), m_msg.dmRecipient(), m_msgID,
TaskSendMessage::DL_SUCCESS == m_result, m_lastError);
logDebugLv0NL("Send message task finished in thread '%p'",
......
......@@ -46,6 +46,25 @@ public:
DL_ERR /*!< Other error. */
};
/*!
* @brief Gives more detailed information about sending outcome.
*/
class ResultData {
public:
/*!
* @brief Constructors.
*/
ResultData(void);
ResultData(bool res, const QString &eInfo,
const QString &recId, const QString &recName, qint64 mId);
bool result; /*!< Return state. */
QString errInfo; /*!< Error description. */
QString dbIDRecipient; /*!< Recipient identifier. */
QString dmRecipient; /*!< Recipient name. */
qint64 dmId; /*!< Sent message identifier. */
};
/*!
* @brief Constructor.
*
......@@ -56,11 +75,12 @@ public:
* @param[in] fileList List of files.
* @param[in] dmOVM True if send message as OVM.
* @param[in] dmPublishOwnID True if add sender name to message.
* @param[in] transactId Unique transaction identifier.
*/
explicit TaskSendMessage(IsdsSession::IsdsContext &ctx,
NetLayer *netLayer, DbWrapper *dbWrapper,
MsgEnvelope &msg, QList<AttachmentData> &fileList,
bool dmOVM, bool dmPublishOwnID);
bool dmOVM, bool dmPublishOwnID, const QString &transactId);
/*!
* @brief Performs actual send message.
......@@ -106,6 +126,7 @@ private:
QList<AttachmentData> m_fileList; /*!< List of files. */
bool m_dmOVM; /*!< True if send message as OVM. */
bool m_dmPublishOwnID; /*!< True if add sender name to message. */
const QString m_transactId; /*!< Unique transaction identifier. */
};
#endif /* _TASK_SEND_MESSAGE_H_ */
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