syncevo-phone-config: reimplemented template generation and calendar+todo detection (MBC #1197)

--combined-calendar-task was broken: because "calendar+todo" was
tested with only an event, the test always passed when using the
settings for events, even if tasks cannot be exchanged using those
settings. If it had worked and had been essential to get correct
results, the option should have been enabled by default.

The new implementation of combined calendar+todo storage works
differently, without increasing the number of tests that need to
be run when searching for complete settings:
- detect settings for "calendar" using VEVENT as test data
- detect settings for "todo" using VTODO as test data
- if uri identical, configure a "calendar+todo" source instead of
  separate "calendar" and "todo"

Note that this hasn't been tested yet.

The --combined-calendar-task option is thus obsolete and was removed.

The template generation was rewritten and now prints the template
to stdout. While doing this, some more changes were made:
- "type" is always set, even if using default data formats,
  because "default" data formats are a bit underspecified and it
  is better to be explicit about what worked
- previously, "type" did not distinguish between events and tasks
  because it omitted the "calendar:" and "todo:" type part
- the template is printed if and only if --advanced is enabled,
  because only then is the result reliable; disabling it makes
  little sense when printing to stdout, so --create-template was
  removed

The generated config is no longer derived from the 'Nokia 7210c'
template. Instead the "SyncEvolution Client" template is used, because
it does not contain a potentially unused "calendar+todo" source.
The same fix for missing "calendar/todo" in "type" also had to
be applied to to the created config.

The syncevo-phone-config tool used source names that differed from the
syncevolution command line, for example "contact" was used instead of
"addressbook". This was not only making the code more complex (it had
two different ways to map "contact" to "addressbook"), it was also
exposed to users via the --source option. Now the same
addressbook/calendar/memo/todo names as in the rest of the
SyncEvolution command line are used.

This patch also includes quite a bit of code, language and output
cleanup. The code still isn't as pythonic as it could be, though.
This commit is contained in:
Patrick Ohly 2010-04-23 21:38:26 +02:00
parent ea3fafe99c
commit 07e74b9996

View file

@ -26,15 +26,21 @@ import shutil
import ConfigParser
import glob
# source names as commonly used in SyncEvolution
allSources = ['addressbook', 'calendar', 'todo', 'memo', 'calendar+todo']
# valid SyncMLVersion values
allVersions = ['1.2', '1.1', '1.0']
########################### cmdline options ##########################################
parser = optparse.OptionParser()
parser.add_option("-b", "--bt-address", action = "store", type = "string",
dest = "btaddr", help = "The Bluetooth mac address for the testing phone", default = "")
parser.add_option ("-p", "--proto-version", action = "store", type = "string",
dest="version", help = "The SyncML protocal version for testing, can be one of 1.0|1.1|1.2, by default it will try all versions one by one"
,default = "")
parser.add_option ("-p", "--protocol-version", action = "store", type = "string",
dest="version", help = "The SyncML protocal version for testing, can be one of " +
"|".join(allVersions) + ", by default it will try all versions one by one",
default = "")
parser.add_option ("-s", "--source", action = "store", type = "string", dest=
"source", help = "The local database for testing, can be one of contact|calendar|task|memo|calendar+task, by default it will try all except calendar+task, use --combined-calendar-task to activate",
"source", help = "The local database for testing, can be one of " + "|".join(allSources),
default = "")
parser.add_option ("-u", "--uri", action = "store", type = "string", dest =
"uri", help = "The URI for testing the selected source, invalid when no specific source is selected via --source", default = "")
@ -48,34 +54,28 @@ parser.add_option ("", "--without-ctcap", action = "store_true", default =False,
dest = "ctcap", help = "Testing without sending CTCap information")
parser.add_option ("-v", "--verbose", action = "count",
dest = "verbose", help = "Increase amount of output")
parser.add_option ("", "--combined-calendar-task", action = "store_true",
default = False, dest = "combined", help = "Testing the combined calendar, task data source")
parser.add_option ("-a", "--advanced", action = "store_true", default = False,
dest = "advanced", help = "More extensive test with sending/receving data, WARNING: will destroy your data on the tested phone")
parser.add_option("-c", "--create-config", action ="store", type = "string",
dest = "create", help = "If set, a configuration file with the name will be created based on the testing result",
default ="")
parser.add_option("-l", "--create-template", action ="store", type = "string",
dest = "template", help = "If set, a template for the found configuration with the name will be created, it is a folder located in current working directory",default ="")
(options, args) = parser.parse_args()
####################semantic check for cmdline options #######################################
if (not options.btaddr):
parser.error ("Please input the bluetooth address for the testing phone by -b")
if (options.version and options.version not in ['1.1', '1.2', '1.3']):
parser.error("option -p can only be one of 1.0|1.1|1.2")
if (options.source and options.source not in ['contact', 'calendar', 'task',
'memo', 'calendar+task']):
parser.error("option -s can only be one of contact|calendar|task|memo|calendar+task")
if (options.uri and not options.source and not options.combined):
parser.error ("options -u must work with -s")
if (options.type and not options.source):
parser.error ("options -t must work with -s")
if not options.btaddr:
parser.error ("Please provide the Bluetooth MAC address for the phone with -b/--bt-address.")
if options.version and options.version not in allVersions:
parser.error("Option -p/--protocol-version can only be one of " + "|".join(allVersions) + ".")
if options.source and options.source not in allContacts:
parser.error("Option -s/--source can only be one of " + "|".join(allContacts) + ".")
if options.uri and not options.source:
parser.error ("Option -u/--uri only works in combination with -s/--source.")
if options.type and not options.source:
parser.error ("Option -t/--type only works in combination with -s/--source.")
#######################some global parameters ######################
syncevoCmd = 'syncevolution'
configName = 'test-phone' # inside temporary testConfig dir
templateName = '"Nokia 7210c"'
# real paths set in main() inside temporary directory
testFolder = '/dev/null/data'
testResult = '/dev/null/cache'
@ -121,12 +121,6 @@ class ConfigurationParameter:
self.type == config.type)
###################### utility functions ####################
def isCombinedSource (source):
return source == 'calendar+task'
def getSubSources (source):
return ['calendar','task']
def clearLocalSyncData(sources):
for source in sources:
dirname = "%s/%s" % (testFolder, source)
@ -140,7 +134,7 @@ def insertLocalSyncData(sources, type):
runCommand(cmd)
def getTestCase(source, type):
if (source == 'contact' and (type == 'text/vcard:3.0' or type == 'text/vcard')):
if (source == 'addressbook' and (type == 'text/vcard:3.0' or type == 'text/vcard')):
return "BEGIN:VCARD\n"\
+"VERSION:3.0\n"\
+"TITLE:tester\n"\
@ -151,7 +145,7 @@ def getTestCase(source, type):
+"X-MOZILLA-HTML:FALSE\n"\
+"NOTE:test-phone\n"\
+"END:VCARD\n"
if (source == 'contact' and (type == 'text/x-vcard:2.1' or type == 'text/x-vcard')):
if (source == 'addressbook' and (type == 'text/x-vcard:2.1' or type == 'text/x-vcard')):
return "BEGIN:VCARD\n"\
+"VERSION:2.1\n"\
+"TITLE:tester\n"\
@ -189,7 +183,7 @@ def getTestCase(source, type):
+"DESCRIPTION:let's talkREVISION\n"\
+"END:VEVENT\n"\
+"END:VCALENDAR\n"
if (source == 'task' and (type == 'text/calendar:2.0' or type == 'text/calendar')):
if (source == 'todo' and (type == 'text/calendar:2.0' or type == 'text/calendar')):
return "BEGIN:VCALENDAR\n"\
+"PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"\
+"VERSION:2.0\n"\
@ -202,7 +196,7 @@ def getTestCase(source, type):
+"LAST-MODIFIED:20060417T173712\n"\
+"END:VTODO\n"\
+"END:VCALENDAR\n"
if (source == 'task' and (type == 'text/x-vcalendar:1.0' or type == 'text/x-vcalendar')):
if (source == 'todo' and (type == 'text/x-vcalendar:1.0' or type == 'text/x-vcalendar')):
return "BEGIN:VCALENDAR\n"\
+"PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"\
+"VERSION:1.0\n"\
@ -222,17 +216,17 @@ def getTestCase(source, type):
# Get the keyword to be matched with for each test case
def getTestCaseKeywords(source, type):
if (source == 'contact' and (type == 'text/vcard:3.0' or type == 'text/vcard')):
if (source == 'addressbook' and (type == 'text/vcard:3.0' or type == 'text/vcard')):
return ["VCARD", "TITLE:tester", "Doe", "John"]
if (source == 'contact' and (type == 'text/x-vcard:2.1' or type == 'text/x-vcard')):
if (source == 'addressbook' and (type == 'text/x-vcard:2.1' or type == 'text/x-vcard')):
return ["VCARD", "TITLE:tester", "Doe", "John"]
if (source == 'calendar' and (type == 'text/calendar:2.0' or type == 'text/calendar')):
return ["VCALENDAR", "VEVENT", "phone meeting", "my office"]
if (source == 'calendar' and (type =='text/x-vcalendar:1.0' or type == 'text/x-vcalendar')):
return ["VCALENDAR", "VEVENT", "phone meeting", "my office"]
if (source == 'task' and (type == 'text/calendar:2.0' or type == 'text/calendar')):
if (source == 'todo' and (type == 'text/calendar:2.0' or type == 'text/calendar')):
return ["VCALENDAR", "VTODO", "do me"]
if (source == 'task' and (type == 'text/x-vcalendar:1.0' or type == 'text/x-vcalendar')):
if (source == 'todo' and (type == 'text/x-vcalendar:1.0' or type == 'text/x-vcalendar')):
return ["VCALENDAR", "VTODO", "do me"]
if (source == 'memo'):
return ["SUMMARY"]
@ -320,38 +314,52 @@ def rm_r(dirname):
if os.path.isdir(dirname):
shutil.rmtree(dirname)
def hash2ini(hash):
"""convert key/value pairs into .ini file without sections"""
res = []
for key, value in hash.items():
res.append("%s = %s" % (key, value))
return "\n".join(res)
##############################TestConfiguration##################################
class TestingConfiguration():
def __init__(self, versions, sources, uris, types, ctcaps, identifiers, btaddr):
self.allSources = ['contact', 'calendar', 'task', 'memo', 'calendar+task']
if (versions):
self.versions = versions
else:
self.versions = ["1.2", "1.1", "1.0"]
if (sources):
self.versions = allVersions
# If "calendar+todo" is tested, then "calendar" and "todo"
# must be tested first. If they lead to the same result,
# then they have to be combined for "calendar+todo".
# "calendar+todo" itself is never tested directly.
if sources:
self.sources = sources
else:
self.sources = ["contact", "calendar", "task", "memo"]
if (options.combined):
self.sources.insert (0, "calendar+task")
self.sources = allSources
if "calendar+todo" in self.sources:
self.sources.remove("calendar+todo")
if not "calendar" in self.sources:
self.sources.append("calendar")
if not "todo" in self.sources:
self.sources.append("todo")
if (uris):
self.uris = uris
else:
self.uris = {}
self.uris['contact'] = ['Contact', 'contact', 'Contacts', 'contacts', 'Addressbook', 'addressbook']
self.uris['addressbook'] = ['Contact', 'contact', 'Contacts', 'contacts', 'Addressbook', 'addressbook']
self.uris['calendar'] = ['Calendar', 'calendar', 'Agenda','agenda']
self.uris['task'] = self.uris['calendar'] + ['Task', 'task', 'Tasks', 'tasks', 'Todo','todo']
self.uris['todo'] = ['Task', 'task', 'Tasks', 'tasks', 'Todo','todo'] + self.uris['calendar']
self.uris['memo'] = ['Memo', 'memo', 'Notes', 'notes', 'Note', 'note']
self.uris['calendar+task'] = self.uris['calendar'] + self.uris['task']
if (types):
self.types = types
else:
self.types = {}
self.types['contact'] = ['text/vcard:3.0', 'text/x-vcard:2.1']
self.types['calendar'] = self.types['task'] = ['text/calendar:2.0', 'text/x-vcalendar:1.0']
self.types['memo'] = ['text/plain:1.0',
'text/calendar:2.0', 'text/x-vcalendar:1.0']
self.types['calendar+task'] = self.types['calendar']
self.types['addressbook'] = ['text/vcard:3.0', 'text/x-vcard:2.1']
self.types['calendar'] = self.types['todo'] = ['text/calendar:2.0', 'text/x-vcalendar:1.0']
self.types['memo'] = ['text/plain:1.0']
if (ctcaps):
self.ctcaps = ctcaps
@ -364,19 +372,6 @@ class TestingConfiguration():
self.btaddr = btaddr
#map between user perceivable source name and the underlying source name in SyncEvolution
def getLocalSourceName (self, source):
if (source == 'contact'):
return 'addressbook'
if (source == 'calendar'):
return 'calendar'
if (source == 'task'):
return 'todo'
if (source == 'memo'):
return 'memo'
if (source =='calendar+task'):
return 'calendar+todo'
#before each configuration is really tested, prepare is called.
#returns True if we decide current configuration need not be tested
def prepare (self, allconfigs, curconfig):
@ -394,8 +389,6 @@ class TestingConfiguration():
if (config):
if ( (config.source == self.source) or (config.identifier != self.identifier ) or (config.ctcap != self.ctcap) or (config.version != self.version)):
skip = True
if ((self.source == 'calendar' or self.source == 'task') and isCombinedSource(config.source)):
skip = True
if (skip):
if (options.verbose > 1):
print "Test %d/%d skipped because already found a working configuration" % (curconfig, allconfigs)
@ -428,23 +421,11 @@ class TestingConfiguration():
rm_r(testConfig)
cmdPrefix = "XDG_CACHE_HOME=%s XDG_CONFIG_HOME=%s " %(testResult, testConfig)
syncevoTest = "%s %s --daemon=no" % (cmdPrefix, syncevoCmd)
runCommand ("%s -c -l %s %s" % (syncevoTest, templateName, configName))
runSources ={'contact':'addressbook', 'calendar':'calendar', 'task':'todo', 'memo':'memo', 'calendar+task':'calendar+todo'}
runCommand ("%s -c --template 'SyncEvolution Client' --sync-property peerIsClient=1 %s" % (syncevoTest, configName))
# set the local database
if (isCombinedSource(self.source)):
for s in getSubSources(self.source):
filesource = testFolder+'/'+s
configCmd = "%s --configure --source-property evolutionsource='file:///%s' %s %s" %(syncevoTest, filesource, configName, runSources[s])
runCommand(configCmd)
subSources = getSubSources(self.source)
filesource = runSources[subSources[0]] +',' + runSources[subSources[1]]
configCmd = "%s --configure --source-property evolutionsource=%s %s %s" %(syncevoTest, filesource, configName, runSources[self.source])
runCommand(configCmd)
else:
filesource = testFolder+'/'+self.source
configCmd = "%s --configure --source-property evolutionsource='file:///%s' %s %s" %(syncevoTest, filesource, configName, runSources[self.source])
runCommand (configCmd)
filesource = testFolder+'/'+self.source
configCmd = "%s --configure --source-property evolutionsource='file:///%s' %s %s" %(syncevoTest, filesource, configName, self.source)
runCommand (configCmd)
configCmd = "%s --configure --sync-property logLevel=5 --sync-property SyncURL=obex-bt://%s --sync-property SyncMLVersion=%s %s" % (syncevoTest, self.btaddr,self.version, configName)
runCommand (configCmd)
@ -453,24 +434,17 @@ class TestingConfiguration():
configCmd = "%s --configure --sync-property remoteIdentifier='%s' %s" %(syncevoTest, self.identifier, configName)
runCommand (configCmd)
if (isCombinedSource(self.source)):
configCmd = "%s --configure --source-property type=%s --source-property uri=%s %s %s" %(syncevoTest, "virtual:"+self.type.partition(':')[0], self.uri, configName, runSources[self.source])
runCommand (configCmd)
for s in getSubSources(self.source):
configCmd = "%s --configure --source-property type=%s %s %s" %(syncevoTest, "file:"+self.type, configName, runSources[s])
runCommand (configCmd)
else:
configCmd = "%s --configure --source-property type=%s --source-property uri=%s %s %s" %(syncevoTest, "file:"+self.type, self.uri, configName, runSources[self.source])
runCommand (configCmd)
configCmd = "%s --configure --source-property type=%s --source-property uri=%s %s %s" %(syncevoTest, "file:"+self.type, self.uri, configName, self.source)
runCommand (configCmd)
""" start the sync session """
if (not self.ctcap):
cmdPrefix += "SYNCEVOLUTION_NOCTCAP=t "
cmdPrefix += "SYNCEVOLUTION_NO_SYNC_SIGNALS=1"
syncCmd = " ".join((cmdPrefix, syncevoCmd, "--daemon=no", configName, runSources[self.source]))
syncCmd = " ".join((cmdPrefix, syncevoCmd, "--daemon=no", configName, self.source))
(status,interrupt) = runSync(syncCmd)
if (options.advanced and status and not interrupt):
(status,interrupt)= self.advancedTestWithCurrentConfiguration(runSources)
(status,interrupt)= self.advancedTestWithCurrentConfiguration()
return (status, interrupt)
'''Basic test for sending/receiving data
@ -484,15 +458,12 @@ class TestingConfiguration():
implements the semantics correctly as specified in the spec. Otherwise the results will
be undefined.
'''
def advancedTestWithCurrentConfiguration (self, runSources):
def advancedTestWithCurrentConfiguration (self):
"""
Sending/receving real data for basic sanity test
"""
sources = []
if (isCombinedSource (self.source)):
sources = getSubSources (self.source)
else:
sources.append(self.source)
sources.append(self.source)
#step 1: clean the data both locally and remotely using a 'slow-sync' and 'two-way'
clearLocalSyncData(sources)
@ -500,26 +471,26 @@ class TestingConfiguration():
if (not self.ctcap):
cmdPrefix += "SYNCEVOLUTION_NOCTCAP=t "
syncevoTest = "%s %s --daemon=no" % (cmdPrefix, syncevoCmd)
syncCmd = "%s --sync slow %s %s" % (syncevoTest, configName, runSources[self.source])
syncCmd = "%s --sync slow %s %s" % (syncevoTest, configName, self.source)
status,interrupt = runSync(syncCmd)
if (not status or interrupt):
return (status, interrupt)
clearLocalSyncData(sources)
syncCmd = "%s --sync two-way %s %s" % (syncevoTest, configName, runSources[self.source])
syncCmd = "%s --sync two-way %s %s" % (syncevoTest, configName, self.source)
status,interrupt = runSync(syncCmd)
if (not status or interrupt):
return (status, interrupt)
#step 2: insert testcase to local data and sync with 'two-way'
insertLocalSyncData(sources, self.type)
syncCmd = "%s --sync two-way %s %s" % (syncevoTest, configName, runSources[self.source])
syncCmd = "%s --sync two-way %s %s" % (syncevoTest, configName, self.source)
status,interrupt = runSync(syncCmd)
if (not status or interrupt):
return (status, interrupt)
#step 3: delete local data and sync with 'slow-sync'
clearLocalSyncData(sources)
syncCmd = "%s --sync slow %s %s" % (syncevoTest, configName, runSources[self.source])
syncCmd = "%s --sync slow %s %s" % (syncevoTest, configName, self.source)
status,interrupt = runSync(syncCmd)
if (not status or interrupt):
return (status, interrupt)
@ -593,26 +564,14 @@ class TestingConfiguration():
print "Configuration parameter for %s:" % (source,)
config.printMe()
#We did not tested with calendar+task but we have found configuration
#for calendar or task
if (options.combined == False):
s = getSubSources(self.source)
try:
if (self.wConfigs[s[0]] or self.wConfigs[s[1]]):
print ""
print "Note some phones have combined calendar and task"
print "you might run the tool with --combined-calendar-task"
print "to detect this behavior"
#restrict to only two subsources
if (self.wConfigs[s[0]] and self.wConfigs[s[0]].equalWith (self.wConfigs[s[1]])):
print "This phone likely works with a combined calendar and task"
print "because they have identical configurations"
except:
pass
if (not found):
print "No working configuration found"
else:
have_combined = \
self.wConfigs.has_key('calendar') and \
self.wConfigs.has_key('todo') and \
self.wConfigs['calendar'].uri == self.wConfigs['todo'].uri
if (options.create):
#first remove the previous configuration if there is a configuration with the same name
create = options.create
@ -621,12 +580,13 @@ class TestingConfiguration():
runCommand (cmd)
except:
pass
#create the configuration based on the template
cmd = "%s -c -l %s %s" %(syncevoCmd, templateName, create)
cmd = "%s -c --template 'SyncEvolution Client' --sync-property peerIsClient=1 %s" %(syncevoCmd, create)
runCommand (cmd)
#disable all sources by default
for source in self.allSources:
cmd = "%s -c --source-property sync='disabled' %s %s" %(syncevoCmd, create, self.getLocalSourceName(source))
for source in allSources:
if source == 'calendar+todo':
continue
cmd = "%s -c --source-property sync='disabled' %s %s" %(syncevoCmd, create, source)
runCommand(cmd)
syncCreated = False
@ -639,75 +599,76 @@ class TestingConfiguration():
runCommand (cmd)
#set each source parameter
ltype = config.type.split(':')[0]
if(isCombinedSource (config.source)):
ltype = 'virtual:'+ltype
cmd = "%s --configure --source-property sync='two-way' --source-property URI='%s' --source-property type='%s' '%s' '%s'" %(syncevoCmd, config.uri, ltype, create, self.getLocalSourceName(config.source))
cmd = "%s --configure --source-property sync='two-way' --source-property URI='%s' --source-property type='%s:%s' '%s' '%s'" %(syncevoCmd, config.uri, source, ltype, create, config.source)
runCommand(cmd)
if have_combined:
ltype = self.wConfigs['calendar'].type.split(':')[0]
uri = self.wConfigs['calendar'].uri
cmd = "%s --configure --source-property sync='two-way' --source-property URI='%s' --source-property type='virtual:%s' '%s' calendar+todo" %(syncevoCmd, uri, ltype, create)
runCommand(cmd)
for source in ('calendar', 'todo'):
cmd = "%s --configure --source-property sync='none' --source-property URI= '%s' calendar+todo" %(syncevoCmd, uri, create)
runCommand(cmd)
if (options.template):
template = options.template
configini = "peerIsClient = 1\n"
sourceConfiginis={}
syncCreated = False
for source,config in self.wConfigs.items():
if(config):
if (not syncCreated):
if (config.identifier):
configini += "remoteIdentifier = '%s'\n" %(config.identifier)
if (config.version != '1.2'):
configini += "SyncMLVersion = '%s'\n" %(config.version)
syncCreated = True
sourceini = "sync = two-way\n"
if (isCombinedSource (source)):
sourceini += "evolutionsource = calendar,todo\n"
sourceini += "uri = %s\n" %(config.uri)
sourceini += "type = virtual:%s\n" %(config.type.split(':')[0])
sourceConfiginis[self.getLocalSourceName(source)]=sourceini
#disable the sub datasoruce
for s in getSubSources(source):
sourceini = "sync = none\n"
sourceConfiginis[self.getLocalSourceName(s)]=sourceini
else:
sourceini += "uri = %s\n" %(config.uri)
sourceConfiginis[self.getLocalSourceName(source)]=sourceini
defualtTypes = ["text/x-vcard:2.1", "text/calendar:2.0", "text/plain:1.0"]
if (config.type not in defualtTypes):
sourceini += "type = %s\n" %(config.type)
fingerprint=''
description=''
templateini = "fingerprint = %s\ndescription = %s\n" %(fingerprint,description)
#write to directory
shutil.rmdir(template)
os.makedirs("%s/sources" % template)
runCommand(cmd)
cmd = "echo '%s' >%s/config.ini; echo ''" %(configini, template)
runCommand(cmd)
cmd = "echo '%s' >%s/template.ini; echo ''" %(templateini, template)
runCommand(cmd)
for s,ini in sourceConfiginis.items():
cmd = "mkdir %s/sources/%s; echo''" %(template, s)
runCommand(cmd)
cmd = "echo '%s' >%s/sources/%s/config.ini; echo ''" %(ini,template,s)
runCommand(cmd)
if (options.advanced):
print ""
print "We have conducted basic test by sending and receiving"
print "data for the phone"
print "data to the phone. You can help the SyncEvolution project"
print "and other users by submitting the following configuration"
print "template at http://syncevolution.org/wiki/phone-compatibility-template"
print ""
configini = { "peerIsClient": "1" }
sourceConfigInis = {}
syncCreated = False
if (config.identifier):
configini["remoteIdentifier"] = config.identifier
if (config.version != '1.2'):
configini["SyncMLVersion"] = config.version
for source,config in self.wConfigs.items():
if(config):
sourceini = {}
sourceini["sync"] = "two-way"
sourceini["uri"] = config.uri
sourceini["type"] = "%s:%s" % (source, config.type.split(':')[0])
sourceConfigInis[source] = sourceini
# create 'calendar+todo' entry, disable separate 'calendar' and 'todo'?
if have_combined:
sourceini = {}
sourceini["evolutionsource"] = "calendar,todo"
sourceini["uri"] = self.wConfigs['calendar'].uri
sourceini["type"] = "virtual:%s" % self.wConfigs['calendar'].type.split(':')[0]
sourceConfigInis['calendar+todo'] = sourceini
# disable the sub datasources
for source in ('calendar', 'todo'):
sourceConfigInis[source]["sync"] = "none"
sourceConfigInis[source].remove("uri")
# print template to stdout
sep = "--------------------> snip <--------------------"
print sep
print "=== template.ini ==="
print "fingerprint = <Model> <Manufacturer>"
print "=== config.ini ==="
print hash2ini(configini)
for source, configini in sourceConfigInis.items():
print "=== sources/%s/config.ini ===" % source
print hash2ini(configini)
print sep
else:
print ""
print "We just conducted minimum test by syncing with the phone"
print "without checking received data. You can use --advanced"
print "to conduct basic sending/receiving test against your phone"
print "without checking received data. For more reliable result,"
print "use the --advanced option, but beware that it will overwrite"
print "contacts, events, tasks and memos on the phone."
if (options.create):
print "Created configuration %s" %(options.create)
print "You may start syncing with syncevolution %s" %(options.create)
if (options.template):
print "Created configuration template %s" %(options.template)
print "It is located as folder %s in current directory" %(options.template)
print ""
print "Created configuration: %s" %(options.create)
print "You may start syncing with: syncevolution %s" %(options.create)
def main():
versions = []