Module utils |
[hide private]
[frames] | no frames]

## Source Code for Module utils

      1
      2  import time, os, sys, types, traceback, re
      3  from xml.dom import Node
      4
      5  import math
      6
      7  nonTextToken = "\x00\t"
      8
      9
     10  # XXX Server Configuration
     11  use4Suite = 1
     12  if (use4Suite):
     13      try:
     14          from Ft.Xml.XPath import ParsedRelativeLocationPath, ParsedAbsoluteLocationPath, \
     15               ParsedStep, ParsedNodeTest, ParsedExpr, Compile, Context, \
     16               ParsedAbbreviatedAbsoluteLocationPath, ParsedAbbreviatedRelativeLocationPath, ParsedNodeTest
     17
     18      except:
     19          os.putenv('USE_MINIDOM', '1')
     20          from Ft.Xml.XPath import ParsedRelativeLocationPath, ParsedAbsoluteLocationPath, \
     21               ParsedStep, ParsedNodeTest, ParsedExpr, Compile
     22  else:
     23      from xml.xpath import *
     24
     25  elementType = Node.ELEMENT_NODE
     26  textType = Node.TEXT_NODE
     27
     28
     29 -def saxToString(data):
     30      txt = []
     31      for e in data:
     32          if (e[0] == "3"):
     33              if (len(txt) and txt[-1][-1] != ' ' and e[2].isalnum()):
     34                  txt.append(' ')
     35              txt.append(e[2:])
     36      txt = ''.join(txt)
     37      return txt
     38
     39 -def fixString(s):
     40      l = []
     41      for c in s:
     42          if (ord(c) > 31 or c in ['\n', '\t', '\r']):
     43              l.append(c)
     44      return ''.join(l)
     45
     46  if (0):
     47      from Ft.Xml.Domlette import NonvalidatingReaderBase
     48      class reader(NonvalidatingReaderBase):
     49          def fromString(self, str):
     50              try:
     51                  return self.parseString(str, 'urn:foo')
     52              except:
     53                  return self.parseString(fixString(str), 'urn:foo')

