Hello!
Status check and some more thoughts below...
On Mi, 2011-05-18 at 11:36 +0100, Patrick Ohly wrote:
> With that, the Yahoo template becomes:
[...]
> The corresponding Google Calendar template would be:
[...]
These are in the webdav-configuration branch.
> On the command line, this would be used as:
>
> $ syncevolution --configure source-config@google-calendar
>
> This searches for a "google calendar" template (spaces, underscore and
> hyphen must compare equal) and uses it automatically.
Done, checked by SyncEvo::CmdlineTest::testWebDAV. You'll need to get
today's commit.
> $ syncevolution --template google_calendar source-config@my-google
>
> Template specified explicitly, automatic search does not find it.
Also checked by that same test.
> At the moment, listing available WebDAV collections (= address books,
> calendar) is not supported by the backend.
>
> On the command line, the traditional "syncevolution" invocation lists
> local databases for all backends. With WebDAV this doesn't work, because
> username/password and potentially syncURL are needed to find the
> databases. My goal is to deprecate this usage of the command line.
> Instead,
>
> $ syncevolution --print-databases <options> <config> <source>
>
> would list the databases. <config> and <source> don't have to exist, so
>
> $ syncevolution --print-databases \
> [email protected] password=foobar \
> backend=CalDAV \
> foo bar
> would find calendars on Yahoo. The "foo bar" <config> <source> is
> redundant, but currently required by the command line syntax check.
> These command line parameters should be made optional.
>
> Via D-Bus, a temporary configuration has to be created as part of a
> session. Then Session.GetDatabases() can be used.
This all still needs to be done.
> The result of listing database should be a full URL. Then setting "uri"
> to that value can skip the discovery phase.
>
> I'm currently wondering whether the "uri" property should be set
> automatically as part of the first sync, if it wasn't set before. That
> way we avoid the risk that the discovery phase suddenly picks a
> different database, for example because a new database was created on
> the server later.
Note that this should be "database", not "uri". I think using that is
the right approach. Less special cases, user directly sees what sync
did.
In terms of implementation: setting this property may go into the
endSync() callback. A complication is that for CalDAV, this method is
called in the wrapper MapSyncSource and not in WebDAVSource.
Attached a patch which shows how this could be done. I verified that the
URL is stored after a sync, but then using it again with Yahoo fails. It
asks for credentials by redirecting to a log in page - not useful. I
haven't checked this further.
> Changing the uri later on should force a slow sync. Not implemented at
> the moment, though: https://bugs.meego.com/show_bug.cgi?id=693
We might have to be more careful here. Consider this:
1. User sets up synchronization of system calendar with CalDAV
calendar A.
2. synchronizes => system calendar contains events from A
3. User changes to calendar B.
4. SyncEvolution detects need for slow sync, asks users what to do,
user accepts slow sync => events from calendar A copied to B.
The "asks users what to do" is part of the slow sync handling in the
command line and the GTK UI. We don't have this concept in Tablet (yet).
See the "preventSlowSync" setting.
Without detecting the need for a slow sync (current state of the source
code), we get:
1. User sets up synchronization of system calendar with CalDAV
calendar A.
2. synchronizes => system calendar contains events from A
3. User changes to calendar B.
4. SyncEvolution does a normal sync. Change tracking sees this as
removal of all items from A, with all items from B added. If
(unlikely) item names are not fully disjunct, then these items
will be seen as updated unless (even more unlikely) they happen
to have the same eTag => system calendar will be identical to B.
Perhaps this is what we want in such a case?
The "likely" part worries me a bit. I think it'll work in practice, but
there is no 100% guarantee.
--
Best Regards, Patrick Ohly
The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.
diff --git a/src/backends/webdav/CalDAVSource.h b/src/backends/webdav/CalDAVSource.h
index 02be1df..b1c0560 100644
--- a/src/backends/webdav/CalDAVSource.h
+++ b/src/backends/webdav/CalDAVSource.h
@@ -33,6 +33,7 @@ class CalDAVSource : public WebDAVSource,
/* implementation of SubSyncSource interface */
virtual void begin() { contactServer(); }
+ virtual void endSubSync(bool success) { if (success) { storeServerInfos(); } }
virtual void listAllSubItems(SubRevisionMap_t &revisions);
virtual SubItemResult insertSubItem(const std::string &uid, const std::string &subid,
const std::string &item);
diff --git a/src/backends/webdav/WebDAVSource.cpp b/src/backends/webdav/WebDAVSource.cpp
index 816eba8..ab2d254 100644
--- a/src/backends/webdav/WebDAVSource.cpp
+++ b/src/backends/webdav/WebDAVSource.cpp
@@ -291,6 +291,18 @@ void WebDAVSource::contactServer()
// we have done this work before, no need to repeat it
}
+ // Can we skip auto-detection because a full resource URL is set?
+ std::string database = getDatabaseID();
+ if (!database.empty() &&
+ m_contextSettings) {
+ m_calendar = Neon::URI::parse(database);
+ // m_contextSettings = m_settings, so this sets m_settings->getURL()
+ m_contextSettings->setURL(database);
+ // start talking to host defined by m_settings->getURL()
+ m_session = Neon::Session::create(m_settings);
+ return;
+ }
+
int timeoutSeconds = m_settings->timeoutSeconds();
int retrySeconds = m_settings->retrySeconds();
SE_LOG_DEBUG(this, NULL, "timout %ds, retry %ds => %s",
@@ -825,6 +837,17 @@ void WebDAVSource::getSynthesisInfo(SynthesisInfo &info,
}
}
+void WebDAVSource::storeServerInfos()
+{
+ if (getDatabaseID().empty()) {
+ // user did not select resource, remember the one used for the
+ // next sync
+ setDatabaseID(m_calendar.toURL());
+ getProperties()->flush();
+ }
+}
+
+
static const ne_propname getetag[] = {
{ "DAV:", "getetag" },
{ "DAV:", "resourcetype" },
diff --git a/src/backends/webdav/WebDAVSource.h b/src/backends/webdav/WebDAVSource.h
index 510817f..a21eda4 100644
--- a/src/backends/webdav/WebDAVSource.h
+++ b/src/backends/webdav/WebDAVSource.h
@@ -54,6 +54,9 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
*/
void contactServer();
+ /** store resource URL permanently after successful sync */
+ void storeServerInfos();
+
/* implementation of SyncSource interface */
virtual void open();
virtual bool isEmpty();
@@ -67,6 +70,13 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
contactServer();
TrackingSyncSource::beginSync(lastToken, resumeToken);
}
+ /** hook into session to store infos */
+ virtual std::string endSync(bool success) {
+ if (success) {
+ storeServerInfos();
+ }
+ return TrackingSyncSource::endSync(success);
+ }
/* implementation of TrackingSyncSource interface */
virtual void listAllItems(RevisionMap_t &revisions);
diff --git a/src/syncevo/MapSyncSource.h b/src/syncevo/MapSyncSource.h
index 9f7a16b..a886108 100644
--- a/src/syncevo/MapSyncSource.h
+++ b/src/syncevo/MapSyncSource.h
@@ -97,6 +97,9 @@ class SubSyncSource : virtual public SyncSourceBase
/** called after open() and before any of the following methods */
virtual void begin() = 0;
+ /** called after a sync */
+ virtual void endSubSync(bool success) = 0;
+
virtual void listAllSubItems(SubRevisionMap_t &revisions) = 0;
virtual SubItemResult insertSubItem(const std::string &uid, const std::string &subid,
const std::string &item) = 0;
@@ -181,6 +184,7 @@ class MapSyncSource : public TrackingSyncSource,
virtual Databases getDatabases() { return dynamic_cast<SyncSource &>(*m_sub).getDatabases(); }
virtual void open() { dynamic_cast<SyncSource &>(*m_sub).open(); }
virtual void beginSync(const std::string &lastToken, const std::string &resumeToken) { m_sub->begin(); TrackingSyncSource::beginSync(lastToken, resumeToken); }
+ virtual std::string endSync(bool success) { m_sub->endSubSync(success); return TrackingSyncSource::endSync(success); }
virtual bool isEmpty() { return dynamic_cast<SyncSource &>(*m_sub).getOperations().m_isEmpty(); }
virtual void listAllItems(SyncSourceRevisions::RevisionMap_t &revisions);
virtual InsertItemResult insertItem(const std::string &luid, const std::string &item, bool raw);
_______________________________________________
SyncEvolution mailing list
[email protected]
http://lists.syncevolution.org/listinfo/syncevolution