WebDAV: use server's order when listing collections

When doing a recursive scan of the home set, preserve the order of
entries as reported by the server and check the first one first. The
server knows better which entries are more relevant for the user (and
thus should be the default) or may have some other relevant
order. Previously, SyncEvolution replaced that order with sorting by
URL, which led to a predictable, but rather meaningless order.

For example, Google lists the users own calendar first, followed by
the shared calendars sorted alphabetical by their name. Now
SyncEvolution picks the main calendar as default correctly when
scanning from https://www.google.com/calendar/dav/.
This commit is contained in:
Patrick Ohly 2014-04-24 22:05:41 +02:00
parent 29c08781ef
commit cca89dbf87
2 changed files with 36 additions and 2 deletions

View File

@ -289,6 +289,27 @@ void ContextSettings::initializeFlags(const std::string &url)
m_noCTag = noCTag;
}
WebDAVSource::Props_t::mapped_type & WebDAVSource::Props_t::operator [] (const WebDAVSource::Props_t::key_type &key)
{
iterator it = find(key);
if (it != end()) {
return it->second;
} else {
push_back(value_type(key, mapped_type()));
return back().second;
}
}
WebDAVSource::Props_t::iterator WebDAVSource::Props_t::find(const WebDAVSource::Props_t::key_type &key) {
for (iterator it = begin();
it != end();
++it) {
if (it->first == key) {
return it;
}
}
return end();
}
WebDAVSource::WebDAVSource(const SyncSourceParams &params,
const boost::shared_ptr<Neon::Settings> &settings) :

View File

@ -238,8 +238,21 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
*/
InitStateString m_postPath;
/** information about certain paths (path->property->value)*/
typedef std::map<std::string, std::map<std::string, std::string> > Props_t;
/**
* Information about certain paths (path->property->value).
* The container acts like a hash (supports indexing with unique string)
* but adds new entries at the end like a vector.
*/
class Props_t : public std::vector< std::pair < std::string, std::map<std::string, std::string> > >
{
public:
typedef std::string key_type;
typedef std::map<std::string, std::string> mapped_type;
mapped_type &operator [] (const key_type &key);
iterator find(const key_type &key);
const_iterator find(const key_type &key) const { return const_cast<Props_t *>(this)->find(key); }
};
/** extract value from first <DAV:href>value</DAV:href>, empty string if not inside propval */
std::string extractHREF(const std::string &propval);