task_download_message_list.cpp 7.67 KB
Newer Older
1
/*
2
 * Copyright (C) 2014-2018 CZ.NIC
3 4 5 6 7 8 9 10
 *
 * 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
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 13 14 15 16 17 18 19 20 21 22 23
 * 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.
 */

24 25
#include <QThread>

26
#include "src/datovka_shared/log/log.h"
27
#include "src/datovka_shared/worker/pool.h" /* List with whole messages. */
28
#include "src/global.h"
29
#include "src/net/db_wrapper.h"
30
#include "src/net/isds_const.h"
31
#include "src/worker/emitter.h"
32
#include "src/worker/task_download_message.h"
33 34
#include "src/worker/task_download_message_list.h"
#include "src/sqlite/message_db_container.h"
35 36
#include "src/xml/xml_download_delivery_info.h"
#include "src/xml/xml_download_message_list.h"
37 38

TaskDownloadMessageList::TaskDownloadMessageList(IsdsSession::IsdsContext &ctx,
39
    NetLayer *netLayer, enum Messages::MessageType msgDirect,
40 41
    uint dmStatusFilter, uint dmOffset, uint dmLimit, WorkerPool *workPool,
    MessageListModel *messageModel, AccountListModel *accountModel,
42 43
    bool downloadCompleteMsgs, const QString &dbsLocation,
    bool saveZfo, bool isTestAccount)
44
    : m_result(DL_ERR),
45
    m_statusBarText(),
46 47 48 49 50
    m_ctx(ctx),
    m_netLayer(netLayer),
    m_msgDirect(msgDirect),
    m_dmStatusFilter(dmStatusFilter),
    m_dmOffset(dmOffset),
51 52 53 54 55
    m_dmLimit(dmLimit),
    m_workPool(workPool),
    m_messageModel(messageModel),
    m_accountModel(accountModel),
    m_downloadCompleteMsgs(downloadCompleteMsgs),
56 57 58
    m_dbsLocation(dbsLocation),
    m_saveZfo(saveZfo),
    m_isTestAccount(isTestAccount)
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
{
}

void TaskDownloadMessageList::run(void)
{
	if (Q_NULLPTR == m_netLayer) {
		Q_ASSERT(0);
		return;
	}

	if ((Messages::TYPE_RECEIVED != m_msgDirect)
	    && (Messages::TYPE_SENT != m_msgDirect)) {
		Q_ASSERT(0);
		return;
	}

	/* ### Worker task begin. ### */

77 78 79 80 81 82
	if ((Messages::TYPE_RECEIVED == m_msgDirect)) {
		logDebugLv0NL("%s", "---------RECEIVED MESSAGE LIST TASK------------");
	} else {
		logDebugLv0NL("%s", "------------SENT MESSAGE LIST TASK-------------");
	}
	logDebugLv0NL("Starting in thread '%p'", QThread::currentThreadId());
83

84
	m_result = downloadMessageList(m_ctx, m_netLayer,
85 86
	    m_msgDirect, m_dmStatusFilter, m_dmOffset, m_dmLimit,
	    m_workPool, m_messageModel, m_accountModel, m_downloadCompleteMsgs,
87
	    m_dbsLocation, m_saveZfo, m_isTestAccount, m_statusBarText);
88

89 90
	if (GlobInstcs::msgProcEmitterPtr != Q_NULLPTR) {
		emit GlobInstcs::msgProcEmitterPtr->downloadMessageListFinishedSignal(
91 92 93 94 95
		    m_ctx.username,
		    TaskDownloadMessageList::DL_SUCCESS == m_result,
		    m_statusBarText, m_ctx.last_isds_msg,
		    m_msgDirect == Messages::TYPE_RECEIVED);
	}
96

97 98 99 100
	logDebugLv0NL("Finished in thread '%p'", QThread::currentThreadId());
	logDebugLv0NL("%s", "-----------------------------------------------");

	/* ### Worker task end. ### */
101 102 103
}

enum TaskDownloadMessageList::Result TaskDownloadMessageList::downloadMessageList(
104
    IsdsSession::IsdsContext &ctx, NetLayer *netLayer,
105
    enum Messages::MessageType msgDirect, uint dmStatusFilter,
106 107 108
    uint dmOffset, uint dmLimit, WorkerPool *workPool,
    MessageListModel *messageModel, AccountListModel *accountModel,
    bool downloadCompleteMsgs, const QString &dbsLocation,
109
    bool saveZfo, bool isTestAccount, QString &statusBarText)