54 def fromStream(self, stream): 55 return self.parseString(stream.read(), 'urn:foo') 56 def releaseNode(self, node): 57 pass 58 else: 59 from xml.dom.minidom import parseString 60 class reader: 61 def fromString(self, s): 62 try: 63 return parseString(s) 64 except: 65 # Somewhere is possibly a fubar character 66 s = fixString(s) 67 return parseString(s) 68 def fromStream(self, s): 69 return self.fromString(s.read()) 70 def releaseNose(self, s): 71 pass 72 73 # --- Definitions --- 74
75 -def evaluateXPath(xp, dom):
76 if (use4Suite): 77 context = Context.Context(dom) 78 return xp.evaluate(context) 79 else: 80 return xp.evaluate(node)
81
82 -def flattenTexts(elem):
83 # recurse down tree and flatten all text nodes into one string. 84 # Use list + join() to avoid memory overhead in Python string addition 85 texts = [] 86 if (hasattr(elem, 'childNodes')): 87 for e in elem.childNodes: 88 if e.nodeType == textType: 89 texts.append(e.data) 90 elif e.nodeType == elementType: 91 # Recurse 92 texts.append(flattenTexts(e)) 93 else: 94 # libxml2 walker/iterator 95 walker = elem.getiterator() 96 for c in walker: 97 if c.text: 98 texts.append(c.text) 99 if c.tail: 100 texts.append(c.tail) 101 return ''.join(texts)
102 103 104
105 -def getFirstElement(elem):
106 """ Find first child which is an Element """ 107 if (hasattr(elem, 'childNodes')): 108 for c in elem.childNodes: 109 if c.nodeType == elementType: 110 return c 111 else: 112 for c in elem: 113 if (c.type == 'element'): 114 return c 115 return None
116
117 -def getFirstData(elem):
118 """ Find first child which is Data """ 119 if (hasattr(elem, 'childNodes')): 120 for c in elem.childNodes: 121 if c.nodeType == Node.TEXT_NODE: 122 return c.data.strip() 123 else: 124 for c in elem: 125 if (c.type == "text"): 126 return c.data.strip() 127 return ""
128 129 130 131
132 -def getFirstElementByTagName(node, local):
133 if node.nodeType == elementType and node.localName == local: 134 return node; 135 for child in node.childNodes: 136 recNode = getFirstElementByTagName(child, local) 137 if recNode: 138 return recNode 139 return None
140
141 -def traversePath(node):
142 143 if (isinstance(node, ParsedRelativeLocationPath.ParsedRelativeLocationPath)): 144 left = traversePath(node._left) 145 right = traversePath(node._right) 146 if (left == []): 147 # self::node() 148 return [right] 149 elif (type(left[0]) in types.StringTypes): 150 return [left, right] 151 else: 152 left.append(right) 153 return left 154 155 elif (isinstance(node, ParsedAbsoluteLocationPath.ParsedAbsoluteLocationPath)): 156 left = ['/'] 157 if (node._child): 158 right = traversePath(node._child) 159 else: 160 return left 161 if (type(right[0]) == types.StringType): 162 return [left, right] 163 else: 164 left.extend(right) 165 return left 166 elif (isinstance(node, ParsedAbbreviatedRelativeLocationPath.ParsedAbbreviatedRelativeLocationPath)): 167 left = traversePath(node._left) 168 right = traversePath(node._right) 169 right[0] = 'descendant' 170 if (left == []): 171 # self::node() 172 return [right] 173 elif (type(left[0]) in types.StringTypes): 174 return [left, right] 175 else: 176 left.append(right) 177 return left 178 179 elif (isinstance(node, ParsedStep.ParsedStep)): 180 # XXX Check that axis is something we can parse 181 a = node._axis._axis 182 if (a == 'self'): 183 return [] 184 185 n = node._nodeTest 186 if use4Suite: 187 local = ParsedNodeTest.LocalNameTest 188 nameattr = "_name" 189 else: 190 local = ParsedNodeTest.NodeNameTest 191 nameattr = "_nodeName" 192 if (isinstance(n, local)): 193 n = getattr(n, nameattr) 194 elif (isinstance(n, ParsedNodeTest.TextNodeTest)): 195 n = "__text()" 196 elif (isinstance(n, ParsedNodeTest.QualifiedNameTest)): 197 n = n._prefix + ":" + n._localName 198 elif (isinstance(n, ParsedNodeTest.PrincipalTypeTest)): 199 n = "*" 200 else: 201 raise(NotImplementedError) 202 203 preds = node._predicates 204 205 pp = [] 206 if (preds): 207 for pred in preds: 208 pp.append(traversePath(pred)) 209 210 return [a, n, pp] 211 212 elif (isinstance(node, ParsedExpr.ParsedEqualityExpr) or isinstance(node, ParsedExpr.ParsedRelationalExpr)): 213 # @id="fish" 214 op = node._op 215 216 # Override check for common: [position()=int] 217 if (op == '=' and isinstance(node._left, ParsedExpr.FunctionCall) and node._left._name == 'position' and isinstance(node._right, ParsedExpr.ParsedNLiteralExpr)): 218 return node._right._literal 219 220 left = traversePath(node._left) 221 if (type(left) == types.ListType and left[0] == "attribute"): 222 left = left[1] 223 right = traversePath(node._right) 224 if not op in ('=', '!='): 225 op = ['<', '<=', '>', '>='][op] 226 return [left, op, right] 227 228 elif (isinstance(node, ParsedExpr.ParsedNLiteralExpr) or isinstance(node, ParsedExpr.ParsedLiteralExpr)): 229 # 7 or "fish" 230 return node._literal 231 elif (isinstance(node, ParsedExpr.FunctionCall)): 232 # XXX check for more functions! 233 if (node._name == 'last'): 234 # Override for last using Pythonic expr 235 return -1 236 elif node._name == 'name': 237 return ['FUNCTION', '__name()'] 238 elif node._name == 'starts-with': 239 # only for foo[starts-with(@bar, 'baz')] 240 return ['FUNCTION', 'starts-with', traversePath(node._arg0)[1], node._arg1._literal] 241 elif node._name == 'regexp': 242 return ['FUNCTION', 'regexp', traversePath(node._arg0)[1], re.compile(node._arg1._literal)] 243 elif node._name == 'count': 244 return ['FUNCTION', 'count', traversePath(node._arg0)] 245 else: 246 raise(NotImplementedError) 247 248 elif (isinstance(node, ParsedExpr.ParsedAndExpr)): 249 return [traversePath(node._left), 'and', traversePath(node._right)] 250 elif (isinstance(node, ParsedExpr.ParsedOrExpr)): 251 return [traversePath(node._left), 'or', traversePath(node._right)] 252 else: 253 # We'll need to do full XPath vs DOM 254 print node.__class__ 255 raise(NotImplementedError)
256 257
258 -def verifyXPaths(paths):
259 compiled = [] 260 for p in paths: 261 allAbsolute = 1 262 # try: 263 plist = [] 264 xpObj= Compile(p) 265 plist.append(xpObj) 266 try: 267 t = traversePath(xpObj) 268 if (t[0] <> '/' and type(t[0]) in types.StringTypes): 269 # a single Step 270 t = [t] 271 plist.append(t) 272 except NotImplementedError: 273 # We can't handle it! 274 plist.append(None) 275 compiled.append(plist) 276 # except: 277 # # Utoh, invalid path. Warn. 278 # print sys.exc_info()[2] 279 # print "Invalid XPath: " + p 280 # raise(sys.exc_info()[1]) 281 return compiled
282 283 284 # ------------- Bitfield --------------- 285 286
287 -class SimpleBitfield(object):
288 - def __init__(self,value=0):
289 if not value: 290 value = 0 291 if type(value) == types.StringType: 292 if value[0:2] == "0x": 293 # Potential security issue? 294 value = eval(value) 295 else: 296 value = int(value, 2) 297 self._d = value
298
299 - def __getitem__(self, index):
300 # Necessary to end for loop 301 # eg: for x in bf: print bf[x] 302 # would continue indefinitely 303 if index >= len(self): 304 raise IndexError() 305 return (self._d >> index) & 1
306
307 - def __setitem__(self,index, value):
308 if value: 309 self._d = self._d | (1L<<index) 310 else: 311 self._d = self._d ^ (1L <<index)
312
313 - def __int__(self):
314 return self._d
315
316 - def __str__(self):
317 # eval(string) to return 318 s = hex(self._d) 319 if s[-1] == "L": 320 return s[:-1] 321 else: 322 return s
323
324 - def __nonzero__(self):
325 return self._d != 0
326
327 - def __len__(self):
328 # Precision hack 329 # NB len(str(self))-3 / 4 == capacity, not actual 330 split = math.modf(math.log(self._d, 2)) 331 if (split[0] > 0.9999999999): 332 return int(split[1]) + 1 333 else: 334 return int(split[1])
335
336 - def union(self, other):
337 self._d = self._d | other._d
338
339 - def intersection(self, other):
340 self._d = self._d & other._d
341
342 - def difference(self, other):
343 andnot = self._d & other._d 344 self._d = self._d ^ andnot
345
346 - def lenTrueItems(self):
347 string = str(self)[2:] 348 string = string.replace('0', '') 349 string = string.lower() 350 l = 0 351 for quad in string: 352 if quad in ['1','2', '4', '8']: 353 l += 1 354 elif quad in ['3', '5', '6', '9', 'a', 'c']: 355 l += 2 356 elif quad in ['7', 'b', 'd', 'e']: 357 l += 3 358 else: 359 l += 4 360 return l
361
362 - def trueItems(self):
363 string = str(self) 364 posn = 0 365 ids = [] 366 # reverse w/o leading 0x 367 string = string[2:][::-1] 368 # string exception throwing is slower 369 string = string.lower() 370 for quad in string: 371 if quad == '0': 372 pass 373 elif quad == '1': # 0001 374 ids.append(posn) 375 elif quad == '2': # 0010 376 ids.append(posn+1) 377 elif quad == '3': # 0011 378 ids.extend([posn, posn+1]) 379 elif quad == '4': # 0100 380 ids.append(posn+2) 381 elif quad == '5': # 0101 382 ids.extend([posn, posn+2]) 383 elif quad == '6': # 0110 384 ids.extend([posn+1, posn+2]) 385 elif quad == '7': # 0111 386 ids.extend([posn, posn+1, posn+2]) 387 elif quad == '8': # 1000 388 ids.append(posn+3) 389 elif quad == '9': # 1001 390 ids.extend([posn, posn+3]) 391 else: 392 if quad == 'a': # 1010 393 ids.extend([posn+1, posn+3]) 394 elif quad == 'b': # 1011 395 ids.extend([posn, posn+1, posn+3]) 396 elif quad == 'c': # 1100 397 ids.extend([posn+2, posn+3]) 398 elif quad == 'd': # 1101 399 ids.extend([posn, posn+2, posn+3]) 400 elif quad == 'e': # 1110 401 ids.extend([posn+1, posn+2, posn+3]) 402 elif quad == 'f': # 1111 403 ids.extend([posn, posn+1, posn+2, posn+3]) 404 else: 405 # WTF? 406 raise ValueError(quad) 407 posn += 4 408 return ids
409 410 411 # -------------- SRB URL Parser ------------- 412 413 import urlparse
414 -def parseSrbUrl(data):
415 info = {'user' : None, 'passwd' : None, 'domain' : None, 416 'host' : None, 'port' : None, 'path' : None, 417 'resource' : None, 'authType' : None} 418 if data[:6] == 'srb://': 419 data = 'http://' + data[6:] 420 else: 421 # Bad. Hope for the best 422 data = "http://" + data 423 424 try: 425 (scheme, net, info['path'], param, qry, fraq) = urlparse.urlparse(data) 426 except: 427 # Splat 428 return info 429 try: 430 (auth, hp) = net.split('@') 431 try: 432 (info['user'], info['passwd']) = auth.split(':') 433 info['authType'] = 'ENCRYPT1' 434 try: 435 (info['user'], info['domain']) = info['user'].split('.') 436 except: 437 pass 438 except: 439 info['authType'] = 'DN' 440 except: 441 hp = net 442 auth = "" 443 try: 444 (info['host'], port) = hp.split(':') 445 info['port'] = int(port) 446 except: 447 info['host'] = hp 448 info['port'] = 5544 449 stuff = qry.split('&') 450 resource = "" 451 for item in stuff: 452 try: 453 (typ, val) = item.split("=") 454 if typ == "resource": 455 info['resource'] = val 456 elif typ == "domain": 457 info['domain'] = val 458 elif typ == "replica": 459 info['replica'] = val 460 elif typ == "fileType": 461 info['fileType'] = val 462 except: 463 pass 464 return info
465