Package ZenRelations :: Module ImportRM
[hide private]
[frames] | no frames]

Source Code for Module ZenRelations.ImportRM

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 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
46 - def context(self):
47 return self.objstack[-1]
48 49
50 - def cleanattrs(self, attrs):
51 myattrs = {} 52 for key, val in attrs.items(): 53 myattrs[key] = str(val) 54 return myattrs
55 56
57 - def startElement(self, name, attrs):
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
82 - def endElement(self, name):
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
101 - def characters(self, chars):
102 self.charvalue += saxutils.unescape(chars)
103 104
105 - def createObject(self, attrs):
106 """create an object and set it into its container""" 107 id = attrs.get('id') 108 obj = None 109 try: 110 if id.startswith("/"): 111 obj = getObjByPath(self.app, id) 112 else: 113 obj = self.context()._getOb(id) 114 except (KeyError, AttributeError, NotFound): pass 115 if obj is None: 116 klass = importClass(attrs.get('module'), attrs.get('class')) 117 if id.find("/") > -1: 118 contextpath, id = os.path.split(id) 119 self.objstack.append( 120 getObjByPath(self.context(), contextpath)) 121 obj = klass(id) 122 self.context()._setObject(obj.id, obj) 123 obj = self.context()._getOb(obj.id) 124 self.objectnumber += 1 125 if self.objectnumber % 5000 == 0: transaction.savepoint() 126 self.log.debug("Added object %s to database" % obj.getPrimaryId()) 127 else: 128 self.log.warn("Object %s already exists skipping" % id) 129 return obj
130 131
132 - def setProperty(self, obj, attrs, value):
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 167 168 182 #raise 183 184 185
186 - def buildOptions(self):
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
210 - def loadObjectFromXML(self, objstack=None, xmlfile=''):
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 # check to see if we're getting the XML from a URL ... 227 schema, host, path, null, null, null = urlparse(xmlfile) 228 if schema and host: 229 self.infile = urllib2.urlopen(xmlfile) 230 # ... or from a file on the file system 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
242 - def loadDatabase(self):
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
248 - def commit(self):
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