File: retrieveitemtask.cpp

package info (click to toggle)
kdepim-runtime 4%3A24.12.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 24,012 kB
  • sloc: cpp: 90,562; xml: 1,020; javascript: 60; sh: 58; makefile: 13
file content (119 lines) | stat: -rw-r--r-- 3,659 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
    SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
    SPDX-FileContributor: Kevin Ottens <kevin@kdab.com>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#include "retrieveitemtask.h"
#include "messagehelper.h"

#include "imapresource_debug.h"

#include <KLocalizedString>

#include <Akonadi/MessageFlags>
#include <KIMAP/SelectJob>
#include <KIMAP/Session>

RetrieveItemTask::RetrieveItemTask(const ResourceStateInterface::Ptr &resource, QObject *parent)
    : ResourceTask(CancelIfNoSession, resource, parent)
{
}

RetrieveItemTask::~RetrieveItemTask() = default;

void RetrieveItemTask::doStart(KIMAP::Session *session)
{
    m_session = session;

    const QString mailBox = mailBoxForCollection(item().parentCollection());
    m_uid = item().remoteId().toLongLong();

    if (m_uid <= 0) {
        qCWarning(IMAPRESOURCE_LOG) << "Remote id is " << item().remoteId();
        cancelTask(i18n("Remote id is empty or invalid"));
        return;
    }

    if (session->selectedMailBox() != mailBox) {
        auto select = new KIMAP::SelectJob(m_session);
        select->setMailBox(mailBox);
        connect(select, &KJob::result, this, &RetrieveItemTask::onSelectDone);
        select->start();
    } else {
        triggerFetchJob();
    }
}

void RetrieveItemTask::onSelectDone(KJob *job)
{
    if (job->error()) {
        cancelTask(job->errorString());
    } else {
        triggerFetchJob();
    }
}

void RetrieveItemTask::triggerFetchJob()
{
    auto fetch = new KIMAP::FetchJob(m_session);
    KIMAP::FetchJob::FetchScope scope;
    fetch->setUidBased(true);
    fetch->setSequenceSet(KIMAP::ImapSet(m_uid));
    scope.parts.clear(); // = parts.toList();
    scope.mode = KIMAP::FetchJob::FetchScope::Content;
    fetch->setScope(scope);
    connect(fetch, &KIMAP::FetchJob::messagesAvailable, this, &RetrieveItemTask::onMessagesReceived);
    connect(fetch, &KJob::result, this, &RetrieveItemTask::onContentFetchDone);
    fetch->start();
}

void RetrieveItemTask::onMessagesReceived(const QMap<qint64, KIMAP::Message> &messages)
{
    auto fetch = qobject_cast<KIMAP::FetchJob *>(sender());
    Q_ASSERT(fetch != nullptr);
    if (messages.size() == 0) {
        qCDebug(IMAPRESOURCE_LOG) << "Requested message does not exist on the server anymore";
        cancelTask(i18n("No message retrieved, failed to read the message."));
        return;
    }

    Akonadi::Item i = item();

    qCDebug(IMAPRESOURCE_LOG) << "MESSAGE from Imap server" << item().remoteId();
    Q_ASSERT(item().isValid());

    const auto message = messages.cbegin();
    const qint64 number = message->uid;
    bool ok;
    const Akonadi::Item remoteItem =
        resourceState()->messageHelper()->createItemFromMessage(message->message, number, 0, message->attributes, {}, fetch->scope(), ok);
    if (!ok) {
        qCWarning(IMAPRESOURCE_LOG) << "Failed to retrieve message " << number;
        cancelTask(i18n("No message retrieved, failed to read the message."));
        return;
    }
    i.setMimeType(remoteItem.mimeType());
    i.setPayload(remoteItem.payload<KMime::Message::Ptr>());
    const auto flags{remoteItem.flags()};
    for (const QByteArray &flag : flags) {
        i.setFlag(flag);
    }

    qCDebug(IMAPRESOURCE_LOG) << "Has Payload: " << i.hasPayload();

    m_messageReceived = true;
    itemRetrieved(i);
}

void RetrieveItemTask::onContentFetchDone(KJob *job)
{
    if (job->error()) {
        cancelTask(job->errorString());
    } else if (!m_messageReceived) {
        cancelTask(i18n("No message retrieved, server reply was empty."));
    }
}

#include "moc_retrieveitemtask.cpp"