configuration: added support for configuration templates in /etc and server icons
The server config.ini files and icon.[svg|png] in src/default will be installed in /etc/default/syncevolution. All configurations found there extend and/or override the builtin templates. The advantage is that file-based templates can have icons and that templates can be added/modified without recompiling SyncEvolution. This meta information is now part of EvolutionSyncConfig: - getWebURL() returns a URL with further information; this replaces the hard-coded URL string that was previously returned as comment for templates in the ServerList - getIconURI() currently returns absolute file paths to an icon file (example: icon.png for ScheduleWorld). The content and exact URI may vary, depending on how system administrators or distributions configure SyncEvolution. If possible, callers should be able to handle http:// and other URI access methods.
This commit is contained in:
parent
905eb74ffd
commit
fa2e0c41c9
11
README
11
README
|
@ -96,6 +96,17 @@ directories before running SyncEvolution for the first time with
|
|||
Evolution. In older Evolution versions the same data is found in
|
||||
$HOME/evolution.
|
||||
|
||||
Configuration templates for SyncML servers are searched in the following
|
||||
order:
|
||||
- "default/syncevolution" inside --sysconfdir DIR, usually
|
||||
/etc/default/syncevolution (when packaged for a distribution) or
|
||||
/usr/local/etc/default/syncevolution (when compiling from source)
|
||||
- built-in templates
|
||||
|
||||
The properties defined in a template override the default properties,
|
||||
so usually only those properties which specifically need to be set for
|
||||
a certain server should be listed in its template config.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
|
|
@ -21,6 +21,7 @@ cat configure-post.in >>configure.in
|
|||
|
||||
sed -e "s;@BACKEND_REGISTRIES@;`echo src/backends/*/*Register.cpp | sed -e s%src/%%g`;" \
|
||||
-e "s;@BACKENDS@;$BACKENDS;" \
|
||||
-e "s;@TEMPLATE_FILES@;`cd src && find default/syncevolution -type f \( -name '*.png' -o -name '*.svg' -o -name '*.ini' \) -printf '%p '`;" \
|
||||
src/Makefile-gen.am >src/Makefile.am
|
||||
|
||||
sed -e "s;@CONFIG_SUBS@;$SUBS;" \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0"?>
|
||||
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
|
||||
<node name="/">
|
||||
|
||||
<interface name="org.Moblin.SyncEvolution">
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@ SYNCEVOLUTION_DEP += $(SYNCSOURCES)
|
|||
endif
|
||||
EXTRA_DIST = shlibs.local Makefile-gen.am syncevolution.xml
|
||||
|
||||
TEMPLATE_FILES = @TEMPLATE_FILES@
|
||||
nobase_dist_sysconf_DATA = $(TEMPLATE_FILES)
|
||||
|
||||
DISTCLEANFILES = synccompare
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
CLEANFILES = libstdc++.a client-test $(CLIENT_LIB_TEST_FILES)
|
||||
|
@ -225,6 +228,7 @@ valgrind : test
|
|||
$(srcdir)/Makefile.am: Makefile-gen.am
|
||||
sed -e 's;[@]BACKEND_REGISTRIES[@];$(BACKEND_REGISTRIES);' \
|
||||
-e 's;[@]BACKENDS[@];$(BACKENDS);' \
|
||||
-e 's;[@]TEMPLATE_FILES[@];$(TEMPLATE_FILES);' \
|
||||
$< >$@
|
||||
|
||||
# old-style name for test program(s)
|
||||
|
|
|
@ -16,10 +16,11 @@
|
|||
|
||||
/** @TODO: replace stdio.h with streams */
|
||||
|
||||
FileConfigNode::FileConfigNode(const string &path, const string &fileName) :
|
||||
FileConfigNode::FileConfigNode(const string &path, const string &fileName, bool readonly) :
|
||||
m_path(path),
|
||||
m_fileName(fileName),
|
||||
m_modified(false),
|
||||
m_readonly(readonly),
|
||||
m_exists(false)
|
||||
{
|
||||
read();
|
||||
|
@ -53,6 +54,10 @@ void FileConfigNode::flush()
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_readonly) {
|
||||
throw std::runtime_error(m_path + ": internal error: flushing read-only file config node not allowed");
|
||||
}
|
||||
|
||||
mkdir_p(m_path);
|
||||
|
||||
string filename = m_path + "/" + m_fileName;
|
||||
|
|
|
@ -32,20 +32,22 @@ class FileConfigNode : public ConfigNode {
|
|||
|
||||
list<string> m_lines;
|
||||
bool m_modified;
|
||||
const bool m_readonly;
|
||||
bool m_exists;
|
||||
|
||||
void read();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Open or create a new file. The file will be physically created
|
||||
* right away whereas changes to its content will not be written
|
||||
* immediately.
|
||||
* Open or create a new file. The file will be read (if it exists)
|
||||
* but not create or written to unless flush() is called explicitly
|
||||
*
|
||||
* @param path node name, maps to directory
|
||||
* @param fileName name of file inside that directory
|
||||
* @param readonly do not create or write file, it must exist;
|
||||
* flush() will throw an exception when changes would have to be written
|
||||
*/
|
||||
FileConfigNode(const string &path, const string &fileName);
|
||||
FileConfigNode(const string &path, const string &fileName, bool readonly);
|
||||
|
||||
virtual string getName() const { return m_path + "/" + m_fileName; }
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
FileConfigTree::FileConfigTree(const string &root,
|
||||
bool oldLayout) :
|
||||
m_root(root),
|
||||
m_oldLayout(oldLayout)
|
||||
m_oldLayout(oldLayout),
|
||||
m_readonly(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -76,7 +77,7 @@ boost::shared_ptr<ConfigNode> FileConfigTree::open(const string &path,
|
|||
if (found != m_nodes.end()) {
|
||||
return found->second;
|
||||
} else {
|
||||
boost::shared_ptr<ConfigNode> node(new FileConfigNode(fullpath, filename));
|
||||
boost::shared_ptr<ConfigNode> node(new FileConfigNode(fullpath, filename, m_readonly));
|
||||
return m_nodes[fullname] = node;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ class FileConfigTree : public ConfigTree {
|
|||
FileConfigTree(const string &root,
|
||||
bool oldLayout);
|
||||
|
||||
void setReadOnly(bool readonly) { m_readonly = readonly; }
|
||||
bool getReadOnly() const { return m_readonly; }
|
||||
|
||||
/* ConfigTree API */
|
||||
virtual string getRootPath() const;
|
||||
virtual void flush();
|
||||
|
@ -38,6 +41,7 @@ class FileConfigTree : public ConfigTree {
|
|||
private:
|
||||
const string m_root;
|
||||
const bool m_oldLayout;
|
||||
bool m_readonly;
|
||||
|
||||
typedef map< string, boost::shared_ptr<ConfigNode> > NodeCache_t;
|
||||
/** cache of all nodes ever accessed */
|
||||
|
|
|
@ -85,6 +85,7 @@ CORE_SOURCES = \
|
|||
libsyncevolution_la_SOURCES = $(CORE_SOURCES)
|
||||
libsyncevolution_la_LIBADD = @EPACKAGE_LIBS@ @GLIB_LIBS@ $(TRANSPORT_LIBS) @LIBS@ $(SYNTHESIS_LIBS) $(SYNCEVOLUTION_LDADD)
|
||||
libsyncevolution_la_CXXFLAGS = $(TRANSPORT_CFLAGS) $(SYNCEVOLUTION_CXXFLAGS) $(SYNTHESIS_CFLAGS)
|
||||
libsyncevolution_la_CPPFLAGS = $(AM_CPPFLAGS) -DTEMPLATE_DIR=\""$(sysconfdir)/default/syncevolution"\"
|
||||
|
||||
SyncEvolutionXML.c: $(srcdir)/../syncevolution.xml
|
||||
echo "const char *SyncEvolutionXML =" > $@
|
||||
|
|
|
@ -879,6 +879,8 @@ public:
|
|||
"config.ini:# SSLServerCertificates = \n"
|
||||
"config.ini:# SSLVerifyServer = 1\n"
|
||||
"config.ini:# SSLVerifyHost = 1\n"
|
||||
"config.ini:WebURL = http://sync.scheduleworld.com\n"
|
||||
"config.ini:# IconURI = \n"
|
||||
"sources/addressbook/.internal.ini:# last = 0\n"
|
||||
"sources/addressbook/config.ini:sync = two-way\n"
|
||||
"sources/addressbook/config.ini:type = addressbook:text/vcard\n"
|
||||
|
@ -964,7 +966,7 @@ protected:
|
|||
cmdline.doit();
|
||||
string res = scanFiles(root);
|
||||
removeRandomUUID(res);
|
||||
string expected = m_scheduleWorldConfig;
|
||||
string expected = ScheduleWorldConfig();
|
||||
boost::replace_first(expected,
|
||||
"# proxyHost = ",
|
||||
"proxyHost = proxy");
|
||||
|
@ -985,7 +987,7 @@ protected:
|
|||
NULL);
|
||||
cmdline.doit();
|
||||
string res = scanFiles(root);
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(string(m_scheduleWorldConfig), res);
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(ScheduleWorldConfig(), res);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1004,7 +1006,7 @@ protected:
|
|||
NULL);
|
||||
cmdline.doit();
|
||||
string res = scanFiles(root);
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(string(m_scheduleWorldConfig), res);
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(ScheduleWorldConfig(), res);
|
||||
}
|
||||
void testSetupRenamed() {
|
||||
string root;
|
||||
|
@ -1021,7 +1023,7 @@ protected:
|
|||
NULL);
|
||||
cmdline.doit();
|
||||
string res = scanFiles(root);
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(string(m_scheduleWorldConfig), res);
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(ScheduleWorldConfig(), res);
|
||||
}
|
||||
void testSetupFunambol() {
|
||||
string root;
|
||||
|
@ -1067,9 +1069,9 @@ protected:
|
|||
help.doit();
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("Available configuration templates:\n"
|
||||
" funambol = http://my.funambol.com\n"
|
||||
" memotoo = http://www.memotoo.com\n"
|
||||
" scheduleworld = http://sync.scheduleworld.com\n"
|
||||
" synthesis = http://www.synthesis.ch\n"
|
||||
" memotoo = http://www.memotoo.com\n",
|
||||
" synthesis = http://www.synthesis.ch\n",
|
||||
help.m_out.str());
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", help.m_err.str());
|
||||
}
|
||||
|
@ -1134,7 +1136,7 @@ protected:
|
|||
string actual = cmdline.m_out.str();
|
||||
removeRandomUUID(actual);
|
||||
string filtered = filterConfig(actual);
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(filterConfig(internalToIni(m_scheduleWorldConfig)),
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(filterConfig(internalToIni(ScheduleWorldConfig())),
|
||||
filtered);
|
||||
// there should have been comments
|
||||
CPPUNIT_ASSERT(actual.size() > filtered.size());
|
||||
|
@ -1146,7 +1148,7 @@ protected:
|
|||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_err.str());
|
||||
string actual = filterConfig(cmdline.m_out.str());
|
||||
removeRandomUUID(actual);
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(filterConfig(internalToIni(m_scheduleWorldConfig)),
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(filterConfig(internalToIni(ScheduleWorldConfig())),
|
||||
actual);
|
||||
}
|
||||
|
||||
|
@ -1165,7 +1167,7 @@ protected:
|
|||
NULL);
|
||||
cmdline.doit();
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_err.str());
|
||||
string expected = filterConfig(internalToIni(m_scheduleWorldConfig));
|
||||
string expected = filterConfig(internalToIni(ScheduleWorldConfig()));
|
||||
boost::replace_first(expected,
|
||||
"syncURL = http://sync.scheduleworld.com/funambol/ds",
|
||||
"syncURL = foo");
|
||||
|
@ -1187,7 +1189,7 @@ protected:
|
|||
CPPUNIT_ASSERT_EQUAL_DIFF("", cmdline.m_err.str());
|
||||
string actual = cmdline.m_out.str();
|
||||
removeRandomUUID(actual);
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(internalToIni(m_scheduleWorldConfig),
|
||||
CPPUNIT_ASSERT_EQUAL_DIFF(internalToIni(ScheduleWorldConfig()),
|
||||
actual);
|
||||
}
|
||||
|
||||
|
@ -1283,7 +1285,11 @@ protected:
|
|||
"\n"
|
||||
"SSLVerifyServer:\n"
|
||||
"\n"
|
||||
"SSLVerifyHost:\n");
|
||||
"SSLVerifyHost:\n"
|
||||
"\n"
|
||||
"WebURL:\n"
|
||||
"\n"
|
||||
"IconURI:\n");
|
||||
string sourceProperties("sync:\n"
|
||||
"\n"
|
||||
"type:\n"
|
||||
|
@ -1561,7 +1567,14 @@ private:
|
|||
};
|
||||
|
||||
string ScheduleWorldConfig() {
|
||||
return m_scheduleWorldConfig;
|
||||
string config = m_scheduleWorldConfig;
|
||||
|
||||
if (isDir(string(TEMPLATE_DIR) + "/scheduleworld")) {
|
||||
boost::replace_all(config,
|
||||
"# IconURI = ",
|
||||
"IconURI = " TEMPLATE_DIR "/scheduleworld/icon.png");
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
string OldScheduleWorldConfig() {
|
||||
|
@ -1591,6 +1604,10 @@ private:
|
|||
"syncURL = http://sync.scheduleworld.com/funambol/ds",
|
||||
"syncURL = http://my.funambol.com/sync");
|
||||
|
||||
boost::replace_first(config,
|
||||
"WebURL = http://sync.scheduleworld.com",
|
||||
"WebURL = http://my.funambol.com");
|
||||
|
||||
boost::replace_first(config,
|
||||
"addressbook/config.ini:uri = card3",
|
||||
"addressbook/config.ini:uri = card");
|
||||
|
@ -1621,6 +1638,10 @@ private:
|
|||
"syncURL = http://sync.scheduleworld.com/funambol/ds",
|
||||
"syncURL = http://www.synthesis.ch/sync");
|
||||
|
||||
boost::replace_first(config,
|
||||
"WebURL = http://sync.scheduleworld.com",
|
||||
"WebURL = http://www.synthesis.ch");
|
||||
|
||||
boost::replace_first(config,
|
||||
"addressbook/config.ini:uri = card3",
|
||||
"addressbook/config.ini:uri = contacts");
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#include <unistd.h>
|
||||
#include "config.h"
|
||||
|
||||
static bool SourcePropSourceTypeIsSet(boost::shared_ptr<EvolutionSyncSourceConfig> source);
|
||||
static bool SourcePropURIIsSet(boost::shared_ptr<EvolutionSyncSourceConfig> source);
|
||||
|
||||
void ConfigProperty::splitComment(const string &comment, list<string> &commentLines)
|
||||
{
|
||||
size_t start = 0;
|
||||
|
@ -107,43 +110,123 @@ static const InitList< pair<string, string> > serverTemplates =
|
|||
|
||||
EvolutionSyncConfig::ServerList EvolutionSyncConfig::getServerTemplates()
|
||||
{
|
||||
return serverTemplates;
|
||||
class TmpList : public ServerList {
|
||||
public:
|
||||
void addDefaultTemplate(const string &server, const string &url) {
|
||||
BOOST_FOREACH(const value_type &entry, static_cast<ServerList &>(*this)) {
|
||||
if (entry.first == server) {
|
||||
// already present
|
||||
return;
|
||||
}
|
||||
}
|
||||
push_back(value_type(server, url));
|
||||
}
|
||||
} result;
|
||||
|
||||
// scan TEMPLATE_DIR for templates
|
||||
string templateDir(TEMPLATE_DIR);
|
||||
if (isDir(templateDir)) {
|
||||
ReadDir dir(templateDir);
|
||||
BOOST_FOREACH(const string &entry, dir) {
|
||||
if (isDir(templateDir + "/" + entry)) {
|
||||
boost::shared_ptr<EvolutionSyncConfig> config = EvolutionSyncConfig::createServerTemplate(entry);
|
||||
string comment = config->getWebURL();
|
||||
if (comment.empty()) {
|
||||
comment = templateDir + "/" + entry;
|
||||
}
|
||||
result.push_back(ServerList::value_type(entry, comment));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// builtin templates if not present
|
||||
result.addDefaultTemplate("funambol", "http://my.funambol.com");
|
||||
result.addDefaultTemplate("scheduleworld", "http://sync.scheduleworld.com");
|
||||
result.addDefaultTemplate("synthesis", "http://www.synthesis.ch");
|
||||
result.addDefaultTemplate("memotoo", "http://www.memotoo.com");
|
||||
|
||||
result.sort();
|
||||
return result;
|
||||
}
|
||||
|
||||
boost::shared_ptr<EvolutionSyncConfig> EvolutionSyncConfig::createServerTemplate(const string &server)
|
||||
{
|
||||
boost::shared_ptr<ConfigTree> tree(new FileConfigTree("/dev/null", false));
|
||||
string templateConfig(string(TEMPLATE_DIR) + "/");
|
||||
if (server == "default") {
|
||||
templateConfig += "scheduleworld";
|
||||
} else {
|
||||
templateConfig += server;
|
||||
}
|
||||
boost::shared_ptr<FileConfigTree> tree(new FileConfigTree(templateConfig, false));
|
||||
tree->setReadOnly(true);
|
||||
boost::shared_ptr<EvolutionSyncConfig> config(new EvolutionSyncConfig(server, tree));
|
||||
boost::shared_ptr<PersistentEvolutionSyncSourceConfig> source;
|
||||
|
||||
config->setDefaults();
|
||||
config->setDefaults(false);
|
||||
// The prefix is important: without it, myFUNAMBOL 6.x and 7.0 map
|
||||
// all SyncEvolution instances to the single phone that they support,
|
||||
// which leads to unwanted slow syncs when switching between multiple
|
||||
// instances.
|
||||
config->setDevID(string("sc-pim-") + UUID());
|
||||
config->setSourceDefaults("addressbook");
|
||||
config->setSourceDefaults("calendar");
|
||||
config->setSourceDefaults("todo");
|
||||
config->setSourceDefaults("memo");
|
||||
|
||||
// set non-default values; this also creates the sync source configs
|
||||
// create sync source configs and set non-default values
|
||||
config->setSourceDefaults("addressbook", false);
|
||||
config->setSourceDefaults("calendar", false);
|
||||
config->setSourceDefaults("todo", false);
|
||||
config->setSourceDefaults("memo", false);
|
||||
|
||||
source = config->getSyncSourceConfig("addressbook");
|
||||
source->setSourceType("addressbook");
|
||||
source->setURI("card");
|
||||
if (!SourcePropSourceTypeIsSet(source)) {
|
||||
source->setSourceType("addressbook");
|
||||
}
|
||||
if (!SourcePropURIIsSet(source)) {
|
||||
source->setURI("card");
|
||||
}
|
||||
source = config->getSyncSourceConfig("calendar");
|
||||
source->setSourceType("calendar");
|
||||
source->setURI("event");
|
||||
if (!SourcePropSourceTypeIsSet(source)) {
|
||||
source->setSourceType("calendar");
|
||||
}
|
||||
if (!SourcePropURIIsSet(source)) {
|
||||
source->setURI("event");
|
||||
}
|
||||
source = config->getSyncSourceConfig("todo");
|
||||
source->setSourceType("todo");
|
||||
source->setURI("task");
|
||||
if (!SourcePropSourceTypeIsSet(source)) {
|
||||
source->setSourceType("todo");
|
||||
}
|
||||
if (!SourcePropURIIsSet(source)) {
|
||||
source->setURI("task");
|
||||
}
|
||||
source = config->getSyncSourceConfig("memo");
|
||||
source->setSourceType("memo");
|
||||
source->setURI("note");
|
||||
if (!SourcePropSourceTypeIsSet(source)) {
|
||||
source->setSourceType("memo");
|
||||
}
|
||||
if (!SourcePropURIIsSet(source)) {
|
||||
source->setURI("note");
|
||||
}
|
||||
|
||||
if (isDir(templateConfig)) {
|
||||
// directory exists, check for icon?
|
||||
if (config->getIconURI().empty()) {
|
||||
ReadDir dir(templateConfig);
|
||||
BOOST_FOREACH(const string &entry, dir) {
|
||||
if (boost::istarts_with(entry, "icon")) {
|
||||
config->setIconURI(templateConfig + "/" + entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// leave the source configs alone and return the config as it is:
|
||||
// in order to have sources configured as part of the template,
|
||||
// the template directory must have directories for all
|
||||
// sources under "sources"
|
||||
return config;
|
||||
}
|
||||
|
||||
if (boost::iequals(server, "scheduleworld") ||
|
||||
boost::iequals(server, "default")) {
|
||||
config->setSyncURL("http://sync.scheduleworld.com/funambol/ds");
|
||||
config->setWebURL("http://sync.scheduleworld.com");
|
||||
source = config->getSyncSourceConfig("addressbook");
|
||||
source->setURI("card3");
|
||||
source->setSourceType("addressbook:text/vcard");
|
||||
|
@ -155,12 +238,14 @@ boost::shared_ptr<EvolutionSyncConfig> EvolutionSyncConfig::createServerTemplate
|
|||
source->setURI("note");
|
||||
} else if (boost::iequals(server, "funambol")) {
|
||||
config->setSyncURL("http://my.funambol.com/sync");
|
||||
config->setWebURL("http://my.funambol.com");
|
||||
source = config->getSyncSourceConfig("calendar");
|
||||
source->setSync("disabled");
|
||||
source = config->getSyncSourceConfig("todo");
|
||||
source->setSync("disabled");
|
||||
} else if (boost::iequals(server, "synthesis")) {
|
||||
config->setSyncURL("http://www.synthesis.ch/sync");
|
||||
config->setWebURL("http://www.synthesis.ch");
|
||||
source = config->getSyncSourceConfig("addressbook");
|
||||
source->setURI("contacts");
|
||||
source = config->getSyncSourceConfig("calendar");
|
||||
|
@ -173,6 +258,7 @@ boost::shared_ptr<EvolutionSyncConfig> EvolutionSyncConfig::createServerTemplate
|
|||
source->setURI("notes");
|
||||
} else if (boost::iequals(server, "memotoo")) {
|
||||
config->setSyncURL("http://sync.memotoo.com/syncML");
|
||||
config->setWebURL("http://www.memotoo.com");
|
||||
source = config->getSyncSourceConfig("addressbook");
|
||||
source->setURI("con");
|
||||
source = config->getSyncSourceConfig("calendar");
|
||||
|
@ -333,6 +419,16 @@ static BoolConfigProperty syncPropSSLVerifyHost("SSLVerifyHost",
|
|||
"to disable this option and allow such connections.\n",
|
||||
"1");
|
||||
|
||||
static ConfigProperty syncPropWebURL("WebURL",
|
||||
"The URL of a web page with further information about the server.\n"
|
||||
"Used only by the GUI."
|
||||
"");
|
||||
|
||||
static ConfigProperty syncPropIconURI("IconURI",
|
||||
"The URI of an icon representing the server graphically.\n"
|
||||
"Should be a 48x48 pixmap or a SVG (preferred).\n"
|
||||
"Used only by the GUI.");
|
||||
|
||||
ConfigPropertyRegistry &EvolutionSyncConfig::getRegistry()
|
||||
{
|
||||
static ConfigPropertyRegistry registry;
|
||||
|
@ -363,6 +459,8 @@ ConfigPropertyRegistry &EvolutionSyncConfig::getRegistry()
|
|||
registry.push_back(&syncPropSSLServerCertificates);
|
||||
registry.push_back(&syncPropSSLVerifyServer);
|
||||
registry.push_back(&syncPropSSLVerifyHost);
|
||||
registry.push_back(&syncPropWebURL);
|
||||
registry.push_back(&syncPropIconURI);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
|
@ -455,6 +553,10 @@ int EvolutionSyncConfig::getMaxLogDirs() const { return syncPropMaxLogDirs.getPr
|
|||
void EvolutionSyncConfig::setMaxLogDirs(int value, bool temporarily) { syncPropMaxLogDirs.setProperty(*m_configNode, value, temporarily); }
|
||||
int EvolutionSyncConfig::getLogLevel() const { return syncPropLogLevel.getProperty(*m_configNode); }
|
||||
void EvolutionSyncConfig::setLogLevel(int value, bool temporarily) { syncPropLogLevel.setProperty(*m_configNode, value, temporarily); }
|
||||
std::string EvolutionSyncConfig::getWebURL() const { return syncPropWebURL.getProperty(*m_configNode); }
|
||||
void EvolutionSyncConfig::setWebURL(const std::string &url, bool temporarily) { syncPropWebURL.setProperty(*m_configNode, url, temporarily); }
|
||||
std::string EvolutionSyncConfig::getIconURI() const { return syncPropIconURI.getProperty(*m_configNode); }
|
||||
void EvolutionSyncConfig::setIconURI(const std::string &uri, bool temporarily) { syncPropIconURI.setProperty(*m_configNode, uri, temporarily); }
|
||||
const char* EvolutionSyncConfig::getSSLServerCertificates() const { return m_stringCache.getProperty(*m_configNode, syncPropSSLServerCertificates); }
|
||||
void EvolutionSyncConfig::setSSLServerCertificates(const string &value, bool temporarily) { syncPropSSLServerCertificates.setProperty(*m_configNode, value, temporarily); }
|
||||
bool EvolutionSyncConfig::getSSLVerifyServer() const { return syncPropSSLVerifyServer.getProperty(*m_configNode); }
|
||||
|
@ -463,25 +565,30 @@ bool EvolutionSyncConfig::getSSLVerifyHost() const { return syncPropSSLVerifyHos
|
|||
void EvolutionSyncConfig::setSSLVerifyHost(bool value, bool temporarily) { syncPropSSLVerifyHost.setProperty(*m_configNode, value, temporarily); }
|
||||
|
||||
static void setDefaultProps(const ConfigPropertyRegistry ®istry,
|
||||
boost::shared_ptr<FilterConfigNode> node)
|
||||
boost::shared_ptr<FilterConfigNode> node,
|
||||
bool force)
|
||||
{
|
||||
BOOST_FOREACH(const ConfigProperty *prop, registry) {
|
||||
if (!prop->isHidden()) {
|
||||
bool isDefault;
|
||||
prop->getProperty(*node, &isDefault);
|
||||
|
||||
if (!prop->isHidden() &&
|
||||
(force || isDefault)) {
|
||||
prop->setDefaultProperty(*node, prop->isObligatory());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EvolutionSyncConfig::setDefaults()
|
||||
void EvolutionSyncConfig::setDefaults(bool force)
|
||||
{
|
||||
setDefaultProps(getRegistry(), m_configNode);
|
||||
setDefaultProps(getRegistry(), m_configNode, force);
|
||||
}
|
||||
|
||||
void EvolutionSyncConfig::setSourceDefaults(const string &name)
|
||||
void EvolutionSyncConfig::setSourceDefaults(const string &name, bool force)
|
||||
{
|
||||
SyncSourceNodes nodes = getSyncSourceNodes(name);
|
||||
setDefaultProps(EvolutionSyncSourceConfig::getRegistry(),
|
||||
nodes.m_configNode);
|
||||
nodes.m_configNode, force);
|
||||
}
|
||||
|
||||
static void copyProperties(const ConfigNode &fromProps,
|
||||
|
@ -657,6 +764,10 @@ public:
|
|||
}
|
||||
}
|
||||
} sourcePropSourceType;
|
||||
static bool SourcePropSourceTypeIsSet(boost::shared_ptr<EvolutionSyncSourceConfig> source)
|
||||
{
|
||||
return source->isSet(sourcePropSourceType);
|
||||
}
|
||||
|
||||
static ConfigProperty sourcePropDatabaseID("evolutionsource",
|
||||
"Picks one of backend data sources:\n"
|
||||
|
@ -676,6 +787,11 @@ static ConfigProperty sourcePropDatabaseID("evolutionsource",
|
|||
static ConfigProperty sourcePropURI("uri",
|
||||
"this is appended to the server's URL to identify the\n"
|
||||
"server's database");
|
||||
static bool SourcePropURIIsSet(boost::shared_ptr<EvolutionSyncSourceConfig> source)
|
||||
{
|
||||
return source->isSet(sourcePropURI);
|
||||
}
|
||||
|
||||
static ConfigProperty sourcePropUser("evolutionuser",
|
||||
"authentication for backend data source; password can be specified\n"
|
||||
"in multiple ways, see SyncML server password for details\n"
|
||||
|
@ -697,7 +813,6 @@ ConfigPropertyRegistry &EvolutionSyncSourceConfig::getRegistry()
|
|||
registry.push_back(&EvolutionSyncSourceConfig::m_sourcePropSync);
|
||||
EvolutionSyncSourceConfig::m_sourcePropSync.setObligatory(true);
|
||||
registry.push_back(&sourcePropSourceType);
|
||||
sourcePropSourceType.setObligatory(true);
|
||||
registry.push_back(&sourcePropDatabaseID);
|
||||
registry.push_back(&sourcePropURI);
|
||||
registry.push_back(&sourcePropUser);
|
||||
|
|
|
@ -96,7 +96,7 @@ class ConfigProperty {
|
|||
virtual string getProperty(const ConfigNode &node, bool *isDefault = NULL) const {
|
||||
string name = getName();
|
||||
string value = node.readProperty(name);
|
||||
if (value.size()) {
|
||||
if (!value.empty()) {
|
||||
string error;
|
||||
if (!checkValue(value, error)) {
|
||||
throwValueError(node, name, value, error);
|
||||
|
@ -113,6 +113,13 @@ class ConfigProperty {
|
|||
}
|
||||
}
|
||||
|
||||
// true if property is set to non-empty value
|
||||
virtual bool isSet(const ConfigNode &node) const {
|
||||
string name = getName();
|
||||
string value = node.readProperty(name);
|
||||
return !value.empty();
|
||||
}
|
||||
|
||||
protected:
|
||||
void throwValueError(const ConfigNode &node, const string &name, const string &value, const string &error) const;
|
||||
|
||||
|
@ -470,7 +477,7 @@ class EvolutionSyncConfig {
|
|||
/** absolute directory name of the configuration root */
|
||||
string getRootPath() const;
|
||||
|
||||
typedef list< pair<string, string> > ServerList;
|
||||
typedef list< std::pair<std::string, std::string> > ServerList;
|
||||
|
||||
/**
|
||||
* returns list of servers in either the old (.sync4j) or
|
||||
|
@ -480,8 +487,7 @@ class EvolutionSyncConfig {
|
|||
static ServerList getServers();
|
||||
|
||||
/**
|
||||
* returns list of available config templates, given as
|
||||
* server name and comment
|
||||
* returns list of available config templates
|
||||
*/
|
||||
static ServerList getServerTemplates();
|
||||
|
||||
|
@ -573,12 +579,12 @@ class EvolutionSyncConfig {
|
|||
/**
|
||||
* initialize all properties with their default value
|
||||
*/
|
||||
void setDefaults();
|
||||
void setDefaults(bool force = true);
|
||||
|
||||
/**
|
||||
* create a new sync source configuration with default values
|
||||
*/
|
||||
void setSourceDefaults(const string &name);
|
||||
void setSourceDefaults(const string &name, bool force = true);
|
||||
|
||||
/**
|
||||
* Copy all registered properties (hidden and visible) and the
|
||||
|
@ -615,6 +621,12 @@ class EvolutionSyncConfig {
|
|||
virtual int getLogLevel() const;
|
||||
virtual void setLogLevel(int value, bool temporarily = false);
|
||||
|
||||
virtual std::string getWebURL() const;
|
||||
virtual void setWebURL(const std::string &url, bool temporarily = false);
|
||||
|
||||
virtual std::string getIconURI() const;
|
||||
virtual void setIconURI(const std::string &uri, bool temporarily = false);
|
||||
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
|
@ -785,6 +797,13 @@ class EvolutionSyncSourceConfig {
|
|||
|
||||
bool exists() const { return m_nodes.m_configNode->exists(); }
|
||||
|
||||
/** checks if a certain property is set to a non-empty value */
|
||||
bool isSet(ConfigProperty &prop) {
|
||||
return prop.isHidden() ?
|
||||
prop.isSet(*m_nodes.m_hiddenNode) :
|
||||
prop.isSet(*m_nodes.m_configNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Settings specific to SyncEvolution SyncSources
|
||||
*/
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
class VolatileConfigNode : public FilterConfigNode {
|
||||
public:
|
||||
VolatileConfigNode() :
|
||||
FilterConfigNode(boost::shared_ptr<ConfigNode>(new FileConfigNode("/dev/null", "dummy.ini")))
|
||||
FilterConfigNode(boost::shared_ptr<ConfigNode>(new FileConfigNode("/dev/null", "dummy.ini", true)))
|
||||
{}
|
||||
|
||||
virtual string getName() const { return "intermediate configuration"; }
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
The configuration templates in this directory get installed into
|
||||
sysconfdir/etc/default.
|
||||
|
||||
When adding/changing a new server, then only enter the properties
|
||||
which need to be changed here so that the default values can
|
||||
be used for the remaining properties.
|
||||
|
||||
An icon can be added here for servers. The file name must start with
|
||||
"icon".
|
||||
|
||||
Server configurations must be kept in sync in three different places:
|
||||
- here (if a server is installed as files)
|
||||
- in SyncEvolutionConfig.cpp's EvolutionSyncConfig::createServerTemplate()
|
||||
- in SyncEvolutionCmdline.cpp's test server configs
|
||||
|
||||
Note that server icons must come with a suitable license that allows
|
||||
redistribution. TODO: verify the license of the ScheduleWorld icon.
|
|
@ -0,0 +1,2 @@
|
|||
syncURL = http://my.funambol.com/sync
|
||||
WebURL = http://my.funambol.com
|
|
@ -0,0 +1,2 @@
|
|||
type = addressbook
|
||||
uri = card
|
|
@ -0,0 +1,2 @@
|
|||
uri = event
|
||||
sync = none
|
|
@ -0,0 +1 @@
|
|||
uri = note
|
|
@ -0,0 +1,2 @@
|
|||
uri = task
|
||||
sync = none
|
|
@ -0,0 +1,2 @@
|
|||
syncURL = http://sync.scheduleworld.com/funambol/ds
|
||||
WebURL = http://sync.scheduleworld.com
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
|
@ -0,0 +1,2 @@
|
|||
type = addressbook:text/vcard
|
||||
uri = card3
|
|
@ -0,0 +1 @@
|
|||
uri = cal2
|
|
@ -0,0 +1 @@
|
|||
uri = note
|
|
@ -0,0 +1 @@
|
|||
uri = task2
|
Loading…
Reference in New Issue