Commit 4769aebf authored by Shashwat Jolly's avatar Shashwat Jolly
Browse files

Implement collection retrieval and setup

Changed JournalsFetchJob to use etebase for fetching collections. Collections are being setup to Akonadi collections in the same job.
Added relevant functions to etebaseadapter for the same.
Made root resource collection a class member as it is now passed to journalsfetchjob and used in slotCollectionsRetrieved().
parent 11857a92
......@@ -26,3 +26,8 @@ EtebaseAccountPtr etebase_account_login(const EtebaseClient *client, const QStri
{
return EtebaseAccountPtr(etebase_account_login(client, charArrFromQString(username), charArrFromQString(password)));
}
void etebase_fetch_options_set_stoken(EtebaseFetchOptions *fetch_options, const QString &stoken)
{
etebase_fetch_options_set_stoken(fetch_options, charArrFromQString(stoken));
}
......@@ -15,6 +15,12 @@
#define charArrFromQString(str) ((str).isNull() ? nullptr : qUtf8Printable((str)))
#define ETEBASE_COLLECTION_TYPE_CALENDAR QStringLiteral("etebase.vevent")
#define ETEBASE_COLLECTION_TYPE_ADDRESS_BOOK QStringLiteral("etebase.vcard")
#define ETEBASE_COLLECTION_TYPE_TASKS QStringLiteral("etebase.vtodo")
#define ETESYNC_DEFAULT_COLLECTION_COLOR QStringLiteral("#8BC34A")
struct EtebaseDeleter
{
void operator()(EtebaseClient *ptr)
......@@ -27,6 +33,26 @@ struct EtebaseDeleter
etebase_account_destroy(ptr);
}
void operator()(EtebaseFetchOptions *ptr)
{
etebase_fetch_options_destroy(ptr);
}
void operator()(EtebaseCollectionListResponse *ptr)
{
etebase_collection_list_response_destroy(ptr);
}
void operator()(EtebaseCollection *ptr)
{
etebase_collection_destroy(ptr);
}
void operator()(EtebaseCollectionMetadata *ptr)
{
etebase_collection_metadata_destroy(ptr);
}
void operator()(char *ptr)
{
std::free(ptr);
......@@ -35,6 +61,10 @@ struct EtebaseDeleter
using EtebaseClientPtr = std::unique_ptr<EtebaseClient, EtebaseDeleter>;
using EtebaseAccountPtr = std::unique_ptr<EtebaseAccount, EtebaseDeleter>;
using EtebaseFetchOptionsPtr = std::unique_ptr<EtebaseFetchOptions, EtebaseDeleter>;
using EtebaseCollectionListResponsePtr = std::unique_ptr<EtebaseCollectionListResponse, EtebaseDeleter>;
using EtebaseCollectionPtr = std::unique_ptr<EtebaseCollection, EtebaseDeleter>;
using EtebaseCollectionMetadataPtr = std::unique_ptr<EtebaseCollectionMetadata, EtebaseDeleter>;
using CharPtr = std::unique_ptr<char, EtebaseDeleter>;
QString QStringFromCharPtr(const CharPtr &str);
......@@ -43,4 +73,6 @@ EtebaseClientPtr etebase_client_new(const QString &client_name, const QString &s
EtebaseAccountPtr etebase_account_login(const EtebaseClient *client, const QString &username, const QString &password);
void etebase_fetch_options_set_stoken(EtebaseFetchOptions *fetch_options, const QString &stoken);
#endif
......@@ -33,6 +33,11 @@ public:
return mClient.get();
}
EtebaseAccount *account() const
{
return mAccountXXX.get();
}
QString derived() const
{
return mDerived;
......
......@@ -115,10 +115,11 @@ void EteSyncResource::retrieveCollections()
return;
}
mRootCollection = createRootCollection();
mJournalsCache.clear();
mClientState->refreshUserInfo();
auto job = new JournalsFetchJob(mClientState->client(), this);
auto job = new JournalsFetchJob(mClientState->account(), mRootCollection, this);
connect(job, &JournalsFetchJob::finished, this, &EteSyncResource::slotCollectionsRetrieved);
job->start();
}
......@@ -154,20 +155,19 @@ void EteSyncResource::slotCollectionsRetrieved(KJob *job)
handleError(job->error());
return;
}
EteSyncJournal **journals = qobject_cast<JournalsFetchJob *>(job)->journals();
Collection::List list;
const Collection &rootCollection = createRootCollection();
list.push_back(rootCollection);
for (EteSyncJournal **iter = journals; *iter; iter++) {
Collection collection;
collection.setParentCollection(rootCollection);
setupCollection(collection, *iter);
mJournalsCache[collection.remoteId()] = EteSyncJournalPtr(*iter);
list.push_back(collection);
}
mJournalsCacheUpdateTime = QDateTime::currentDateTime();
free(journals);
collectionsRetrieved(list);
qCDebug(ETESYNC_LOG) << "slotCollectionsRetrieved()";
QString sToken = qobject_cast<JournalsFetchJob *>(job)->syncToken();
mRootCollection.setRemoteRevision(sToken);
Collection::List collections = {mRootCollection};
collections.append(qobject_cast<JournalsFetchJob *>(job)->collections());
Collection::List removedCollections = qobject_cast<JournalsFetchJob *>(job)->removedCollections();
collectionsRetrievedIncremental(collections, removedCollections);
qCDebug(ETESYNC_LOG) << "Collections retrieval done";
}
/**
......
......@@ -78,6 +78,7 @@ private:
std::map<QString, EteSyncJournalPtr> mJournalsCache;
QDateTime mJournalsCacheUpdateTime;
bool mCredentialsRequired = false;
Akonadi::Collection mRootCollection;
ContactHandler::Ptr mContactHandler;
CalendarHandler::Ptr mCalendarHandler;
......
......@@ -7,19 +7,28 @@
#include "journalsfetchjob.h"
#include <QtConcurrent>
#include <AkonadiCore/EntityDisplayAttribute>
#include <AkonadiCore/CollectionColorAttribute>
#include <kcontacts/addressee.h>
#include <kcontacts/contactgroup.h>
#include <KCalendarCore/Event>
#include <KCalendarCore/Todo>
#include "etesync_debug.h"
using namespace EteSyncAPI;
using namespace Akonadi;
JournalsFetchJob::JournalsFetchJob(EteSync *client, QObject *parent)
JournalsFetchJob::JournalsFetchJob(const EtebaseAccount *account, const Akonadi::Collection &resourceCollection, QObject *parent)
: KJob(parent)
, mClient(client)
, mAccount(account)
, mResourceCollection(resourceCollection)
{
}
void JournalsFetchJob::start()
{
qCDebug(ETESYNC_LOG) << "Journals fetch start";
QFutureWatcher<void> *watcher = new QFutureWatcher<void>(this);
connect(watcher, &QFutureWatcher<void>::finished, this, [this] {
qCDebug(ETESYNC_LOG) << "emitResult from JournalsFetchJob";
......@@ -31,12 +40,117 @@ void JournalsFetchJob::start()
void JournalsFetchJob::fetchJournals()
{
EteSyncJournalManager *journalManager = etesync_journal_manager_new(mClient);
mJournals = etesync_journal_manager_list(journalManager);
if (!mJournals) {
setError(int(etesync_get_error_code()));
CharPtr err(etesync_get_error_message());
setErrorText(QStringFromCharPtr(err));
QString stoken;
bool done = 0;
EtebaseCollectionManager *collectionManager = etebase_account_get_collection_manager(mAccount);
while (!done) {
EtebaseFetchOptions *fetchOptions = etebase_fetch_options_new();
etebase_fetch_options_set_stoken(fetchOptions, stoken);
etebase_fetch_options_set_limit(fetchOptions, 30);
EtebaseCollectionListResponse *collectionList = etebase_collection_manager_list(collectionManager, fetchOptions);
if (!collectionList) {
setError(int(etebase_error_get_code()));
const char *err = etebase_error_get_message();
setErrorText(QString::fromUtf8(err));
return;
}
stoken = QString::fromUtf8(etebase_collection_list_response_get_stoken(collectionList));
done = etebase_collection_list_response_is_done(collectionList);
uintptr_t dataLength = etebase_collection_list_response_get_data_length(collectionList);
qCDebug(ETESYNC_LOG) << "Retrieved collection list length" << dataLength;
const EtebaseCollection *etesyncCollections[dataLength];
if (etebase_collection_list_response_get_data(collectionList, etesyncCollections)) {
setError(int(etesync_get_error_code()));
const char *err = etebase_error_get_message();
setErrorText(QString::fromUtf8(err));
}
for (int i = 0; i < dataLength; i++) {
setupCollection(etesyncCollections[i]);
}
int removedCollectionsLength = etebase_collection_list_response_get_removed_memberships_length(collectionList);
if (removedCollectionsLength) {
const EtebaseRemovedCollection *removedEtesyncCollections[removedCollectionsLength];
etebase_collection_list_response_get_removed_memberships(collectionList, removedEtesyncCollections);
for (int i = 0; i < removedCollectionsLength; i++) {
Collection collection;
const QString journalUid = QString::fromUtf8(etebase_removed_collection_get_uid(removedEtesyncCollections[i]));
collection.setRemoteId(journalUid);
mRemovedCollections.push_back(collection);
}
}
}
qCDebug(ETESYNC_LOG) << "Journals fetched";
}
void JournalsFetchJob::setupCollection(const EtebaseCollection *etesyncCollection)
{
qCDebug(ETESYNC_LOG) << "Setting up collection" << etebase_collection_get_uid(etesyncCollection);
if (!etesyncCollection) {
qCDebug(ETESYNC_LOG) << "Unable to setup collection - etesyncCollection is null";
return;
}
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;
Collection collection;
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;
}
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);
if (etebase_collection_is_deleted(etesyncCollection)) {
mRemovedCollections.push_back(collection);
}
collection.setParentCollection(mResourceCollection);
mCollections.push_back(collection);
}
......@@ -9,30 +9,47 @@
#include <KJob>
#include "etebaseadapter.h"
#include "etesyncadapter.h"
#include <AkonadiCore/Collection>
namespace EteSyncAPI {
class JournalsFetchJob : public KJob
{
Q_OBJECT
public:
explicit JournalsFetchJob(EteSync *client, QObject *parent = nullptr);
explicit JournalsFetchJob(const EtebaseAccount *account, const Akonadi::Collection &resourceCollection, QObject *parent = nullptr);
void start() override;
EteSyncJournal **journals() const
Akonadi::Collection::List collections() const
{
return mCollections;
}
Akonadi::Collection::List removedCollections() const
{
return mRemovedCollections;
}
QString syncToken() const
{
return mJournals;
return sToken;
}
protected:
void fetchJournals();
void setupCollection(const EtebaseCollection *etesyncCollection);
private:
EteSync *mClient = nullptr;
EteSyncJournal **mJournals = nullptr;
const EtebaseAccount *mAccount = nullptr;
Akonadi::Collection::List mCollections;
Akonadi::Collection::List mRemovedCollections;
const Akonadi::Collection mResourceCollection;
QString sToken;
};
} // namespace EteSyncAPI
} // namespace EteSyncAPI
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment