ActiveSync: added getDatabases support for fetching folder list
A new method, findCollections, fetches the folder list from the server and creates two maps: m_collections - store all the information about each collection (folder), indexed by server collection ID m_folderPaths - map full folder paths to collection IDs getDatabases uses this data to returns the folder path, collection ID and a flag indicating if the folder is the default for that type. Note 1: getDatabases always asks activesyncd to update the folder list from the server in order to return up to date information. Note 2: this depends on a new libeasclient routine: eas_sync_handler_get_folder_list
This commit is contained in:
parent
d8ca8b64cf
commit
5920bf59b3
|
@ -32,6 +32,7 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/range/adaptors.hpp>
|
||||
|
||||
/* #include <eas-connection-errors.h> */
|
||||
#include <syncevo/declarations.h>
|
||||
|
@ -39,6 +40,7 @@ SE_BEGIN_CXX
|
|||
|
||||
void EASItemUnref(EasItemInfo *info) { g_object_unref(&info->parent_instance); }
|
||||
void GStringUnref(char *str) { g_free(str); }
|
||||
void EASFolderUnref(EasFolder *f) { g_object_unref(&f->parent_instance); }
|
||||
|
||||
void ActiveSyncSource::enableServerMode()
|
||||
{
|
||||
|
@ -50,11 +52,125 @@ bool ActiveSyncSource::serverModeEnabled() const
|
|||
return m_operations.m_loadAdminData;
|
||||
}
|
||||
|
||||
/* Recursively work out full path name */
|
||||
std::string ActiveSyncSource::Collection::fullPath() {
|
||||
if (!pathFound) {
|
||||
if (parentId == "0") {
|
||||
pathName = name;
|
||||
} else {
|
||||
pathName = source->m_collections[parentId].fullPath() + "/" + name;
|
||||
}
|
||||
pathFound = true;
|
||||
}
|
||||
|
||||
return pathName;
|
||||
}
|
||||
|
||||
void ActiveSyncSource::findCollections(const std::string account, const bool force_update)
|
||||
{
|
||||
GErrorCXX gerror;
|
||||
EasSyncHandler *handler;
|
||||
EASFoldersCXX folders;
|
||||
|
||||
if (!m_collections.empty()) {
|
||||
if (!force_update) return;
|
||||
m_collections.clear();
|
||||
m_folderPaths.clear();
|
||||
}
|
||||
|
||||
/* Fetch the folders */
|
||||
handler = eas_sync_handler_new(account.c_str());
|
||||
if (!handler) throwError("findCollections cannot allocate sync handler");
|
||||
|
||||
if (!eas_sync_handler_get_folder_list (handler,
|
||||
force_update,
|
||||
folders,
|
||||
NULL,
|
||||
gerror)) {
|
||||
g_object_unref(handler);
|
||||
gerror.throwError("fetching folder list");
|
||||
}
|
||||
g_object_unref(handler);
|
||||
|
||||
/* Save the Collections */
|
||||
BOOST_FOREACH(EasFolder *folder, folders) {
|
||||
m_collections[folder->folder_id].collectionId = folder->folder_id;
|
||||
m_collections[folder->folder_id].name = folder->display_name;
|
||||
m_collections[folder->folder_id].parentId = folder->parent_id;
|
||||
m_collections[folder->folder_id].type = folder->type;
|
||||
m_collections[folder->folder_id].source = this;
|
||||
}
|
||||
|
||||
/* Save the full paths */
|
||||
BOOST_FOREACH(std::string id, m_collections | boost::adaptors::map_keys) {
|
||||
m_folderPaths[m_collections[id].fullPath()] = id;
|
||||
}
|
||||
}
|
||||
|
||||
int ActiveSyncSource::Collection::getFolderType () {
|
||||
switch (type) {
|
||||
case EAS_FOLDER_TYPE_DEFAULT_INBOX:
|
||||
case EAS_FOLDER_TYPE_DEFAULT_DRAFTS:
|
||||
case EAS_FOLDER_TYPE_DEFAULT_DELETED_ITEMS:
|
||||
case EAS_FOLDER_TYPE_DEFAULT_SENT_ITEMS:
|
||||
case EAS_FOLDER_TYPE_DEFAULT_OUTBOX:
|
||||
case EAS_FOLDER_TYPE_USER_CREATED_MAIL:
|
||||
return EAS_ITEM_MAIL;
|
||||
case EAS_FOLDER_TYPE_DEFAULT_TASKS:
|
||||
case EAS_FOLDER_TYPE_USER_CREATED_TASKS:
|
||||
return EAS_ITEM_TODO;
|
||||
case EAS_FOLDER_TYPE_DEFAULT_CALENDAR:
|
||||
case EAS_FOLDER_TYPE_USER_CREATED_CALENDAR:
|
||||
return EAS_ITEM_CALENDAR;
|
||||
case EAS_FOLDER_TYPE_DEFAULT_CONTACTS:
|
||||
case EAS_FOLDER_TYPE_USER_CREATED_CONTACTS:
|
||||
return EAS_ITEM_CONTACT;
|
||||
case EAS_FOLDER_TYPE_DEFAULT_NOTES:
|
||||
case EAS_FOLDER_TYPE_USER_CREATED_NOTES:
|
||||
//TODO: implement memos
|
||||
case EAS_FOLDER_TYPE_DEFAULT_JOURNAL:
|
||||
case EAS_FOLDER_TYPE_USER_CREATED_JOURNAL:
|
||||
case EAS_FOLDER_TYPE_UNKNOWN:
|
||||
case EAS_FOLDER_TYPE_RECIPIENT_CACHE:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool ActiveSyncSource::Collection::collectionIsDefault () {
|
||||
return type == EAS_FOLDER_TYPE_DEFAULT_INBOX ||
|
||||
type == EAS_FOLDER_TYPE_DEFAULT_DRAFTS ||
|
||||
type == EAS_FOLDER_TYPE_DEFAULT_DELETED_ITEMS ||
|
||||
type == EAS_FOLDER_TYPE_DEFAULT_SENT_ITEMS ||
|
||||
type == EAS_FOLDER_TYPE_DEFAULT_OUTBOX ||
|
||||
type == EAS_FOLDER_TYPE_DEFAULT_TASKS ||
|
||||
type == EAS_FOLDER_TYPE_DEFAULT_CALENDAR ||
|
||||
type == EAS_FOLDER_TYPE_DEFAULT_CONTACTS ||
|
||||
type == EAS_FOLDER_TYPE_DEFAULT_NOTES ||
|
||||
type == EAS_FOLDER_TYPE_DEFAULT_JOURNAL;
|
||||
}
|
||||
|
||||
ActiveSyncSource::Databases ActiveSyncSource::getDatabases()
|
||||
{
|
||||
Databases result;
|
||||
// empty string always selects the default database
|
||||
result.push_back(Database("", "", true));
|
||||
// do a scan if username is set
|
||||
std::string account = m_context->getSyncUsername();
|
||||
|
||||
if (!account.empty()) {
|
||||
|
||||
findCollections(account, true);
|
||||
|
||||
BOOST_FOREACH(Collection coll, m_collections | boost::adaptors::map_values) {
|
||||
if (coll.getFolderType() == getEasType()) {
|
||||
result.push_back(Database(coll.pathName, coll.collectionId, coll.collectionIsDefault()));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
result.push_back(Database("to scan, specify --print-databases username=<account> backend=\""+getSourceType().m_backend+"\"",
|
||||
""));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "libeassync.h"
|
||||
#include <eas-item-info.h>
|
||||
#include <eas-folder.h>
|
||||
|
||||
#include <syncevo/declarations.h>
|
||||
SE_BEGIN_CXX
|
||||
|
@ -179,6 +180,8 @@ class ActiveSyncSource :
|
|||
void setStartSyncKey(const std::string &startSyncKey) { m_startSyncKey = startSyncKey; }
|
||||
std::string getCurrentSyncKey() { return m_currentSyncKey; }
|
||||
void setCurrentSyncKey(const std::string ¤tSyncKey) { m_currentSyncKey = currentSyncKey; }
|
||||
void findCollections(const std::string account, bool force_update);
|
||||
std::string getCollectionPath(const std::string parentId, const std::string name);
|
||||
|
||||
boost::shared_ptr<ConfigNode> m_itemNode;
|
||||
|
||||
|
@ -212,6 +215,28 @@ class ActiveSyncSource :
|
|||
* changes are made (if doing change tracking)
|
||||
*/
|
||||
std::map<std::string, std::string> m_items;
|
||||
|
||||
/**
|
||||
* list of folders
|
||||
*/
|
||||
typedef struct Collection {
|
||||
std::string collectionId;
|
||||
std::string name;
|
||||
std::string parentId;
|
||||
std::string pathName;
|
||||
unsigned type;
|
||||
bool pathFound;
|
||||
ActiveSyncSource *source;
|
||||
|
||||
Collection() {pathFound = false;}
|
||||
|
||||
int getFolderType();
|
||||
bool collectionIsDefault();
|
||||
std::string fullPath();
|
||||
|
||||
} collection;
|
||||
std::map<std::string, Collection> m_collections; // Indexed by collectionID
|
||||
std::map<std::string, std::string> m_folderPaths; // Maps pathName to collectionId
|
||||
};
|
||||
|
||||
class ActiveSyncContactSource : public ActiveSyncSource
|
||||
|
@ -263,6 +288,11 @@ typedef GListCXX<char, GSList, GStringUnref> EASIdsCXX;
|
|||
/** non-copyable smart pointer to an EasItemInfo, unrefs when going out of scope */
|
||||
typedef eptr<EasItemInfo, GObject> EASItemPtr;
|
||||
|
||||
void EASFolderUnref(EasFolder *f);
|
||||
|
||||
/** non-copyable list of EasFolder pointers, owned by list */
|
||||
typedef GListCXX<EasFolder, GSList, EASFolderUnref> EASFoldersCXX;
|
||||
|
||||
SE_END_CXX
|
||||
|
||||
#endif // ENABLE_ACTIVESYNC
|
||||
|
|
Loading…
Reference in New Issue