1 """
2 Represents a group of conduits
3
4 Copyright: John Stowers, 2007
5 License: GPLv2
6 """
7 import traceback
8 import os
9 import xml.dom.minidom
10 import gobject
11 import logging
12 log = logging.getLogger("SyncSet")
13
14 import conduit
15 import conduit.Conduit as Conduit
16 import conduit.Settings as Settings
17
18
19
20 SETTINGS_VERSION = "1"
21
23 """
24 Represents a group of conduits
25 """
26 __gsignals__ = {
27
28
29 "conduit-added" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [
30 gobject.TYPE_PYOBJECT]),
31 "conduit-removed" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [
32 gobject.TYPE_PYOBJECT]),
33 }
34
35 - def __init__(self, moduleManager, syncManager, xmlSettingFilePath="settings.xml"):
36 gobject.GObject.__init__(self)
37
38 self.moduleManager = moduleManager
39 self.syncManager = syncManager
40 self.xmlSettingFilePath = xmlSettingFilePath
41 self.conduits = []
42
43 self.moduleManager.connect("dataprovider-available", self.on_dataprovider_available_unavailable)
44 self.moduleManager.connect("dataprovider-unavailable", self.on_dataprovider_available_unavailable)
45
46
47
48 self.moduleManager.emit("syncset-added", self)
49
54
56 """
57 Adds the dataprovider back onto the canvas at the specifed
58 location and configures it with the given settings
59 """
60 log.debug("Restoring %s to (source=%s)" % (wrapperKey,trySourceFirst))
61 wrapper = self.moduleManager.get_module_wrapper_with_instance(wrapperKey)
62 wrapper.set_name(dpName)
63 if wrapper is not None:
64 for i in dpxml.childNodes:
65 if i.nodeType == i.ELEMENT_NODE and i.localName == "configuration":
66 wrapper.set_configuration_xml(xmltext=i.toxml())
67 cond.add_dataprovider(wrapper, trySourceFirst)
68
84
85 - def emit(self, *args):
86 """
87 Override the gobject signal emission so that all signals are emitted
88 from the main loop on an idle handler
89 """
90 gobject.idle_add(gobject.GObject.emit,self,*args)
91
93 self.conduits.append(cond)
94 self.emit("conduit-added", cond)
95
100
103
105 return self.conduits[index]
106
107 - def index (self, conduit):
109
111 return len(self.conduits)
112
116
118 """
119 Saves the synchronisation settings (icluding all dataproviders and how
120 they are connected) to an xml file so that the 'sync set' can
121 be restored later
122 """
123 if xmlSettingFilePath == None:
124 xmlSettingFilePath = self.xmlSettingFilePath
125 log.info("Saving Sync Set to %s" % self.xmlSettingFilePath)
126
127
128 doc = xml.dom.minidom.Document()
129 rootxml = doc.createElement("conduit-application")
130 rootxml.setAttribute("application-version", conduit.VERSION)
131 rootxml.setAttribute("settings-version", SETTINGS_VERSION)
132 doc.appendChild(rootxml)
133
134
135 for cond in self.conduits:
136 conduitxml = doc.createElement("conduit")
137 conduitxml.setAttribute("uid",cond.uid)
138 conduitxml.setAttribute("twoway",str(cond.is_two_way()))
139 conduitxml.setAttribute("autosync",str(cond.do_auto_sync()))
140 for policyName in Conduit.CONFLICT_POLICY_NAMES:
141 conduitxml.setAttribute(
142 "%s_policy" % policyName,
143 cond.get_policy(policyName)
144 )
145 rootxml.appendChild(conduitxml)
146
147
148 source = cond.datasource
149 if source is not None:
150 sourcexml = doc.createElement("datasource")
151 sourcexml.setAttribute("key", source.get_key())
152 sourcexml.setAttribute("name", source.get_name())
153 conduitxml.appendChild(sourcexml)
154
155 configxml = xml.dom.minidom.parseString(source.get_configuration_xml())
156 sourcexml.appendChild(configxml.documentElement)
157
158
159 sinksxml = doc.createElement("datasinks")
160 for sink in cond.datasinks:
161 sinkxml = doc.createElement("datasink")
162 sinkxml.setAttribute("key", sink.get_key())
163 sinkxml.setAttribute("name", sink.get_name())
164 sinksxml.appendChild(sinkxml)
165
166 configxml = xml.dom.minidom.parseString(sink.get_configuration_xml())
167 sinkxml.appendChild(configxml.documentElement)
168 conduitxml.appendChild(sinksxml)
169
170
171 try:
172 file_object = open(xmlSettingFilePath, "w")
173 file_object.write(doc.toxml())
174
175 file_object.close()
176 except IOError, err:
177 log.warn("Could not save settings to %s (Error: %s)" % (xmlSettingFilePath, err.strerror))
178
180 """
181 Restores sync settings from the xml file
182 """
183 if xmlSettingFilePath == None:
184 xmlSettingFilePath = self.xmlSettingFilePath
185 log.info("Restoring Sync Set from %s" % xmlSettingFilePath)
186
187
188 if not os.path.isfile(xmlSettingFilePath):
189 log.info("%s not present" % xmlSettingFilePath)
190 return
191
192 try:
193
194 doc = xml.dom.minidom.parse(xmlSettingFilePath)
195
196
197 if doc.documentElement.hasAttribute("settings-version"):
198 if SETTINGS_VERSION != doc.documentElement.getAttribute("settings-version"):
199 log.info("%s xml file is incorrect version" % xmlSettingFilePath)
200 os.remove(xmlSettingFilePath)
201 return
202
203
204 for conds in doc.getElementsByTagName("conduit"):
205
206 cond = Conduit.Conduit(self.syncManager, conds.getAttribute("uid"))
207 self.add_conduit(cond)
208
209
210 twoway = Settings.string_to_bool(conds.getAttribute("twoway"))
211 if twoway == True:
212 cond.enable_two_way_sync()
213 auto = Settings.string_to_bool(conds.getAttribute("autosync"))
214 if auto == True:
215 cond.enable_auto_sync()
216 for policyName in Conduit.CONFLICT_POLICY_NAMES:
217 cond.set_policy(
218 policyName,
219 conds.getAttribute("%s_policy" % policyName)
220 )
221
222
223 for i in conds.childNodes:
224
225
226
227 if i.nodeType == i.ELEMENT_NODE and i.localName == "datasource":
228 key = i.getAttribute("key")
229 name = i.getAttribute("name")
230
231 if len(key) > 0:
232 self._restore_dataprovider(cond, key, name, i, True)
233
234 elif i.nodeType == i.ELEMENT_NODE and i.localName == "datasinks":
235
236 for sink in i.childNodes:
237 if sink.nodeType == sink.ELEMENT_NODE and sink.localName == "datasink":
238 key = sink.getAttribute("key")
239 name = sink.getAttribute("name")
240
241 if len(key) > 0:
242 self._restore_dataprovider(cond, key, name, sink, False)
243
244 except:
245 log.warn("Error parsing %s. Exception:\n%s" % (xmlSettingFilePath, traceback.format_exc()))
246 os.remove(xmlSettingFilePath)
247
254