1
2
3
4
5
6
7
8
9
10
11
12
13
14 __doc__="""ImportRM
15
16 Export RelationshipManager objects from a zope database
17
18 $Id: ImportRM.py,v 1.3 2003/10/03 16:16:01 edahl Exp $"""
19
20 __version__ = "$Revision: 1.3 $"[11:-2]
21
22 import sys
23 import os
24 import types
25 import urllib2
26 import transaction
27 from urlparse import urlparse
28 from xml.sax import make_parser, saxutils
29 from xml.sax.handler import ContentHandler
30
31 from Acquisition import aq_base
32 from zExceptions import NotFound
33
34 from DateTime import DateTime
35
36 from Products.ZenUtils.ZCmdBase import ZCmdBase
37 from Products.ZenUtils.Utils import importClass
38 from Products.ZenUtils.Utils import getObjByPath
39
40 from Products.ZenRelations.Exceptions import *
41
42 -class ImportRM(ZCmdBase, ContentHandler):
43
44 rootpath = ""
45
47 return self.objstack[-1]
48
49
51 myattrs = {}
52 for key, val in attrs.items():
53 myattrs[key] = str(val)
54 return myattrs
55
56
58 attrs = self.cleanattrs(attrs)
59 self.state = name
60 self.log.debug("tag %s, context %s", name, self.context().id)
61 if name == 'object':
62 obj = self.createObject(attrs)
63 if (not self.options.noindex
64 and hasattr(aq_base(obj), 'reIndex')
65 and not self.rootpath):
66 self.rootpath = obj.getPrimaryId()
67 self.objstack.append(obj)
68 elif name == 'tomanycont' or name == 'tomany':
69 self.objstack.append(self.context()._getOb(attrs['id']))
70 elif name == 'toone':
71 relname = attrs.get('id')
72 self.log.debug("toone %s, on object %s", relname, self.context().id)
73 rel = getattr(aq_base(self.context()),relname)
74 objid = attrs.get('objid')
75 self.addLink(rel, objid)
76 elif name == 'link':
77 self.addLink(self.context(), attrs['objid'])
78 elif name == 'property':
79 self.curattrs = attrs
80
81
83 if name in ('object', 'tomany', 'tomanycont'):
84 obj = self.objstack.pop()
85 if self.rootpath == obj.getPrimaryId():
86 self.log.info("calling reIndex %s", obj.getPrimaryId())
87 obj.reIndex()
88 self.rootpath = ""
89 elif name == 'objects':
90 self.log.info("End loading objects")
91 self.log.info("Processing links")
92 self.processLinks()
93 if not self.options.noCommit:
94 self.commit()
95 self.log.info("Loaded %d objects into database" % self.objectnumber)
96 elif name == 'property':
97 self.setProperty(self.context(), self.curattrs, self.charvalue)
98 self.charvalue = ""
99
100
102 self.charvalue += saxutils.unescape(chars)
103
104
130
131
133 """Set the value of a property on an object.
134 """
135 name = attrs.get('id')
136 proptype = attrs.get('type')
137 setter = attrs.get("setter",None)
138 self.log.debug("setting object %s att %s type %s value %s"
139 % (obj.id, name, proptype, value))
140 value = value.strip()
141 try: value = str(value)
142 except UnicodeEncodeError: pass
143 if proptype == 'selection':
144 try:
145 firstElement = getattr(obj, name)[0]
146 if type(firstElement) in types.StringTypes:
147 proptype = 'string'
148 except (TypeError, IndexError):
149 proptype = 'string'
150 if proptype == "date":
151 try: value = float(value)
152 except ValueError: pass
153 value = DateTime(value)
154 elif proptype != "string" and proptype != 'text':
155 try: value = eval(value)
156 except SyntaxError: pass
157 if not obj.hasProperty(name):
158 obj._setProperty(name, value, type=proptype, setter=setter)
159 else:
160 obj._updateProperty(name, value)
161
162
164 """build list of links to form after all objects have been created
165 make sure that we don't add other side of a bidirectional relation"""
166 self.links.append((rel.getPrimaryId(), objid))
167
168
170 """walk through all the links that we saved and link them up"""
171 for relid, objid in self.links:
172 try:
173 self.log.debug("Linking relation %s to object %s",
174 relid,objid)
175 rel = getObjByPath(self.app, relid)
176 obj = getObjByPath(self.app, objid)
177 if not rel.hasobject(obj):
178 rel.addRelation(obj)
179 except:
180 self.log.critical(
181 "Failed linking relation %s to object %s",relid,objid)
182
183
184
185
187 """basic options setup sub classes can add more options here"""
188 ZCmdBase.buildOptions(self)
189
190 self.parser.add_option('-i', '--infile',
191 dest="infile",
192 help="input file for import default is stdin")
193
194 self.parser.add_option('-x', '--commitCount',
195 dest='commitCount',
196 default=20,
197 type="int",
198 help='how many lines should be loaded before commit')
199
200 self.parser.add_option('--noindex',
201 dest='noindex',action="store_true",default=False,
202 help='Do not try to index data that was just loaded')
203
204 self.parser.add_option('-n', '--noCommit',
205 dest='noCommit',
206 action="store_true",
207 default=0,
208 help='Do not store changes to the Dmd (for debugging)')
209
211 """This method can be used to load data for the root of Zenoss (default
212 behavior) or it can be used to operate on a specific point in the
213 Zenoss hierarchy (ZODB).
214
215 Upon loading the XML file to be processed, the content of the XML file
216 is handled (processed) by the methods in this class.
217 """
218 if objstack:
219 self.objstack = [objstack]
220 else:
221 self.objstack = [self.app]
222 self.links = []
223 self.objectnumber = 0
224 self.charvalue = ""
225 if xmlfile:
226
227 schema, host, path, null, null, null = urlparse(xmlfile)
228 if schema and host:
229 self.infile = urllib2.urlopen(xmlfile)
230
231 else:
232 self.infile = open(xmlfile)
233 elif self.options.infile:
234 self.infile = open(self.options.infile)
235 else:
236 self.infile = sys.stdin
237 parser = make_parser()
238 parser.setContentHandler(self)
239 parser.parse(self.infile)
240 self.infile.close()
241
243 """The default behavior of loadObjectFromXML() will be to use the Zope
244 app object, and thus operatate on the whole of Zenoss.
245 """
246 self.loadObjectFromXML()
247
249 trans = transaction.get()
250 trans.note('Import from file %s using %s'
251 % (self.options.infile, self.__class__.__name__))
252 trans.commit()
253
254
255 if __name__ == '__main__':
256 im = ImportRM()
257 im.loadDatabase()
258