1
2
3
4
5
6
7
8
9
10
11
12
13
14 __doc__="""Utils
15
16 General Utility function module
17
18 $Id: Utils.py,v 1.15 2004/04/04 02:22:38 edahl Exp $"""
19
20 __version__ = "$Revision: 1.15 $"[11:-2]
21
22 import sys
23 import os
24 import types
25 import struct
26 import logging
27 import re
28 import socket
29 from sets import Set
30 log = logging.getLogger("zen.Utils")
31
32 from Acquisition import aq_base
33 from zExceptions import NotFound
34 from AccessControl import getSecurityManager
35 from AccessControl import Unauthorized
36 from AccessControl.ZopeGuards import guarded_getattr
37 from ZODB.POSException import ConflictError
38 from Acquisition import Acquired, aq_inner, aq_parent, aq_base
39
40 from Products.ZenUtils.Exceptions import ZenPathError
41
56
57
59 """Setup logging to log to a browser using a request object."""
60 handler = logging.StreamHandler(stream)
61 handler.setFormatter(HtmlFormatter())
62 rlog = logging.getLogger()
63 rlog.addHandler(handler)
64 rlog.setLevel(logging.ERROR)
65 zlog = logging.getLogger("zen")
66 zlog.setLevel(logging.INFO)
67 return handler
68
69
71 """Clear our web logger."""
72 rlog = logging.getLogger()
73 rlog.removeHandler(handler)
74
75
77 """Convert a number to its human readable form. ie: 4GB, 4MB, etc.
78 """
79 units = ('B','KB','MB','GB','TB','PB')
80 numb = float(numb)
81 sign = 1
82 if numb < 0:
83 numb = abs(numb)
84 sign = -1
85 for unit in units:
86 if numb < divby: break
87 numb /= divby
88 return "%.1f%s" % (numb * sign, unit)
89
90
103
104
106 """Get a Zope object by its path (e.g. '/Devices/Server/Linux').
107 Mostly a stripdown of unrestrictedTraverse method from Zope 2.8.8.
108 """
109 if not path:
110 return base
111
112 _getattr = getattr
113 _none = None
114 marker = object()
115
116 if isinstance(path, str):
117
118 path = path.split('/')
119 else:
120 path = list(path)
121
122 REQUEST = {'TraversalRequestNameStack': path}
123 path.reverse()
124 path_pop=path.pop
125
126 if len(path) > 1 and not path[0]:
127
128 path.pop(0)
129
130 if restricted:
131 securityManager = getSecurityManager()
132 else:
133 securityManager = _none
134
135 if not path[-1]:
136
137 path_pop()
138 base = base.getPhysicalRoot()
139 if (restricted
140 and not securityManager.validate(None, None, None, base)):
141 raise Unauthorized, base
142
143 obj = base
144 while path:
145 name = path_pop()
146 __traceback_info__ = path, name
147
148 if name[0] == '_':
149
150 raise NotFound, name
151
152 if name == '..':
153 next = aq_parent(obj)
154 if next is not _none:
155 if restricted and not securityManager.validate(
156 obj, obj,name, next):
157 raise Unauthorized, name
158 obj = next
159 continue
160
161 bobo_traverse = _getattr(obj, '__bobo_traverse__', _none)
162 if bobo_traverse is not _none:
163 next = bobo_traverse(REQUEST, name)
164 if restricted:
165 if aq_base(next) is not next:
166
167
168 container = aq_parent(aq_inner(next))
169 elif _getattr(next, 'im_self', _none) is not _none:
170
171
172 container = next.im_self
173 elif _getattr(aq_base(obj), name, marker) == next:
174
175
176 container = obj
177 else:
178
179 container = _none
180 try:
181 validated = securityManager.validate(
182 obj, container, name, next)
183 except Unauthorized:
184
185
186
187
188
189 validated = 0
190 if container is _none and \
191 guarded_getattr(obj, name, marker) is next:
192 validated = 1
193 if not validated:
194 raise Unauthorized, name
195 else:
196 if restricted:
197 next = guarded_getattr(obj, name, marker)
198 else:
199 next = _getattr(obj, name, marker)
200
201
202
203
204
205
206
207
208 if next is marker:
209 try:
210 next=obj[name]
211 except AttributeError:
212
213
214 raise NotFound, name
215 if restricted and not securityManager.validate(
216 obj, obj, _none, next):
217 raise Unauthorized, name
218 obj = next
219 return obj
220
221
222
224 """perform issubclass using class name as string"""
225 if myclass.__name__ == className:
226 return 1
227 for mycl in myclass.__bases__:
228 if checkClass(mycl, className):
229 return 1
230
231
233 """look in sys.modules for our class"""
234 import sys
235 if sys.modules.has_key(productName):
236 mod = sys.modules[productName]
237 elif sys.modules.has_key("Products."+productName):
238 mod = sys.modules["Products."+productName]
239 else:
240 return None
241 if not classname:
242 classname = productName.split('.')[-1]
243 return getattr(mod,classname)
244
245
247 """Import a class from the module given.
248 """
249 try:
250 if not classname: classname = modulePath.split(".")[-1]
251 mod = __import__(modulePath, globals(), locals(), classname)
252 return getattr(mod, classname)
253 except AttributeError:
254 raise ImportError("failed importing class %s from module %s" % (
255 classname, modulePath))
256
257
263
264
266 """do a depth first search looking for objects that the function filter
267 returns as true. If decend is passed it will check to see if we
268 should keep going down or not"""
269 if not retobjs: retobjs = []
270 for obj in base.objectValues():
271 if not filter or filter(obj):
272 retobjs.append(obj)
273 if not decend or decend(obj):
274 retobjs = getSubObjects(obj, filter, decend, retobjs)
275 return retobjs
276
277
297
298
315 def filter(obj):
316 return isinstance(obj, ZenModelRM) and obj.id != "dmd"
317 return getSubObjectsMemo(base, filter=filter, decend=decend)
318
325
327 """build a zenpath in its string form"""
328 return "/" + "/".join(pathar)
329
332 """build and return the path to an object
333 based on a hierarchical name (ex /Mail/Mta) relative
334 to the root passed in. If lastfactory is passed the leaf object
335 will be created with it instead of factory.
336 relpath is the relationship within which we will recurse as
337 objects are created. Having the relationship in the path passed
338 is optional."""
339 path = zenpathsplit(name)
340 for id in path:
341 if id == relpath: continue
342 if getattr(aq_base(root), id, False):
343 nextroot = getattr(root, id)
344 else:
345 if id == path[-1]:
346 if lastrelpath: relpath = lastrelpath
347 if lastfactory: factory = lastfactory
348 if relpath and getattr(aq_base(root), relpath, False):
349 relobj = getattr(root, relpath)
350 if not getattr(aq_base(relobj), id, False):
351 log.debug("creating object with id %s in relation %s",
352 id, relobj.getId())
353 factory(relobj, id)
354 nextroot = relobj._getOb(id)
355 else:
356 log.debug("creating object with id %s", id)
357 factory(root, id)
358 nextroot = root._getOb(id)
359 root = nextroot
360 return root
361
362
382
383
394
395
396
398 """add the username and password to a url in the form
399 http://username:password@host/path"""
400 urlar = url.split('/')
401 if not username or not password or urlar[2].find('@') > -1:
402 return url
403 urlar[2] = "%s:%s@%s" % (username, password, urlar[2])
404 return "/".join(urlar)
405
406
407
409 """Make an id with valid url characters. Subs [^a-zA-Z0-9-_,.$\(\) ]
410 with subchar. If id then starts with subchar it is removed.
411 """
412 _prepId = re.compile(r'[^a-zA-Z0-9-_,.$\(\) ]').sub
413 _cleanend = re.compile(r"%s+$" % subchar).sub
414 if id is None:
415 raise ValueError('Ids can not be None')
416 if type(id) not in types.StringTypes:
417 id = str(id)
418 id = _prepId(subchar, id)
419 while id.startswith(subchar):
420 if len(id) > 1: id = id[1:]
421 else: id = "-"
422 id = _cleanend("",id)
423 return str(id)
424
425 -def sendEmail(emsg, host, port=25, usetls=0, usr='', pwd=''):
426 ''' Send an email. Return a tuple:
427 (sucess, message) where sucess is True or False.
428 '''
429 import smtplib
430 fromaddr = emsg['From']
431 toaddr = emsg['To'].split(', ')
432 try:
433 server = smtplib.SMTP(host, port)
434 if usetls:
435 server.ehlo()
436 server.starttls()
437 server.ehlo()
438 if len(usr): server.login(usr, pwd)
439 server.sendmail(fromaddr, toaddr, emsg.as_string())
440
441
442 try: server.quit()
443 except: pass
444 except (smtplib.SMTPException, socket.error):
445 result = (False, '%s - %s' % tuple(sys.exc_info()[:2]))
446 else:
447 result = (True, '')
448 return result
449
450
451 -def sendPage(recipient, msg, snppHost, snppPort):
452 ''' Send a page. Return a tuple: (success, message) where
453 sucess is True or False.
454 '''
455 import Pager
456 try:
457 rcpt = Pager.Recipient((recipient or '').strip())
458 pmsg = Pager.Message(msg)
459 page = Pager.Pager((rcpt,), pmsg, snppHost, snppPort)
460 page.send()
461 except (Pager.SNPPException, Pager.PagerException, socket.error):
462 result = (False, '%s - %s' % tuple(sys.exc_info()[:2]))
463 else:
464 result = (True, '')
465 return result
466
467
473
474
476 """Test to see if ip it should not be included in the network map."""
477 return re.search(getattr(context, 'zLocalIpAddresses', '^$'), ip)
478
480 """Test to see if ips on an in should not be included in the network map."""
481 return re.search(getattr(context, 'zLocalInterfaceNames', '^$'), intname)
482
483
485 """ Check to see if any of an object's base classes
486 are in a list of class names. Like isinstance(),
487 but without requiring a class to compare against.
488 """
489 finalnames = Set()
490 x = [obj.__class__]
491 while x:
492 thisclass = x.pop()
493 x.extend(thisclass.__bases__)
494 finalnames.add(thisclass.__name__)
495 return bool( Set(classnames).intersection(finalnames) )
496
497 -def resequence(context, objects, seqmap, origseq, REQUEST):
513 for i, obj in enumerate(sort(objects)):
514 obj.sequence = i
515 if REQUEST:
516 return context.callZenScreen(REQUEST)
517
519 ps = dmd.getPhysicalRoot().zport.portal_skins
520 layers = ps._objects
521 layers = filter(lambda x:getattr(ps, x['id'], False), layers)
522 ps._objects = tuple(layers)
523
525 nodet = '<Node id="%s" prop="%s" icon="%s" color="%s"/>'
526 edget = '<Edge fromID="%s" toID="%s"/>'
527 xmlels = ['<Start name="%s" url="%s"/>' % start]
528 nodeels = []
529 edgeels = []
530 for a, b in edges:
531 node1 = nodet % (a[0], a[0], a[1], a[2])
532 node2 = nodet % (b[0], b[0], b[1], b[2])
533 edge1 = edget % (a[0], b[0])
534 if node1 not in nodeels: nodeels.append(node1)
535 if node2 not in nodeels: nodeels.append(node2)
536 if edge1 not in edgeels: edgeels.append(edge1)
537 xmlels.extend(nodeels)
538 xmlels.extend(edgeels)
539 xmldoc = "<graph>%s</graph>" % ''.join(list(xmlels))
540 return xmldoc
541
545
547 """
548 IE puts the POST content in one place in the REQUEST object, and Firefox in
549 another. Thus we need to try both.
550 """
551 try:
552 try:
553
554 result = REQUEST._file.read()
555 except:
556
557 result = REQUEST.form.keys()[0]
558 except: result = ''
559 return result
560