Buteo+DAV: added support for Yahoo! Contacts

Enabled support for Yahoo! Contacts, by adding it to the configuration
created for Yahoo. Sending data to it requires suppressing empty
properties, which it doesn't seem to handle in all cases (empty
X-GENDER, for example).
This commit is contained in:
Patrick Ohly 2011-01-25 19:29:33 +01:00
parent 883f9a0cab
commit 14a5612134
5 changed files with 69 additions and 8 deletions

View file

@ -45,7 +45,22 @@ bool ButeoBridge::startSync()
SE_THROW("init() not called");
}
// run sync
std::vector<const char *> sources;
int count = 0;
sources.resize(4, NULL);
QList<const Buteo::Profile *> storages = iProfile.storageProfiles();
BOOST_FOREACH(const Buteo::Profile *profile, storages) {
if (profile->isEnabled()) {
// translate between names in profile and names in SyncEvolution
if (profile->name() == "hcontacts") {
sources[count++] = "addressbook";
} else if (profile->name() == "hcalendar") {
sources[count++] = "calendar";
}
}
}
// run sync with just the enabled sources
Cmdline sync(std::cout, std::cerr,
"buteo-sync",
"--run",
@ -53,6 +68,7 @@ bool ButeoBridge::startSync()
"--sync-property", StringPrintf("password=%s", password.c_str()).c_str(),
"--sync-property", "preventSlowSync=0",
m_config.c_str(),
sources[0], sources[1], sources[2], sources[3],
NULL);
bool res = sync.parse() && sync.run();
@ -118,18 +134,25 @@ bool ButeoBridge::init()
// determine parameters for configuration
std::string url;
std::vector<const char *> sources;
sources.resize(4, NULL);
QString profile = getProfileName();
if (profile == "google-calendar") {
m_config = "google-calendar";
url = "syncURL=https://www.google.com/calendar/dav/%u/user/?SyncEvolution=Google";
sources[0] = "calendar";
} else if (profile == "yahoo") {
m_config = "yahoo";
url = "syncURL=https://caldav.calendar.yahoo.com/dav/%u/Calendar/";
url = "syncURL="; // depend on DNS SRV to find right host
// for CalDAV/CardDAV (which currently
// are different!)
sources[0] = "calendar";
sources[1] = "addressbook";
} else {
return false;
}
// configure local sync of calendar with CalDAV
// configure local sync of calendar with CalDAV and/or CardDAV
std::string config = StringPrintf("source-config@%s", m_config.c_str());
if (!SyncConfig(config).exists()) {
Cmdline target(std::cout, std::cerr,
@ -138,9 +161,10 @@ bool ButeoBridge::init()
"--sync-property", url.c_str(),
"--sync-property", "printChanges=0",
"--sync-property", "dumpData=0",
"--source-property", "type=CalDAV",
"--source-property", "calendar/type=CalDAV",
"--source-property", "addressbook/type=CalDAV",
config.c_str(),
"calendar",
sources[0], sources[1], sources[2], sources[3],
NULL);
bool res = target.parse() && target.run();
if (!res) {
@ -156,7 +180,7 @@ bool ButeoBridge::init()
"--sync-property", "dumpData=0",
"--sync-property", StringPrintf("syncURL=local://@%s", m_config.c_str()).c_str(),
m_config.c_str(),
"calendar",
sources[0], sources[1], sources[2], sources[3],
NULL);
bool res = server.parse() && server.run();
if (!res) {

View file

@ -7,5 +7,8 @@
<key name="Calendar Format" value="vcalendar"/>
<key name="Notebook Name" value="Personal"/>
</profile>
<profile name="hcontact" type="storage"/>
<profile name="hcontacts" type="storage">
<key name="Local URI" value="./contacts"/>
<key name="Target URI" value="card"/>
</profile>
</profile>

View file

@ -8,6 +8,6 @@
<key name="enabled" value="true"/>
</profile>
<profile name="hcontacts" type="storage">
<key name="enabled" value="false"/>
<key name="enabled" value="true"/>
</profile>
</profile>

View file

@ -482,6 +482,38 @@ WebDAVSource::Databases WebDAVSource::getDatabases()
return result;
}
void WebDAVSource::getSynthesisInfo(SynthesisInfo &info,
XMLConfigFragments &fragments)
{
TrackingSyncSource::getSynthesisInfo(info, fragments);
// TODO: instead of identifying the peer based on the
// session URI, use some information gathered about
// it during open()
if (m_session) {
string host = m_session->getURI().m_host;
if (host.find("google") != host.npos) {
info.m_backendRule = "GOOGLE";
fragments.m_remoterules["GOOGLE"] =
" <remoterule name='GOOGLE'>\n"
" <deviceid>none</deviceid>\n"
" </remoterule>";
} else if (host.find("yahoo") != host.npos) {
info.m_backendRule = "YAHOO";
fragments.m_remoterules["YAHOO"] =
" <remoterule name='YAHOO'>\n"
" <deviceid>none</deviceid>\n"
// Yahoo! Contacts reacts with a "500 - internal server error"
// to an empty X-GENDER property. In general, empty properties
// should never be necessary in CardDAV and CalDAV, because
// sent items conceptually replace the one on the server, so
// disable them all.
" <noemptyproperties>yes</noemptyproperties>\n"
" </remoterule>";
}
SE_LOG_DEBUG(this, NULL, "using data conversion rules for '%s'", info.m_backendRule.c_str());
}
}
static const ne_propname getetag[] = {
{ "DAV:", "getetag" },
{ "DAV:", "resourcetype" },

View file

@ -40,6 +40,8 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
virtual bool isEmpty();
virtual void close();
virtual Databases getDatabases();
void getSynthesisInfo(SynthesisInfo &info,
XMLConfigFragments &fragments);
/* implementation of TrackingSyncSource interface */
virtual void listAllItems(RevisionMap_t &revisions);