journalsfetchjob.cpp 7.39 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
149
150
151
152
153
154
155
156
157
    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 {
        qCWarning(ETESYNC_LOG) << "Unknown journal type. Cannot set collection mime type.";
    }

    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;
    }
158
159
160
161
    // 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);
    }
162
163
164
165
166
167
168
169
170
    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);
171
    collection.setParentCollection(mResourceCollection);
172
173
174

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

    mCollections.push_back(collection);
179
}