journalsfetchjob.cpp 7.41 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 "journalsfetchjob.h"

9
#include <QtConcurrent>
10
11
12
13
14
15
#include <AkonadiCore/EntityDisplayAttribute>
#include <AkonadiCore/CollectionColorAttribute>
#include <kcontacts/addressee.h>
#include <kcontacts/contactgroup.h>
#include <KCalendarCore/Event>
#include <KCalendarCore/Todo>
16

17
18
#include "etesync_debug.h"

19
20
#define COLLECTIONS_FETCH_BATCH_SIZE 50

21
using namespace EteSyncAPI;
22
using namespace Akonadi;
23

24
JournalsFetchJob::JournalsFetchJob(const EtebaseAccount *account, const Akonadi::Collection &resourceCollection, const QString &cacheDir, QObject *parent)
Laurent Montel's avatar
Laurent Montel committed
25
    : KJob(parent)
26
27
    , mAccount(account)
    , mResourceCollection(resourceCollection)
28
    , mCacheDir(cacheDir)
29
30
31
32
33
{
}

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

void JournalsFetchJob::fetchJournals()
{
46
47
48
49
50
51
52
    if (!mAccount) {
        setError(UserDefinedError);
        setErrorText(QStringLiteral("EntriesFetchJob: Etebase account is empty"));
        return;
    }

    mSyncToken = mResourceCollection.remoteRevision();
53
    bool done = 0;
54
    EtebaseCollectionManagerPtr collectionManager(etebase_account_get_collection_manager(mAccount));
55
56

    while (!done) {
57
        EtebaseFetchOptionsPtr fetchOptions(etebase_fetch_options_new());
58
59
        etebase_fetch_options_set_stoken(fetchOptions.get(), mSyncToken);
        etebase_fetch_options_set_limit(fetchOptions.get(), COLLECTIONS_FETCH_BATCH_SIZE);
60
        etebase_fetch_options_set_prefetch(fetchOptions.get(), ETEBASE_PREFETCH_OPTION_MEDIUM);
61

62
        EtebaseCollectionListResponsePtr collectionList(etebase_collection_manager_list(collectionManager.get(), fetchOptions.get()));
63
64
65
66
67
68
69
        if (!collectionList) {
            setError(int(etebase_error_get_code()));
            const char *err = etebase_error_get_message();
            setErrorText(QString::fromUtf8(err));
            return;
        }

70
        mSyncToken = QString::fromUtf8(etebase_collection_list_response_get_stoken(collectionList.get()));
71
        done = etebase_collection_list_response_is_done(collectionList.get());
72

73
        uintptr_t dataLength = etebase_collection_list_response_get_data_length(collectionList.get());
74
75
76

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

Shashwat Jolly's avatar
Shashwat Jolly committed
77
78
        std::vector<const EtebaseCollection *> etesyncCollections(dataLength, nullptr);
        if (etebase_collection_list_response_get_data(collectionList.get(), etesyncCollections.data())) {
Shashwat Jolly's avatar
Shashwat Jolly committed
79
            setError(int(etebase_error_get_code()));
80
81
82
83
            const char *err = etebase_error_get_message();
            setErrorText(QString::fromUtf8(err));
        }

84
85
        Collection collection;

Shashwat Jolly's avatar
Shashwat Jolly committed
86
        for (uintptr_t i = 0; i < dataLength; i++) {
87
            saveEtebaseCollectionCache(collectionManager.get(), etesyncCollections[i], mCacheDir);
88
            setupCollection(collection, etesyncCollections[i]);
89
90
        }

Shashwat Jolly's avatar
Shashwat Jolly committed
91
        uintptr_t removedCollectionsLength = etebase_collection_list_response_get_removed_memberships_length(collectionList.get());
92
        qCDebug(ETESYNC_LOG) << "Removed collection membership list length" << removedCollectionsLength;
93
        if (removedCollectionsLength) {
Shashwat Jolly's avatar
Shashwat Jolly committed
94
95
            std::vector<const EtebaseRemovedCollection *> removedEtesyncCollections(removedCollectionsLength, nullptr);
            if (etebase_collection_list_response_get_removed_memberships(collectionList.get(), removedEtesyncCollections.data())) {
Shashwat Jolly's avatar
Shashwat Jolly committed
96
                setError(int(etebase_error_get_code()));
97
98
99
                const char *err = etebase_error_get_message();
                setErrorText(QString::fromUtf8(err));
            }
Shashwat Jolly's avatar
Shashwat Jolly committed
100
            for (uintptr_t i = 0; i < removedCollectionsLength; i++) {
101
102
103
                Collection collection;
                const QString journalUid = QString::fromUtf8(etebase_removed_collection_get_uid(removedEtesyncCollections[i]));
                collection.setRemoteId(journalUid);
104
105
                collection.setParentCollection(mResourceCollection);
                qCDebug(ETESYNC_LOG) << "Removed collection membership" << journalUid;
106
107
108
                mRemovedCollections.push_back(collection);
            }
        }
109
    }
110
111
}

112
void JournalsFetchJob::setupCollection(Akonadi::Collection &collection, const EtebaseCollection *etesyncCollection)
113
114
115
116
117
118
{
    if (!etesyncCollection) {
        qCDebug(ETESYNC_LOG) << "Unable to setup collection - etesyncCollection is null";
        return;
    }

119
120
    qCDebug(ETESYNC_LOG) << "Setting up collection" << etebase_collection_get_uid(etesyncCollection);

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
    EtebaseCollectionMetadataPtr metaData(etebase_collection_get_meta(etesyncCollection));

    const QString type = QString::fromUtf8(etebase_collection_metadata_get_collection_type(metaData.get()));

    qCDebug(ETESYNC_LOG) << "Type" << type;

    QStringList mimeTypes;

    auto attr = collection.attribute<EntityDisplayAttribute>(Collection::AddIfMissing);

    const QString displayName = QString::fromUtf8(etebase_collection_metadata_get_name(metaData.get()));

    qCDebug(ETESYNC_LOG) << "Name:" << displayName;

    if (type == ETEBASE_COLLECTION_TYPE_ADDRESS_BOOK) {
        mimeTypes.push_back(KContacts::Addressee::mimeType());
        mimeTypes.push_back(KContacts::ContactGroup::mimeType());
        attr->setDisplayName(displayName);
        attr->setIconName(QStringLiteral("view-pim-contacts"));
    } else if (type == ETEBASE_COLLECTION_TYPE_CALENDAR) {
        mimeTypes.push_back(KCalendarCore::Event::eventMimeType());
        attr->setDisplayName(displayName);
        attr->setIconName(QStringLiteral("view-calendar"));
    } else if (type == ETEBASE_COLLECTION_TYPE_TASKS) {
        mimeTypes.push_back(KCalendarCore::Todo::todoMimeType());
        attr->setDisplayName(displayName);
        attr->setIconName(QStringLiteral("view-pim-tasks"));
    } else {
149
150
        qCInfo(ETESYNC_LOG) << "Unknown collection type. Cannot set collection mime type.";
        return;
151
152
153
154
155
156
157
158
    }

    const QString journalUid = QString::fromUtf8(etebase_collection_get_uid(etesyncCollection));
    auto collectionColor = QString::fromUtf8(etebase_collection_metadata_get_color(metaData.get()));
    auto colorAttr = collection.attribute<Akonadi::CollectionColorAttribute>(Collection::AddIfMissing);
    if (collectionColor.isEmpty()) {
        collectionColor = ETESYNC_DEFAULT_COLLECTION_COLOR;
    }
159
160
161
162
    // Convert #RRGGBBAA strings to #AARRGGBB, which is required by Qt
    if (collectionColor.length() == 9) {
        collectionColor = collectionColor.left(1) + collectionColor.right(2) + collectionColor.mid(1, 6);
    }
163
164
165
166
167
168
169
170
171
    colorAttr->setColor(collectionColor);

    if (etebase_collection_get_access_level(etesyncCollection) == ETEBASE_COLLECTION_ACCESS_LEVEL_READ_ONLY) {
        collection.setRights(Collection::ReadOnly);
    }

    collection.setRemoteId(journalUid);
    collection.setName(journalUid);
    collection.setContentMimeTypes(mimeTypes);
172
    collection.setParentCollection(mResourceCollection);
173
174
175

    if (etebase_collection_is_deleted(etesyncCollection)) {
        mRemovedCollections.push_back(collection);
176
        return;
177
178
179
    }

    mCollections.push_back(collection);
180
}