entriesfetchjob.cpp 5.27 KB
Newer Older
1
/*
2
 * SPDX-FileCopyrightText: 2020 Shashwat Jolly <shashwat.jolly@gmail.com>
Laurent Montel's avatar
Laurent Montel committed
3
 *
4
 * SPDX-License-Identifier: GPL-2.0-or-later
5 6 7 8
 */

#include "entriesfetchjob.h"

9 10 11 12
#include <kcontacts/addressee.h>
#include <KCalendarCore/Event>
#include <KCalendarCore/Todo>
#include <AkonadiCore/CollectionModifyJob>
13
#include <QtConcurrent>
14

15
#include "etesync_debug.h"
16 17
#include "settings.h"

18 19 20
#define ITEMS_FETCH_BATCH_SIZE 50
#define ITEM_SIZE_INITIAL_TRY 2000

21
using namespace Akonadi;
22 23
using namespace EteSyncAPI;

24
EntriesFetchJob::EntriesFetchJob(const EteSyncClientState *clientState, const Akonadi::Collection &collection, EtebaseCollectionPtr etesyncCollection, QObject *parent)
Laurent Montel's avatar
Laurent Montel committed
25
    : KJob(parent)
26
    , mClientState(clientState)
Laurent Montel's avatar
Laurent Montel committed
27
    , mCollection(collection)
28
    , mEtesyncCollection(std::move(etesyncCollection))
29 30 31 32 33
{
}

void EntriesFetchJob::start()
{
34 35 36 37 38 39 40
    QFutureWatcher<void> *watcher = new QFutureWatcher<void>(this);
    connect(watcher, &QFutureWatcher<int>::finished, this, [this] {
        qCDebug(ETESYNC_LOG) << "emitResult from EntriesFetchJob";
        emitResult();
    });
    QFuture<void> fetchEntriesFuture = QtConcurrent::run(this, &EntriesFetchJob::fetchEntries);
    watcher->setFuture(fetchEntriesFuture);
41 42 43 44
}

void EntriesFetchJob::fetchEntries()
{
45 46 47 48 49 50 51 52 53
    if (!mClientState) {
        setError(UserDefinedError);
        setErrorText(QStringLiteral("EntriesFetchJob: EteSync client state is null"));
        return;
    }

    EtebaseAccount *account = mClientState->account();

    if (!account) {
54
        setError(UserDefinedError);
55
        setErrorText(QStringLiteral("EntriesFetchJob: Etebase account is null"));
56
        return;
57
    }
58 59

    if (!mEtesyncCollection) {
60
        setError(UserDefinedError);
61
        setErrorText(QStringLiteral("EntriesFetchJob: Etebase collection is null"));
62 63
        return;
    }
64

65
    EtebaseCollectionMetadataPtr metaData(etebase_collection_get_meta(mEtesyncCollection.get()));
66 67 68 69 70
    const QString type = QString::fromUtf8(etebase_collection_metadata_get_collection_type(metaData.get()));
    qCDebug(ETESYNC_LOG) << "Type:" << type;

    QString sToken = mCollection.remoteRevision();
    bool done = 0;
71
    EtebaseCollectionManagerPtr collectionManager(etebase_account_get_collection_manager(account));
72
    EtebaseItemManagerPtr itemManager(etebase_collection_manager_get_item_manager(collectionManager.get(), mEtesyncCollection.get()));
73 74 75 76

    while (!done) {
        EtebaseFetchOptionsPtr fetchOptions(etebase_fetch_options_new());
        etebase_fetch_options_set_stoken(fetchOptions.get(), sToken);
77
        etebase_fetch_options_set_limit(fetchOptions.get(), ITEMS_FETCH_BATCH_SIZE);
78 79 80 81 82 83 84 85 86 87

        EtebaseItemListResponsePtr itemList(etebase_item_manager_list(itemManager.get(), fetchOptions.get()));
        if (!itemList) {
            setError(int(etebase_error_get_code()));
            const char *err = etebase_error_get_message();
            setErrorText(QString::fromUtf8(err));
            return;
        }

        sToken = QString::fromUtf8(etebase_item_list_response_get_stoken(itemList.get()));
88

89
        done = etebase_item_list_response_is_done(itemList.get());
90

91 92 93 94
        uintptr_t dataLength = etebase_item_list_response_get_data_length(itemList.get());

        qCDebug(ETESYNC_LOG) << "Retrieved item list length" << dataLength;

Shashwat Jolly's avatar
Shashwat Jolly committed
95 96
        std::vector<const EtebaseItem *> etesyncItems(dataLength, nullptr);
        if (etebase_item_list_response_get_data(itemList.get(), etesyncItems.data())) {
Shashwat Jolly's avatar
Shashwat Jolly committed
97
            setError(int(etebase_error_get_code()));
98 99 100 101 102 103
            const char *err = etebase_error_get_message();
            setErrorText(QString::fromUtf8(err));
        }

        Item item;

Shashwat Jolly's avatar
Shashwat Jolly committed
104
        for (uintptr_t i = 0; i < dataLength; i++) {
105
            mClientState->saveEtebaseItemCache(etesyncItems[i], mEtesyncCollection.get());
106 107
            setupItem(item, etesyncItems[i], type);
        }
108
    }
109

110
    mCollection.setRemoteRevision(sToken);
111
}
112

113
void EntriesFetchJob::setupItem(Akonadi::Item &item, const EtebaseItem *etesyncItem, const QString &type)
114
{
115 116 117
    if (!etesyncItem) {
        qCDebug(ETESYNC_LOG) << "Unable to setup item - etesyncItem is null";
        return;
118
    }
119

120 121
    qCDebug(ETESYNC_LOG) << "Setting up item" << etebase_item_get_uid(etesyncItem);

122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    if (type == ETEBASE_COLLECTION_TYPE_ADDRESS_BOOK) {
        item.setMimeType(KContacts::Addressee::mimeType());
    } else if (type == ETEBASE_COLLECTION_TYPE_CALENDAR) {
        item.setMimeType(KCalendarCore::Event::eventMimeType());
    } else if (type == ETEBASE_COLLECTION_TYPE_TASKS) {
        item.setMimeType(KCalendarCore::Todo::todoMimeType());
    } else {
        qCWarning(ETESYNC_LOG) << "Unknown item type. Cannot set item mime type.";
        return;
    }

    const QString itemUid = QString::fromUtf8(etebase_item_get_uid(etesyncItem));
    item.setParentCollection(mCollection);
    item.setRemoteId(itemUid);

137 138 139
    QByteArray content(ITEM_SIZE_INITIAL_TRY, '\0');
    auto const len = etebase_item_get_content(etesyncItem, content.data(), ITEM_SIZE_INITIAL_TRY);
    if (len > ITEM_SIZE_INITIAL_TRY) {
140 141 142 143 144 145 146 147 148 149
        QByteArray content(len, '\0');
        etebase_item_get_content(etesyncItem, content.data(), len);
        item.setPayloadFromData(content);
        return;
    }
    item.setPayloadFromData(content);

    if (etebase_item_is_deleted(etesyncItem)) {
        mRemovedItems.push_back(item);
        return;
150
    }
151 152 153

    mItems.push_back(item);
}