Commit fa71700c authored by Shashwat Jolly's avatar Shashwat Jolly

Implement retrieveCollections()

This makes address books show up in Kontact
parent 6e7768e6
...@@ -4,8 +4,9 @@ set(etesyncresource_SRCS ...@@ -4,8 +4,9 @@ set(etesyncresource_SRCS
ecm_qt_declare_logging_category(etesyncresource_SRCS ecm_qt_declare_logging_category(etesyncresource_SRCS
HEADER debug.h HEADER debug.h
IDENTIFIER log_etesyncresource IDENTIFIER ETESYNC_LOG
CATEGORY_NAME log_etesyncresource CATEGORY_NAME org.kde.pim.google
DESCRIPTION "resource etesync (kdepim-runtime)"
) )
kconfig_add_kcfg_files(etesyncresource_SRCS kconfig_add_kcfg_files(etesyncresource_SRCS
...@@ -34,6 +35,7 @@ target_link_libraries(akonadi_etesync_resource ...@@ -34,6 +35,7 @@ target_link_libraries(akonadi_etesync_resource
Qt5::DBus Qt5::DBus
KF5::AkonadiAgentBase KF5::AkonadiAgentBase
KF5::ConfigCore KF5::ConfigCore
KF5::Contacts
) )
install(TARGETS akonadi_etesync_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS akonadi_etesync_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
......
#include <etesync/etesync.h>
QString QStringFromCharArr(const char *str) { return QLatin1String(str); }
const char *charArrFromQString(const QString &str)
{
QByteArray ba = str.toLocal8Bit();
const char *ret = qstrdup(ba.data());
return ret;
}
QString etesync_auth_get_token(const EteSync *etesync, const QString &username,
const QString &password)
{
const char *uname = charArrFromQString(username);
const char *pass = charArrFromQString(password);
char *token = etesync_auth_get_token(etesync, uname, pass);
return QStringFromCharArr(token);
}
qint32 etesync_auth_invalidate_token(const EteSync *etesync,
const QString &token)
{
const char *tok = charArrFromQString(token);
return etesync_auth_invalidate_token(etesync, tok);
}
EteSyncCollectionInfo *etesync_collection_info_new(const QString &col_type,
const QString &display_name,
const QString &description,
qint32 color)
{
const char *colType = charArrFromQString(col_type);
const char *displayName = charArrFromQString(display_name);
const char *desc = charArrFromQString(description);
return etesync_collection_info_new(colType, displayName, desc, color);
}
QString etesync_crypto_derive_key(const EteSync *_etesync, const QString &salt,
const QString &password)
{
const char *s = charArrFromQString(salt);
const char *pass = charArrFromQString(password);
char *ret = etesync_crypto_derive_key(_etesync, s, pass);
return QStringFromCharArr(ret);
}
EteSyncEntry *etesync_entry_from_sync_entry(const EteSyncCryptoManager *crypto_manager,
const EteSyncSyncEntry *sync_entry,
const QString &prev_uid)
{
const char *prevUid = charArrFromQString(prev_uid);
return etesync_entry_from_sync_entry(crypto_manager, sync_entry, prevUid);
}
EteSyncSyncEntry *etesync_entry_get_sync_entry(const EteSyncEntry *entry,
const EteSyncCryptoManager *crypto_manager,
const QString &prev_uid)
{
const char *prevUid = charArrFromQString(prev_uid);
return etesync_entry_get_sync_entry(entry, crypto_manager, prevUid);
}
qint32 etesync_entry_manager_create(const EteSyncEntryManager *entry_manager,
const EteSyncEntry *const *entries,
const QString &prev_uid)
{
const char *prevUid = charArrFromQString(prev_uid);
return etesync_entry_manager_create(entry_manager, entries, prevUid);
}
EteSyncEntry **etesync_entry_manager_list(const EteSyncEntryManager *entry_manager,
const QString &prev_uid, uintptr_t limit)
{
const char *prevUid = charArrFromQString(prev_uid);
return etesync_entry_manager_list(entry_manager, prevUid, limit);
}
EteSyncEntryManager *etesync_entry_manager_new(const EteSync *etesync,
const QString &journal_uid)
{
const char *journalUid = charArrFromQString(journal_uid);
return etesync_entry_manager_new(etesync, journalUid);
}
EteSyncCryptoManager *etesync_journal_get_crypto_manager(const EteSyncJournal *journal,
const QString &key,
const EteSyncAsymmetricKeyPair *keypair)
{
const char *k = charArrFromQString(key);
return etesync_journal_get_crypto_manager(journal, k, keypair);
}
EteSyncJournal *etesync_journal_manager_fetch(const EteSyncJournalManager *journal_manager,
const QString &journal_uid)
{
const char *journalUid = charArrFromQString(journal_uid);
return etesync_journal_manager_fetch(journal_manager, journalUid);
}
EteSyncJournal *etesync_journal_new(const QString &uid, uint8_t version)
{
const char *id = charArrFromQString(uid);
return etesync_journal_new(id, version);
}
EteSync *etesync_new(const QString &client_name, const QString &server_url)
{
const char *clientName = charArrFromQString(client_name);
const char *serverUrl = charArrFromQString(server_url);
return etesync_new(clientName, serverUrl);
}
void etesync_set_auth_token(EteSync *etesync, const QString &token)
{
const char *tok = charArrFromQString(token);
etesync_set_auth_token(etesync, tok);
}
EteSyncSyncEntry *etesync_sync_entry_new(const QString &action,
const QString &content)
{
const char *act = charArrFromQString(action);
const char *cont = charArrFromQString(content);
return etesync_sync_entry_new(act, cont);
}
EteSyncCryptoManager *etesync_user_info_get_crypto_manager(const EteSyncUserInfo *user_info,
const QString &key)
{
const char *k = charArrFromQString(key);
return etesync_user_info_get_crypto_manager(user_info, k);
}
EteSyncUserInfo *etesync_user_info_manager_fetch(const EteSyncUserInfoManager *user_info_manager,
const QString &owner)
{
const char *own = charArrFromQString(owner);
return etesync_user_info_manager_fetch(user_info_manager, own);
}
...@@ -16,98 +16,156 @@ ...@@ -16,98 +16,156 @@
*/ */
#include "etesyncresource.h" #include "etesyncresource.h"
#include "etesync/etesync.h"
#include <QDBusConnection>
#include "debug.h" #include "debug.h"
#include "etesyncadapter.h"
#include "settings.h" #include "settings.h"
#include "settingsadaptor.h" #include "settingsadaptor.h"
#include <QDBusConnection>
using namespace Akonadi; using namespace Akonadi;
etesyncResource::etesyncResource(const QString &id) : ResourceBase(id) { etesyncResource::etesyncResource(const QString& id)
new SettingsAdaptor(Settings::self()); : ResourceBase(id)
QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), {
Settings::self(), new SettingsAdaptor(Settings::self());
QDBusConnection::ExportAdaptors); QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"),
Settings::self(),
QDBusConnection::ExportAdaptors);
// TODO: you can put any resource specific initialization code here. QLoggingCategory::setFilterRules(QStringLiteral("ETESYNC_LOG.debug = true"));
QLoggingCategory::setFilterRules( qCDebug(ETESYNC_LOG) << "Resource started";
QStringLiteral("log_etesyncresource.debug = true"));
qCDebug(log_etesyncresource) << "Resource started";
} }
etesyncResource::~etesyncResource() {} etesyncResource::~etesyncResource() {}
void etesyncResource::retrieveCollections() { void etesyncResource::retrieveCollections()
// TODO: this method is called when Akonadi wants to have all the {
// collections your resource provides. EteSyncJournal** journals = etesync_journal_manager_list(journalManager);
// Be sure to set the remote ID and the content MIME types
Collection::List list;
for (EteSyncJournal** iter = journals; *iter; iter++) {
EteSyncJournal* journal = *iter;
EteSyncCryptoManager* cryptoManager = etesync_journal_get_crypto_manager(journal, derived, keypair);
EteSyncCollectionInfo* info = etesync_journal_get_info(journal, cryptoManager);
if (QStringFromCharArr(etesync_collection_info_get_type(info)) != QStringLiteral("ADDRESS_BOOK"))
continue;
Collection c;
c.setParentCollection(Collection::root());
c.setRemoteId(QStringFromCharArr(etesync_journal_get_uid(journal)));
c.setName(QStringFromCharArr(etesync_collection_info_get_display_name(info)));
QStringList mimeTypes;
mimeTypes << KContacts::Addressee::mimeType();
c.setContentMimeTypes(mimeTypes);
list << c;
etesync_collection_info_destroy(info);
etesync_crypto_manager_destroy(cryptoManager);
etesync_journal_destroy(journal);
}
free(journals);
collectionsRetrieved(list);
} }
void etesyncResource::retrieveItems(const Akonadi::Collection &collection) { void etesyncResource::retrieveItems(const Akonadi::Collection& collection)
// TODO: this method is called when Akonadi wants to know about all the {
// items in the given collection. You can but don't have to provide all the
// data for each item, remote ID and MIME type are enough at this stage.
// Depending on how your resource accesses the data, there are several
// different ways to tell Akonadi when you are done.
} }
bool etesyncResource::retrieveItem(const Akonadi::Item &item, bool etesyncResource::retrieveItem(const Akonadi::Item& item,
const QSet<QByteArray> &parts) { const QSet<QByteArray>& parts)
// TODO: this method is called when Akonadi wants more data for a given item. {
// You can only provide the parts that have been requested but you are allowed // TODO: this method is called when Akonadi wants more data for a given
// to provide all in one go // item. You can only provide the parts that have been requested but you are
// allowed to provide all in one go
return true; return true;
} }
void etesyncResource::aboutToQuit() { void etesyncResource::aboutToQuit()
// TODO: any cleanup you need to do while there is still an active {
// event loop. The resource will terminate after this method returns // TODO: any cleanup you need to do while there is still an active
// event loop. The resource will terminate after this method returns
} }
void etesyncResource::configure(WId windowId) { void etesyncResource::configure(WId windowId)
// TODO: this method is usually called when a new resource is being {
// added to the Akonadi setup. You can do any kind of user interaction here, // TODO: this method is usually called when a new resource is being
// e.g. showing dialogs. // added to the Akonadi setup. You can do any kind of user interaction here,
// The given window ID is usually useful to get the correct // e.g. showing dialogs.
// "on top of parent" behavior if the running window manager applies any kind // The given window ID is usually useful to get the correct
// of focus stealing prevention technique // "on top of parent" behavior if the running window manager applies any
// // kind of focus stealing prevention technique
// If the configuration dialog has been accepted by the user by clicking Ok, //
// the signal configurationDialogAccepted() has to be emitted, otherwise, if // If the configuration dialog has been accepted by the user by clicking Ok,
// the user canceled the dialog, configurationDialogRejected() has to be // the signal configurationDialogAccepted() has to be emitted, otherwise, if
// emitted. // the user canceled the dialog, configurationDialogRejected() has to be
// emitted.
/// TODO: Implement config dialog and move settings to kcfg
QString username = QStringLiteral("test@localhost");
QString password = QStringLiteral("testetesync");
QString encryptionPassword = QStringLiteral("etesync");
QString serverUrl = QStringLiteral("http://192.168.29.145:9966");
// Initialise EteSync client state
etesync = etesync_new(QStringLiteral("Akonadi EteSync Resource"), serverUrl);
derived = etesync_crypto_derive_key(etesync, username, encryptionPassword);
QString token = etesync_auth_get_token(etesync, username, password);
etesync_set_auth_token(etesync, token);
journalManager = etesync_journal_manager_new(etesync);
// Get user keypair
EteSyncUserInfoManager* userInfoManager = etesync_user_info_manager_new(etesync);
EteSyncUserInfo* userInfo = etesync_user_info_manager_fetch(userInfoManager, username);
EteSyncCryptoManager* userInfoCryptoManager = etesync_user_info_get_crypto_manager(userInfo, derived);
keypair = etesync_user_info_get_keypair(userInfo, userInfoCryptoManager);
etesync_crypto_manager_destroy(userInfoCryptoManager);
etesync_user_info_destroy(userInfo);
etesync_user_info_manager_destroy(userInfoManager);
synchronize();
} }
void etesyncResource::itemAdded(const Akonadi::Item &item, void etesyncResource::itemAdded(const Akonadi::Item& item,
const Akonadi::Collection &collection) { const Akonadi::Collection& collection)
// TODO: this method is called when somebody else, e.g. a client application, {
// has created an item in a collection managed by your resource. // TODO: this method is called when somebody else, e.g. a client
// application, has created an item in a collection managed by your
// resource.
// NOTE: There is an equivalent method for collections, but it isn't part // NOTE: There is an equivalent method for collections, but it isn't part
// of this template code to keep it simple // of this template code to keep it simple
} }
void etesyncResource::itemChanged(const Akonadi::Item &item, void etesyncResource::itemChanged(const Akonadi::Item& item,
const QSet<QByteArray> &parts) { const QSet<QByteArray>& parts)
// TODO: this method is called when somebody else, e.g. a client application, {
// has changed an item managed by your resource. // TODO: this method is called when somebody else, e.g. a client
// application, has changed an item managed by your resource.
// NOTE: There is an equivalent method for collections, but it isn't part // NOTE: There is an equivalent method for collections, but it isn't part
// of this template code to keep it simple // of this template code to keep it simple
} }
void etesyncResource::itemRemoved(const Akonadi::Item &item) { void etesyncResource::itemRemoved(const Akonadi::Item& item)
// TODO: this method is called when somebody else, e.g. a client application, {
// has deleted an item managed by your resource. // TODO: this method is called when somebody else, e.g. a client
// application, has deleted an item managed by your resource.
// NOTE: There is an equivalent method for collections, but it isn't part // NOTE: There is an equivalent method for collections, but it isn't part
// of this template code to keep it simple // of this template code to keep it simple
} }
AKONADI_RESOURCE_MAIN(etesyncResource) AKONADI_RESOURCE_MAIN(etesyncResource)
...@@ -18,33 +18,43 @@ ...@@ -18,33 +18,43 @@
#ifndef ETESYNCRESOURCE_H #ifndef ETESYNCRESOURCE_H
#define ETESYNCRESOURCE_H #define ETESYNCRESOURCE_H
#include <kcontacts/addressee.h>
#include <kcontacts/vcardconverter.h>
#include <AkonadiAgentBase/ResourceBase> #include <AkonadiAgentBase/ResourceBase>
class etesyncResource : public Akonadi::ResourceBase, class etesyncResource : public Akonadi::ResourceBase,
public Akonadi::AgentBase::Observer { public Akonadi::AgentBase::Observer
Q_OBJECT {
Q_OBJECT
public: public:
explicit etesyncResource(const QString &id); explicit etesyncResource(const QString &id);
~etesyncResource() override; ~etesyncResource() override;
public Q_SLOTS: public Q_SLOTS:
void configure(WId windowId) override; void configure(WId windowId) override;
protected Q_SLOTS: protected Q_SLOTS:
void retrieveCollections() override; void retrieveCollections() override;
void retrieveItems(const Akonadi::Collection &col) override; void retrieveItems(const Akonadi::Collection &col) override;
bool retrieveItem(const Akonadi::Item &item, bool retrieveItem(const Akonadi::Item &item,
const QSet<QByteArray> &parts) override; const QSet<QByteArray> &parts) override;
protected: protected:
void aboutToQuit() override; void aboutToQuit() override;
void itemAdded(const Akonadi::Item &item, void itemAdded(const Akonadi::Item &item,
const Akonadi::Collection &collection) override; const Akonadi::Collection &collection) override;
void itemChanged(const Akonadi::Item &item, void itemChanged(const Akonadi::Item &item,
const QSet<QByteArray> &parts) override; const QSet<QByteArray> &parts) override;
void itemRemoved(const Akonadi::Item &item) override; void itemRemoved(const Akonadi::Item &item) override;
private:
EteSync *etesync;
QString derived;
EteSyncJournalManager *journalManager;
EteSyncAsymmetricKeyPair *keypair;
}; };
#endif #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