110
{
111 112
	if (Q_UNLIKELY((GlobInstcs::messageDbsPtr == Q_NULLPTR) ||
	        (GlobInstcs::acntMapPtr == Q_NULLPTR))) {
113
		logErrorNL("%s", "Internal error!");
114 115 116 117
		Q_ASSERT(0);
		return DL_ERR;
	}

118
	if (ctx.username.isEmpty()) {
119
		logErrorNL("%s", "Account user name missing!");
120 121 122 123
		Q_ASSERT(0);
		return DL_ERR;
	}

124 125 126
	logDebugLv1NL("Sending from account '%s'",
	    ctx.account_name.toUtf8().constData());

127 128 129 130
	QByteArray xmlDataOut;

	/* Send SOAP request */
	if (!netLayer->sendSoapRequest(ctx, MESSAGE_SERVICE,
131
	    Xml::xmlCreateGetMessageListSoapRequest(msgDirect,
132
	    dmStatusFilter, dmOffset, dmLimit), xmlDataOut)) {
133 134
		logErrorNL("ISDS returns: '%s'",
		    ctx.last_isds_msg.toUtf8().constData());
135 136 137 138
		return DL_ISDS_ERROR;
	}

	/* Parse SOAP response */
139 140 141 142 143
	QList<Isds::Envelope> envelopes = Xml::parseGetListOfMessagesResponse(
	    xmlDataOut, ctx.last_isds_msg);

	if (envelopes.isEmpty()) {
		return DL_SUCCESS;
144 145 146
	}

	/* Store data into db */
147
	QList<qint64> listOfNewMsgIds;
148
	QList<qint64> messageChangedStatusList;
149

150
	if (!DbWrapper::insertMessageListToDb(ctx.username,
151 152 153
	    (Messages::TYPE_RECEIVED == msgDirect) ? MessageDb::TYPE_RECEIVED
	        : MessageDb::TYPE_SENT,
	    envelopes, messageChangedStatusList, ctx.last_isds_msg,
154
	    listOfNewMsgIds)) {
155 156
		logErrorNL("Cannot insert message list into database: '%s'",
		    ctx.last_isds_msg.toUtf8().constData());
157 158 159
		return DL_DB_INS_ERR;
	}

160 161 162
	/* Store info text about new messages (for showing in status bar) */
	statusBarText = ctx.last_isds_msg;

163 164
	/*
	 * For sent message where message status was changed
165
	 * we should update delivery info as well.
166 167 168 169 170
	 */
	if (Messages::TYPE_SENT == msgDirect) {

		foreach (qint64 msgId, messageChangedStatusList) {

171 172 173 174 175
			/*
			 * Following functions don't have to check return values
			 * because they are complementary actions for message
			 * list download (delivery info is not important).
			 */
176

177 178
			/* Send delivery info SOAP request */
			netLayer->sendSoapRequest(ctx, MESSAGE_SERVICE,
179
			    Xml::xmlCreateSignedDeliveryInfoSoapRequest(msgId),
180
			    xmlDataOut);
181

182
			/* Parse delivery info SOAP response */
183 184 185
			QList<Isds::Event> events =
			    Xml::parseGetSignedMsgDeliveryInfoResponse(
			    xmlDataOut, ctx.last_isds_msg);
186

187
			/* Store delivery info into db */
188
			if (!events.isEmpty()) {
189
				DbWrapper::insertMesasgeDeliveryInfoToDb(
190
				    ctx.username, events, msgId,
191
				    ctx.last_isds_msg);
192 193 194 195
			}
		}
	}

196 197
	/* Update message counters in the account list */
	if (accountModel == Q_NULLPTR) {
198
		logWarningNL("%s", "Cannot access account model.");
199
	} else {
200
		MessageDb *msgDb = GlobInstcs::messageDbsPtr->accessMessageDb(
201
		    dbsLocation, ctx.username,
202
		    (*GlobInstcs::acntMapPtr)[ctx.username].storeToDisk());
203 204 205
		if (msgDb != Q_NULLPTR) {
			if (msgDirect == Messages::TYPE_RECEIVED) {
				accountModel->updateCounters(ctx.username,
206 207
				    msgDb->getNewMessageCountFromDb(MessageDb::TYPE_RECEIVED),
				    msgDb->getMessageCountFromDb(MessageDb::TYPE_RECEIVED),
208 209 210 211
				    -1, -1);
			} else {
				accountModel->updateCounters(ctx.username,
				    -1, -1,
212 213
				    msgDb->getNewMessageCountFromDb(MessageDb::TYPE_SENT),
				    msgDb->getMessageCountFromDb(MessageDb::TYPE_SENT));
214 215 216 217
			}
		}
	}

218 219
	/* Download new complete messages if this setting is enabled.
	 * (create and insert download compete message tasks to worker pool) */
220 221
	if (downloadCompleteMsgs) {
		if (messageModel == Q_NULLPTR) {
222
			logWarningNL("%s", "Cannot access message model.");
223
		}
224
		foreach (qint64 msgId, listOfNewMsgIds) {
225 226
			TaskDownloadMessage *task;
			task = new (std::nothrow) TaskDownloadMessage(ctx,
227
			    netLayer, msgId, msgDirect, messageModel,
228
			    saveZfo, isTestAccount);
229 230 231
			task->setAutoDelete(true);
			workPool->assignLo(task, WorkerPool::APPEND);
		}
232 233
	}

234 235
	logDebugLv1NL("%s", "Message list has been downloaded");

236 237
	return DL_SUCCESS;
}