This commit was manufactured by cvs2svn to create tag 'wxPy_2_6_4_0'.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/tags/wxPy_2_6_4_0@44989 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Bryan Petty
2007-03-20 20:36:57 +00:00
parent 219ee9ba9d
commit 2c6b0ab87d
2304 changed files with 240793 additions and 262981 deletions

View File

@@ -1,48 +0,0 @@
#----------------------------------------------------------------------------
# Name: __init__.py
# Purpose: Utilities
#
# Author: Joel Hare
#
# Created: 7/28/04
# CVS-ID: $Id$
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
import traceback
import sys
import os
def isWindows():
return os.name == 'nt'
def _generateMainModuleDir():
if sys.executable.find('python') != -1:
utilModuleDir = os.path.dirname(__file__)
if not os.path.isabs(utilModuleDir):
utilModuleDir = os.path.join(os.getcwd(), utilModuleDir)
mainModuleDir = os.path.normpath(os.path.join(utilModuleDir, os.path.join(os.path.pardir, os.path.pardir)))
if mainModuleDir.endswith('.zip'):
mainModuleDir = os.path.dirname(mainModuleDir) # Get rid of library.zip
else:
mainModuleDir = os.path.dirname(sys.executable)
return mainModuleDir
mainModuleDir = _generateMainModuleDir()
def _generatePythonExecPath():
if sys.executable.find('python') != -1:
pythonExecPath = sys.executable
else:
pythonExecPath = os.path.join(os.path.dirname(sys.executable), '3rdparty\python2.3\python')
return pythonExecPath
pythonExecPath = _generatePythonExecPath()
def getCommandNameForExecPath(execPath):
if isWindows():
return '"%s"' % execPath
return execPath

View File

@@ -15,7 +15,11 @@ import os
import re
import traceback
import logging
import logging.config
from activegrid.util.lang import *
import activegrid.util.objutils as objutils
import activegrid.util.sysutils as sysutils
import activegrid.util.appdirs as appdirs
LEVEL_FATAL = logging.FATAL
LEVEL_ERROR = logging.ERROR
@@ -23,6 +27,99 @@ LEVEL_WARN = logging.WARN
LEVEL_INFO = logging.INFO
LEVEL_DEBUG = logging.DEBUG
EXCEPTION_INFO = 'exceptionInfo'
loggingInitialized = False
LOG_MODE_IDE = 1
LOG_MODE_TESTRUN = 2
LOG_MODE_RUN = 3
def initLogging(mode, force=False):
global ag_debugLogger, loggingInitialized
if (force or not loggingInitialized):
loggingInitialized = True
configFile = None
if (mode == LOG_MODE_IDE):
configFile = os.getenv("AG_LOGCONFIG_IDE")
elif (mode == LOG_MODE_TESTRUN):
configFile = os.getenv("AG_LOGCONFIG_PYTESTRUN")
else:
configFile = os.getenv("AG_LOGCONFIG_RUN")
if ((configFile == None) or not os.path.exists(configFile)):
if (mode == LOG_MODE_IDE):
configFile = "IDELog"
elif (mode == LOG_MODE_TESTRUN):
configFile = "TestRunLog"
else:
configFile = "RunLog"
configFile = os.path.join(appdirs.getSystemDir(appdirs.AG_LOGS_DIR), "py" + configFile + ".ini")
if (os.path.exists(configFile)):
print "Using logging configuration file: %s" % configFile
fileConfig(configFile)
else:
print "*** Cannot find logging configuration file (%s) -- setting default logging level to WARN ***" % (configFile)
defaultStream = sys.stderr
if (mode == LOG_MODE_RUN):
defaultStream = sys.stdout
handler = logging.StreamHandler(defaultStream)
handler.setLevel(logging.DEBUG)
handler.setFormatter(logging.Formatter("%(asctime)s %(name)s %(levelname)s: %(message)s"))
logging.getLogger().addHandler(handler)
logging.getLogger().setLevel(logging.WARN)
ag_debugLogger = logging.getLogger("activegrid.debug")
ag_debugLogger.setLevel(logging.DEBUG)
return configFile
ag_debugLogger = logging.getLogger("activegrid.debug")
def log(logger, level, msg, *params):
if (logger == None):
logger = ag_debugLogger
apply(logger.log, (level, msg) + params)
def fatal(logger, msg, *params):
apply(logger.fatal, (msg,) + params)
def error(logger, msg, *params):
apply(logger.error, (msg,) + params)
def warn(logger, msg, *params):
apply(logger.warn, (msg,) + params)
def info(logger, msg, *params):
apply(logger.info, (msg,) + params)
def debug(logger, msg, *params):
if (logger == None):
logger = ag_debugLogger
apply(logger.debug, (msg,) + params)
def setLevelFatal(logger):
logger.setLevel(LEVEL_FATAL)
def setLevelError(logger):
logger.setLevel(LEVEL_ERROR)
def setLevelWarn(logger):
logger.setLevel(LEVEL_WARN)
def setLevelInfo(logger):
logger.setLevel(LEVEL_INFO)
def setLevelDebug(logger):
logger.setLevel(LEVEL_DEBUG)
def isEnabledForError(logger):
return logger.isEnabledFor(LEVEL_ERROR)
def isEnabledForWarn(logger):
return logger.isEnabledFor(LEVEL_WARN)
def isEnabledForInfo(logger):
return logger.isEnabledFor(LEVEL_INFO)
def isEnabledForDebug(logger):
return logger.isEnabledFor(LEVEL_DEBUG)
TEST_MODE_NONE = 0
TEST_MODE_DETERMINISTIC = 1
TEST_MODE_NON_DETERMINISTIC = 2
@@ -38,8 +135,11 @@ def getTestMode():
global agTestMode
return agTestMode
def testMode(normalObj, testObj=None):
if getTestMode() > TEST_MODE_NONE:
def testMode(normalObj, testObj=None, nonDeterministicObj=None):
testMode = getTestMode()
if testMode > TEST_MODE_NONE:
if ((nonDeterministicObj != None) and (testMode == TEST_MODE_NON_DETERMINISTIC)):
return nonDeterministicObj
return testObj
return normalObj
@@ -68,36 +168,208 @@ def _fileNameReplacement(match):
def _fileNameReplacementPHP(match):
return "%s...%s" % (match.group(1), match.group(2).replace(os.sep, "/"))
def getTraceback():
extype, val, tb = sys.exc_info()
tbs = "\n"
for s in traceback.format_tb(tb):
tbs += s
def formatTraceback(tb=None):
if (tb == None):
extype, val, tb = sys.exc_info()
tbs = "\n" + "".join(traceback.format_tb(tb))
return tbs
def reportException(out=None, stacktrace=False, diffable=False, exception=None):
if (True): # exception == None):
extype, val, t = sys.exc_info()
def formatExceptionCause(cause, stacktrace=False):
if (cause == None):
return ""
tbs = ""
if (stacktrace):
tbs = formatTraceback()
return "Caused by %s.%s: %s%s" % (cause.__module__, cause.__class__.__name__, str(cause), tbs)
def addExceptionInfo(e, key, value):
if not hasattr(e, EXCEPTION_INFO):
try:
setattr(e, EXCEPTION_INFO, {})
except:
return # Make sure we still report the real exception even if we can't add the extra info
if not e.exceptionInfo.has_key(key): # Never overwrite exception info since we assume earlier info is more specific
e.exceptionInfo[key] = value
def reportException(exception, out=None, stacktrace=False, diffable=False):
exstr = exceptionToString(exception, stacktrace, diffable)
if (out == None):
print exstr
else:
extype = type(exception)
val = exception
if (stacktrace):
e,v,t = sys.exc_info()
print >> out, exstr
def exceptionToString(exception, stacktrace=False, diffable=False):
extype = objutils.typeToString(exception)
val = exception
if (stacktrace):
e,v,t = sys.exc_info()
if (diffable):
exstr = removeFileRefs(str(val))
else:
exstr = str(val)
if (out == None):
print "Got Exception = %s: %s" % (extype, exstr)
else:
print >> out, "Got Exception = %s: %s" % (extype, exstr)
if hasattr(val, EXCEPTION_INFO):
firstTime = True
for infoKey, infoValue in getattr(val, EXCEPTION_INFO).items():
if firstTime:
prefix = " EXTRA INFO:"
firstTime = False
else:
prefix = ","
exstr += ("%s %s=%s" % (prefix, infoKey, infoValue))
result = "Got Exception = %s: %s" % (extype, exstr)
if (stacktrace):
fmt = traceback.format_exception(extype, val, t)
for s in fmt:
if (diffable):
s = removeFileRefs(s)
if (out == None):
print s
result = result + "\n" + s
return result
def fileConfig(fname, defaults=None):
"""
This is copied from logging.config so that we could fix the class lookup of
handlers. Previously handlers had to be defined in logging.handlers and we
need to be able to define our own.
"""
import ConfigParser, string
cp = ConfigParser.ConfigParser(defaults)
if hasattr(cp, 'readfp') and hasattr(fname, 'readline'):
cp.readfp(fname)
else:
cp.read(fname)
#first, do the formatters...
flist = cp.get("formatters", "keys")
if len(flist):
flist = string.split(flist, ",")
formatters = {}
for form in flist:
sectname = "formatter_%s" % form
opts = cp.options(sectname)
if "format" in opts:
fs = cp.get(sectname, "format", 1)
else:
print >> out, s
fs = None
if "datefmt" in opts:
dfs = cp.get(sectname, "datefmt", 1)
else:
dfs = None
f = logging.Formatter(fs, dfs)
formatters[form] = f
#next, do the handlers...
#critical section...
logging._acquireLock()
try:
## try:
#first, lose the existing handlers...
logging._handlers.clear()
#now set up the new ones...
hlist = cp.get("handlers", "keys")
if len(hlist):
hlist = string.split(hlist, ",")
handlers = {}
fixups = [] #for inter-handler references
for hand in hlist:
## try:
sectname = "handler_%s" % hand
classname = cp.get(sectname, "class")
opts = cp.options(sectname)
if "formatter" in opts:
fmt = cp.get(sectname, "formatter")
else:
fmt = ""
klass = None
try:
klass = eval(classname, vars(logging))
except:
pass
if (klass == None):
klass = objutils.classForName(classname)
args = cp.get(sectname, "args")
args = eval(args, vars(logging))
h = apply(klass, args)
if "level" in opts:
level = cp.get(sectname, "level")
h.setLevel(logging._levelNames[level])
if len(fmt):
h.setFormatter(formatters[fmt])
#temporary hack for FileHandler and MemoryHandler.
if klass == logging.handlers.MemoryHandler:
if "target" in opts:
target = cp.get(sectname,"target")
else:
target = ""
if len(target): #the target handler may not be loaded yet, so keep for later...
fixups.append((h, target))
handlers[hand] = h
## except Exception, e: #if an error occurs when instantiating a handler, too bad
## pass #this could happen e.g. because of lack of privileges
#now all handlers are loaded, fixup inter-handler references...
for fixup in fixups:
h = fixup[0]
t = fixup[1]
h.setTarget(handlers[t])
#at last, the loggers...first the root...
llist = cp.get("loggers", "keys")
llist = string.split(llist, ",")
llist.remove("root")
sectname = "logger_root"
root = logging.root
log = root
opts = cp.options(sectname)
if "level" in opts:
level = cp.get(sectname, "level")
log.setLevel(logging._levelNames[level])
for h in root.handlers[:]:
root.removeHandler(h)
hlist = cp.get(sectname, "handlers")
if len(hlist):
hlist = string.split(hlist, ",")
for hand in hlist:
log.addHandler(handlers[hand])
#and now the others...
#we don't want to lose the existing loggers,
#since other threads may have pointers to them.
#existing is set to contain all existing loggers,
#and as we go through the new configuration we
#remove any which are configured. At the end,
#what's left in existing is the set of loggers
#which were in the previous configuration but
#which are not in the new configuration.
existing = root.manager.loggerDict.keys()
#now set up the new ones...
for log in llist:
sectname = "logger_%s" % log
qn = cp.get(sectname, "qualname")
opts = cp.options(sectname)
if "propagate" in opts:
propagate = cp.getint(sectname, "propagate")
else:
propagate = 1
logger = logging.getLogger(qn)
if qn in existing:
existing.remove(qn)
if "level" in opts:
level = cp.get(sectname, "level")
logger.setLevel(logging._levelNames[level])
for h in logger.handlers[:]:
logger.removeHandler(h)
logger.propagate = propagate
logger.disabled = 0
hlist = cp.get(sectname, "handlers")
if len(hlist):
hlist = string.split(hlist, ",")
for hand in hlist:
logger.addHandler(handlers[hand])
#Disable any old loggers. There's no point deleting
#them as other threads may continue to hold references
#and by disabling them, you stop them doing any logging.
for log in existing:
root.manager.loggerDict[log].disabled = 1
## except:
## import traceback
## ei = sys.exc_info()
## traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
## del ei
finally:
logging._releaseLock()

View File

@@ -0,0 +1,126 @@
#----------------------------------------------------------------------------
# Name: appdirs.py
# Purpose: Utilities for retrieving special application dirs
#
# Author: Kevin Ollivier, Jeff Norton
#
# Created: 8/27/05
# CVS-ID: $Id$
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
from activegrid.util.lang import *
import sys
import os
import string
import activegrid.util.sysutils as sysutils
def _getSystemDir(kind):
if (kind == AG_LOGS_DIR):
return os.path.join(getSystemDir(AG_SYSTEM_DIR) , "logs")
elif (kind == AG_DEMOS_DIR):
return os.path.join(getSystemDir(AG_SYSTEM_DIR), "demos")
else:
path = ""
if (sysutils.isServer()):
path = os.getenv("ACTIVEGRID_SERVER_HOME")
if ((path is None) or (len(path) < 1)):
path = sysutils.mainModuleDir
else:
path = os.getenv("AG_DOCUMENTS_DIR")
if ((path is None) or (len(path) < 1)):
if sysutils.isWindows():
ifDefPy()
try:
from win32com.shell import shell, shellcon
path = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)
except:
pass
endIfDef()
if ((path is None) or (len(path) < 1)):
homedrive = asString(os.getenv("HOMEDRIVE"))
homepath = os.getenv("HOMEPATH")
## if ((homedrive is not None) and (len(homedrive) > 0) and (homepath is not None) and (len(homepath) > 0)):
path = os.path.join(homedrive, homepath, "MYDOCU~1")
else:
ifDefPy()
if sys.platform == "darwin":
try:
import macfs
import MACFS
fsspec_disk, fsspec_desktop = macfs.FindFolder(MACFS.kOnSystemDisk, MACFS.kDocumentsFolderType, 0)
path = macfs.FSSpec((fsspec_disk, fsspec_desktop, '')).as_pathname()
except:
pass
endIfDef()
ifDefPy()
if ((path is None) or (len(path) < 1)):
path = os.path.expanduser("~")
endIfDef()
if ((path is None) or (len(path) < 1)):
path = "/"
path = os.path.join(path, "ActiveGrid")
return path
AG_SYSTEM_DIR = 0
AG_LOGS_DIR = 1
AG_DEMOS_DIR = 2
__systemDir = None
__logsDir = None
__demosDir = None
def getSystemDir(kind=0):
if (kind == AG_SYSTEM_DIR):
global __systemDir
if (__systemDir is None):
__systemDir = _getSystemDir(kind)
return __systemDir
elif (kind == AG_LOGS_DIR):
global __logsDir
if (__logsDir is None):
__logsDir = _getSystemDir(kind)
return __logsDir
elif (kind == AG_DEMOS_DIR):
global __demosDir
if (__demosDir is None):
__demosDir = _getSystemDir(kind)
return __demosDir
return None
# NOTE: We don't set this at startup because wxStandardPaths needs a running
# application object. This makes sure the wxApp will always be created when
# we get the folder.
ifDefPy()
def getAppDataFolder():
try:
# NOTE: cannot import wx from the server
import wx
# wxStandardPaths requires a running app
if wx.GetApp() and wx.Platform != "__WXGTK__":
data_folder = wx.StandardPaths.Get().GetUserDataDir()
if not os.path.exists(data_folder):
os.mkdir(data_folder)
return data_folder
except:
pass
# wxBug: on *nix, it wants to point to ~/.appname, but
# so does wxConfig... For now, redirect this to ~/.appbuilder
# when this is fixed, we'll migrate settings to the correct place
return os.path.join(os.path.expanduser("~"), ".appbuilder")
endIfDef()
ifDefPy()
def createSystemDirs():
if (not os.path.exists(getSystemDir())):
os.mkdir(getSystemDir())
if (not os.path.exists(getSystemDir(AG_LOGS_DIR))):
os.mkdir(getSystemDir(AG_LOGS_DIR))
if (not os.path.exists(getSystemDir(AG_DEMOS_DIR))):
os.mkdir(getSystemDir(AG_DEMOS_DIR))
endIfDef()

View File

@@ -0,0 +1,118 @@
#----------------------------------------------------------------------------
# Name: datetimeparser.py
#
# Purpose: - Instantiate datetime.datetime/date instance from a string
# date representation.
# Uses dateutil from http://labix.org/python-dateutil.
#
# - Creates string representation of datetime/date instance.
#
#
# Author: Simon Toens
#
# Created: 28-Feb-06
# CVS-ID:
# Copyright: (c) 2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
import datetime
try:
import dateutil.parser
DATEUTIL_INSTALLED = True
except ImportError:
DATEUTIL_INSTALLED = False
ISO_8601_DATE_FORMAT = "%Y-%m-%d"
ISO_8601_TIME_FORMAT = "%H:%M:%S"
ISO_8601_DATETIME_FORMAT = "%s %s" %(ISO_8601_DATE_FORMAT,
ISO_8601_TIME_FORMAT)
DEFAULT_DATETIME = datetime.datetime(1, 1, 1, 0, 0, 0, 0)
def format(dateobj, formatstr=None):
if (formatstr != None and _isDateTimeObject(dateobj)):
return dateobj.strftime(str(formatstr))
return str(dateobj)
def parse(datestr, formatstr=None, asdate=False, astime=False):
"""Instantiates and returns a datetime instance from the datestr datetime
representation.
Optionally, a format string may be used. The format is only loosely
interpreted, its only purpose beeing to determine if the year is first
or last in datestr, and whether the day is in front or follows the
month. If no formatstr is passed in, dateutil tries its best to parse
the datestr. The default date format is YYYY-mm-dd HH:SS.
If asdate is True, returns a date instance instead of a datetime
instance, if astime is True, returns a time instance instead of a
datetime instance."""
dayfirst, yearfirst = _getDayFirstAndYearFirst(formatstr)
rtn = None
try:
if DATEUTIL_INSTALLED:
rtn = dateutil.parser.parse(str(datestr), fuzzy=True,
dayfirst=dayfirst, yearfirst=yearfirst,
default=DEFAULT_DATETIME)
else:
rtn = DEFAULT_DATETIME
except:
rtn = DEFAULT_DATETIME
if (asdate and isinstance(rtn, datetime.datetime)):
rtn = datetime.date(rtn.year, rtn.month, rtn.day)
elif (astime and isinstance(rtn, datetime.datetime)):
rtn = datetime.time(rtn.hour, rtn.minute, rtn.second, rtn.microsecond)
return rtn
def _isDateTimeObject(obj):
return (isinstance(obj, datetime.datetime) or
isinstance(obj, datetime.date) or
isinstance(obj, datetime.time))
def _getDayFirstAndYearFirst(formatstr):
dayFirst = False
yearFirst = False
gotYear = False
gotMonth = False
gotDay = False
if (formatstr == None):
formatstr = ""
for c in formatstr:
if (c.lower() == "y"):
if (gotYear):
continue
if (not gotDay and not gotMonth):
yearFirst = True
gotYear = True
elif (c.lower() == "m"):
if (gotMonth):
continue
if (not gotDay):
dayFirst = False
gotMonth = True
elif (c.lower() == "d"):
if (gotDay):
continue
if (not gotMonth):
dayFirst = True
gotDay = True
return dayFirst, yearFirst

View File

@@ -0,0 +1,431 @@
#----------------------------------------------------------------------------
# Name: fileutils.py
# Purpose: Active grid miscellaneous utilities
#
# Author: Jeff Norton
#
# Created: 12/10/04
# CVS-ID: $Id$
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
import logging
import copy
import os
import shutil
import sys
import zipfile
import activegrid.util.aglogging as aglogging
import activegrid.util.sysutils as sysutils
import activegrid.util.utillang as utillang
from activegrid.util.lang import *
global fileutilsLogger
fileutilsLogger = logging.getLogger("activegrid.util.fileutils")
# FATAL : No logging
# ERROR : No logging
# WARN : No logging
# INFO : No logging
# DEBUG : debugging
aglogging.setLevelFatal(fileutilsLogger)
#logging.getLogger().addHandler(logging.StreamHandler(sys.stderr))
def addRef(varname):
return "${%s}" % varname
AG_SYSTEM_VAR_NAMES = [] # all AG System vars, with ${} syntax
AG_SYSTEM_VAR = "AG_SYSTEM"
AG_SYSTEM_VAR_REF = addRef(AG_SYSTEM_VAR)
AG_SYSTEM_VAR_NAMES.append(AG_SYSTEM_VAR_REF)
AG_SYSTEM_STATIC_VAR = "AG_SYSTEM_STATIC"
AG_SYSTEM_STATIC_VAR_REF = addRef(AG_SYSTEM_STATIC_VAR)
AG_SYSTEM_VAR_NAMES.append(AG_SYSTEM_STATIC_VAR_REF)
AG_APP_VAR = "AG_APP"
AG_APP_STATIC_VAR = "AG_APP_STATIC"
# _initAGSystemVars needs to be called to initialize the following two
# containers:
EXPANDED_AG_SYSTEM_VARS = {} # ${varname} -> value (path)
# ${varname}, ordered from longest to shortest path value
AG_SYSTEM_VARS_LENGTH_ORDER = []
def _initAGSystemVars():
if (len(EXPANDED_AG_SYSTEM_VARS) > 0):
return
for v in AG_SYSTEM_VAR_NAMES:
EXPANDED_AG_SYSTEM_VARS[v] = os.path.abspath(expandVars(v))
AG_SYSTEM_VARS_LENGTH_ORDER.append(v)
AG_SYSTEM_VARS_LENGTH_ORDER.sort(_sortByValLength)
def parameterizePathWithAGSystemVar(inpath):
"""Returns parameterized path if path starts with a known AG directory. Otherwise returns path as it was passed in."""
_initAGSystemVars()
path = inpath
if not sysutils.isWindows():
# ensure we have forward slashes
path = path.replace("\\", "/")
path = os.path.abspath(path)
for varname in AG_SYSTEM_VARS_LENGTH_ORDER:
varval = EXPANDED_AG_SYSTEM_VARS[varname]
if path.startswith(varval):
return path.replace(varval, varname)
return inpath
def startsWithAgSystemVar(path):
"""Returns True if path starts with a known AG system env var, False otherwise."""
for varname in AG_SYSTEM_VAR_NAMES:
if path.startswith(varname):
return True
return False
def _sortByValLength(v1, v2):
return len(EXPANDED_AG_SYSTEM_VARS[v2]) - len(EXPANDED_AG_SYSTEM_VARS[v1])
def makeDirsForFile(filename):
d = os.path.dirname(filename)
if (not os.path.exists(d)):
os.makedirs(d)
def createFile(filename, mode='w'):
f = None
if (not os.path.exists(filename)):
makeDirsForFile(filename)
f = file(filename, mode)
return f
def compareFiles(file1, file2, ignore=None):
## result = filecmp.cmp(file1, file2)
## if result:
## return 0
## return -1
file1.seek(0)
file2.seek(0)
while True:
line1 = file1.readline()
line2 = file2.readline()
if (len(line1) == 0):
if (len(line2) == 0):
return 0
else:
return -1
elif (len(line2) == 0):
return -1
elif (line1 != line2):
if (ignore != None):
if (line1.startswith(ignore) or line2.startswith(ignore)):
continue
line1 = line1.replace(" ", "")
line2 = line2.replace(" ", "")
if (line1 != line2):
len1 = len(line1)
len2 = len(line2)
if ((abs(len1 - len2) == 1) and (len1 > 0) and (len2 > 0)
and (line1[-1] == "\n") and (line2[-1] == "\n")):
if (len1 > len2):
longer = line1
shorter = line2
else:
shorter = line1
longer = line2
if ((longer[-2] == "\r") and (longer[:-2] == shorter[:-1])):
continue
if ((longer[-2:] == shorter[-2:]) and (longer[-3] == "\r") and (longer[:-3] == shorter[:-2])):
continue
return -1
def expandKnownAGVars(value):
return expandVars(value, includeEnv=False)
def expandVars(value, includeEnv=True):
"""Syntax: ${myvar,default="default value"}"""
import activegrid.runtime as runtime
sx = value.find("${")
if (sx >= 0):
result = asString(value[:sx])
endx = value.find("}")
if (endx > 1):
defaultValue = None
defsx = value.find(",default=\"")
if ((defsx > sx) and (defsx < endx)):
varname = value[sx+2:defsx]
if (value[endx-1] == '"'):
defaultValue = value[defsx+10:endx-1]
if (defaultValue == None):
varname = value[sx+2:endx]
if (varname == AG_SYSTEM_VAR):
varval = runtime.appInfo.getSystemDir()
elif (varname == AG_SYSTEM_STATIC_VAR):
varval = runtime.appInfo.getSystemStaticDir()
elif (varname == AG_APP_VAR):
varval = runtime.appInfo.getAppDir()
elif (varname == AG_APP_STATIC_VAR):
varval = runtime.appInfo.getAppStaticDir()
else:
if (includeEnv):
varval = os.getenv(varname)
else:
varval = None
if ((varval == None) and (defaultValue != None)):
varval = defaultValue
if (varval == None):
result += value[sx:endx+1]
else:
result += varval
return result + expandVars(value[endx+1:])
return value
def toPHPpath(path, otherdir=None):
return convertSourcePath(path, "php", otherdir=otherdir)
def toPythonpath(path, otherdir=None):
return convertSourcePath(path, "python", otherdir=otherdir)
def toUnixPath(path):
if (path != None and os.sep != '/'):
path = path.replace(os.sep, '/')
return path
def convertSourcePath(path, to, otherdir=None):
fromname = "python"
if (to == "python"):
fromname = "php"
pythonNode = os.sep + fromname + os.sep
ix = path.find(pythonNode)
if (ix < 0):
ix = path.find(fromname) - 1
if ((ix < 0) or (len(path) <= ix+7)
or (path[ix] not in ("\\", "/")) or (path[ix+7] not in ("\\", "/"))):
raise Exception("Not in a %s source tree. Cannot create file name for %s." % (fromname, path))
if (otherdir == None):
return path[:ix+1] + to + path[ix+7:]
else:
return otherdir + path[ix+7:]
if (otherdir == None):
return path.replace(pythonNode, os.sep + to + os.sep)
else:
return otherdir + path[ix+7:]
def visit(directory, files, extension, maxLevel=None, level=1):
testdirs = os.listdir(directory)
for thing in testdirs:
fullpath = os.path.join(directory, thing)
if (os.path.isdir(fullpath) and (maxLevel == None or level < maxLevel)):
visit(fullpath, files, extension, maxLevel, level+1)
elif thing.endswith(extension):
fullname = os.path.normpath(os.path.join(directory, thing))
if not fullname in files:
files.append(fullname)
def listFilesByExtensionInPath(path=[], extension='.lyt', maxLevel=None):
retval = []
for directory in path:
visit(directory, retval, extension, maxLevel)
return retval
def getFileLastModificationTime(fileName):
return os.path.getmtime(fileName)
def findFileLocation(location, fileName):
i = fileName.rfind(os.sep)
if i > 0:
fileName = fileName[:i]
while location[0:2] == '..' and location[2:3] == os.sep:
location = location[3:]
i = fileName.rfind(os.sep)
fileName = fileName[:i]
absPath = fileName + os.sep + location
return absPath
def getAllExistingFiles(files, basepath=None, forceForwardSlashes=False):
"""For each file in files, if it exists, adds its absolute path to the rtn list. If file is a dir, calls this function recursively on all child files in the dir.
If basepath is set, and if the file being processed is relative to basedir, adds that relative path to rtn list instead of the abs path.
Is this is Windows, and forceForwardSlashes is True, make sure returned paths only have forward slashes."""
if isinstance(files, basestring):
files = [files]
rtn = []
for file in files:
if os.path.exists(file):
if os.path.isfile(file):
if basepath and hasAncestorDir(file, basepath):
rtn.append(getRelativePath(file, basepath))
else:
rtn.append(os.path.abspath(str(file)))
elif os.path.isdir(file):
dircontent = [os.path.join(file, f) for f in os.listdir(file)]
rtn.extend(getAllExistingFiles(dircontent, basepath))
if forceForwardSlashes and sysutils.isWindows():
newRtn = []
for f in rtn:
newRtn.append(f.replace("\\", "/"))
rtn = newRtn
return rtn
def hasAncestorDir(file, parent):
"""Returns true if file has the dir 'parent' as some parent in its path."""
return getRelativePath(file, parent) != None
def getRelativePath(file, basedir):
"""Returns relative path from 'basedir' to 'file', assuming 'file' lives beneath 'basedir'. If it doesn't, returns None."""
file = os.path.abspath(file)
parent = os.path.abspath(basedir)
if file == parent:
return None
if file.startswith(parent):
return file[len(parent)+1:]
return None
def isEmptyDir(dir):
if not os.path.isdir(dir):
return False
return len(os.listdir(dir)) == 0
ifDefPy()
def zip(zipfilepath, basedir=None, files=None):
"""Zip all files in files and save zip as zipfilepath. If files is None, zip all files in basedir. For all files to be zipped, if they are relative to basedir, include the relative path in the archive."""
if not files and not basedir:
raise AssertionError("Either 'basedir' or 'files' must be set")
if not files:
aglogging.debug(fileutilsLogger,\
"Looking for files to zip in %s" % basedir)
files = getAllExistingFiles(basedir)
else:
# removes files that don't exist and gets abs for each
files = getAllExistingFiles(files)
if len(files) == 0:
aglogging.debug(fileutilsLogger, "No files to zip, nothing to do")
return
z = zipfile.ZipFile(zipfilepath, mode="w", compression=zipfile.ZIP_DEFLATED)
try:
for file in files:
arcname = None
if basedir:
arcname = getRelativePath(file, basedir)
if not arcname:
arcname = file
aglogging.debug(fileutilsLogger,\
"%s: adding %s with arcname %s" %\
(zipfilepath, file, arcname))
z.write(file, arcname)
finally:
z.close()
endIfDef()
ifDefPy()
def unzip(zipfilepath, extractdir):
"""Unzip zipfilepath into extractdir."""
z = zipfile.ZipFile(zipfilepath, mode="r")
for info in z.infolist():
filename = os.path.join(extractdir, info.filename)
try:
dir = os.path.dirname(filename)
aglogging.debug(fileutilsLogger, "Creating dir %s" % dir)
os.makedirs(dir) # do we have to worry about permissions?
except:
pass
if os.path.isdir(filename):
continue
aglogging.debug(fileutilsLogger,\
("Writing arcfile %s to %s" % (info.filename, filename)))
f = open(filename, "w")
f.write(z.read(info.filename))
f.close()
endIfDef()
ifDefPy()
def copyFile(src, dest):
"""Copies file src to dest. Creates directories in 'dest' path if necessary."""
destdir = os.path.dirname(dest)
if not os.path.exists(destdir):
os.makedirs(destdir)
shutil.copy(src, dest)
endIfDef()
ifDefPy()
def copyDir(src, dest):
"""Copies dir 'src' into dir 'dest'. Creates 'dest' if it does not exist."""
shutil.copytree(src, dest)
endIfDef()
ifDefPy()
def remove(file):
if not os.path.exists(file):
return
if os.path.isfile(file):
os.remove(file)
elif os.path.isdir(file):
shutil.rmtree(file)
endIfDef()
def getUserTempDir():
systemTempDir = utillang.getSystemTempDir()
userName = sysutils.getUserName()
userNameNoSpace = userName.replace('_','__').replace(' ','_')
userTempDir = systemTempDir + os.sep + "activegrid_" + userNameNoSpace
return userTempDir
def createUserTempDir():
userTempDir = getUserTempDir()
if not os.path.exists(userTempDir):
os.makedirs(userTempDir)
os.chmod(userTempDir, 0700)
createUserTempDir()
ifDefPy()
import warnings
warnings.filterwarnings("ignore", message="tmpnam is a potential security risk to your program")
def getTmpFile():
return os.tmpnam()
endIfDef()
ifDefPy()
#@accepts str, dict, str, str, boolean
def replaceToken(infilepath, tokens={}, outfilepath=None, delim="@@",\
useEnv=False):
"""Replaces tokens of form 'delim'<tokenname>'delim' in file at 'infilepath', using values in dict 'tokens'. If 'outfilepath' is set, writes output to 'outfilepath', if not set, overwrites original file. If 'useEnv' is True, adds os.environ to 'tokens'. This makes it possible to define an env var FOO=BLAH, and have @@FOO@@ be replaced with BLAH, without explicitly passing FOO=BLAH in 'tokens'. Note that entries in 'tokens' take precedence over entries in os.environ."""
if useEnv:
for key, val in os.environ.items():
# passed in tokens take precedence
if not tokens.has_key(key):
tokens[key] = val
f = open(infilepath, "r")
try:
content = f.read()
finally:
if f: f.close()
for token, value in tokens.items():
content = content.replace("%s%s%s" % (delim, token , delim), str(value))
if not outfilepath: outfilepath = infilepath
f = open(outfilepath, "w")
try:
f.write(content)
finally:
if f: f.close()
endIfDef()

View File

@@ -65,3 +65,9 @@ def ifDefPy(comment=False):
def endIfDef():
pass
def ag_isPHP():
return False
def ag_isPython():
return True

View File

@@ -14,36 +14,222 @@ import logging
import traceback
import sys
import os
import __builtin__
import types
import activegrid.util.utillang as utillang
import activegrid.util.datetimeparser as datetimeparser
from types import *
from activegrid.util.lang import *
FUNCTION_HAS_ATTR = '_hasAttr'
FUNCTION_GET_ATTR = '_getAttr'
FUNCTION_SET_ATTR = '_setAttr'
FUNCTION_DEL_ATTR = '_delAttr'
def hasRawAttr(obj, name):
if obj == None:
return False
if name != FUNCTION_HAS_ATTR and hasattr(obj, FUNCTION_HAS_ATTR):
return obj._hasAttr(name)
return obj.__dict__.has_key(name)
def getRawAttr(obj, name):
if name != FUNCTION_GET_ATTR and hasattr(obj, FUNCTION_GET_ATTR):
return obj._getAttr(name)
return obj.__dict__.get(name)
def setRawAttr(obj, name, value):
if name != FUNCTION_SET_ATTR and hasattr(obj, FUNCTION_SET_ATTR):
obj._setAttr(name, value)
else:
obj.__dict__[name] = value
def delRawAttr(obj, name):
if name != FUNCTION_DEL_ATTR and hasattr(obj, FUNCTION_DEL_ATTR):
obj._delAttr(name)
else:
del obj.__dict__[name]
def getStaticAttr(obj, attr):
if (isinstance(obj, types.TypeType)):
classDesc = obj
else:
classDesc = obj.__class__
if (hasattr(classDesc, attr)):
return getattr(classDesc, attr)
return None
def setStaticAttr(obj, attr, value):
if (isinstance(obj, types.TypeType)):
classDesc = obj
else:
classDesc = obj.__class__
setattr(classDesc, attr, value)
def hasAttrFast(obj, name):
if hasRawAttr(obj, name):
return True
if hasattr(obj, '_complexType'):
complexType=obj._complexType
element=complexType.findElement(name)
if element:
return True
if hasattr(obj, name):
return True
return False
def moduleForName(moduleName):
module = None
pathList = moduleName.split('.')
if (len(moduleName) > 0):
module = __import__(moduleName)
for name in pathList[1:]:
if (name in module.__dict__):
module = module.__dict__[name]
else:
module = None
break
return module
def typeForName(typeName):
i = typeName.rfind('.')
if (i >= 0):
module = moduleForName(typeName[:i])
if (module != None):
name = typeName[i+1:]
if (name in module.__dict__):
return module.__dict__[name]
elif __builtin__.__dict__.has_key(typeName):
return __builtin__.__dict__[typeName]
return None
def functionForName(functionName):
ftype = typeForName(functionName)
if (isinstance(ftype, (types.FunctionType, types.MethodType, types.BuiltinFunctionType, types.BuiltinMethodType))):
return ftype
return None
def classForName(className):
pathList = className.split('.')
moduleName = '.'.join(pathList[:-1])
code = __import__(moduleName)
for name in pathList[1:]:
code = code.__dict__[name]
return code
ctype = typeForName(className)
if (isinstance(ctype, (types.ClassType, types.TypeType))):
return ctype
return None
def hasPropertyValue(obj, attr):
hasProp = False
try:
prop = obj.__class__.__dict__[attr]
if (isinstance(prop, property)):
hasProp = hasattr(obj, attr)
if (hasProp):
# It's a property and it has a value but sometimes we don't want it.
# If there is a _hasattr method execute it and the
# result will tell us whether to include this value
try:
hasProp = obj._hasattr(attr)
except:
pass
except KeyError:
pass
return hasProp
def newInstance(className, objargs=None):
"dynamically create an object based on the className and return it."
def toDiffableString(value):
s = str(value)
if not isinstance(objargs, list):
objargs = [objargs]
if className == "None":
return None
elif className == "bool":
if ((len(objargs) < 1) or (objargs[0].lower() == "false") or (not objargs[0])):
return False
return True
if className == "str" or className == "unicode": # don't strip: blanks are significant
if len(objargs) > 0:
try:
return utillang.unescape(objargs[0]).encode()
except:
return "?"
else:
return ""
if className == "date":
return datetimeparser.parse(objargs[0], asdate=True)
if className == "datetime":
return datetimeparser.parse(objargs[0])
if className == "time":
return datetimeparser.parse(objargs[0], astime=True)
classtype = classForName(className)
if (classtype == None):
raise Exception("Could not find class %s" % className)
if (len(objargs) > 0):
return classtype(*objargs)
else:
return classtype()
def getClassProperty(classType, propertyName):
return getattr(classType, propertyName)
def toDiffableRepr(value, maxLevel=None):
if (value == None):
return "None"
if (maxLevel == None):
maxLevel = 8
maxLevel -= 1
if (maxLevel < 0):
return typeToString(value, PRINT_OBJ_DIFFABLE)
## if ((exclude != None) and not isinstance(value, (basestring, int))):
## for v in exclude:
## if (v is value):
## return "<recursive reference>"
## exclude.append(value)
## elif (isinstance(value, ObjectType) and hasattr(value, "__dict__")):
## if (exclude == None):
## exclude = []
## s = "%s(%s)" % (type(value), toDiffableString(value.__dict__, exclude))
if (not isinstance(value, (BooleanType, ClassType, ComplexType, DictType, DictionaryType,
FloatType, IntType, ListType, LongType, StringType, TupleType,
UnicodeType, BufferType, BuiltinFunctionType, BuiltinMethodType,
CodeType, FrameType, FunctionType, GeneratorType, InstanceType,
LambdaType, MethodType, ModuleType, SliceType, TracebackType,
TypeType, XRangeType))):
if (hasattr(value, "_toDiffableString")):
s = value._toDiffableString(maxLevel)
elif (hasattr(value, "__str__")):
s = str(value)
elif (hasattr(value, "__dict__")):
s = "%s(%s)" % (type(value), toDiffableString(value.__dict__, maxLevel))
else:
s = str(type(value))
ix2 = s.find(" object at 0x")
if (ix2 > 0):
ix = s.rfind(".")
if (ix > 0):
s = "<class %s>" %s[ix+1:ix2]
elif (isinstance(value, bool)):
if (value):
return "True"
else:
return "False"
elif (isinstance(value, (tuple, list))):
items = []
for v in value:
if (isinstance(v, basestring)):
if (v.find("'") >= 0):
items.append('"%s"' % v)
else:
items.append("'%s'" % v)
else:
items.append(toDiffableString(v, maxLevel))
s = "[" + ", ".join(items) + "]"
elif (isinstance(value, dict)):
items = []
for key, val in value.iteritems():
if (isinstance(val, UnicodeType)):
items.append("'%s': u'%s'" % (key, toDiffableString(val, maxLevel)))
elif (isinstance(val, basestring)):
items.append("'%s': '%s'" % (key, toDiffableString(val, maxLevel)))
else:
items.append("'%s': %s" % (key, toDiffableString(val, maxLevel)))
s = "{" + ", ".join(items) + "}"
else:
s = str(value)
return s
def toDiffableString(value, maxLevel=None):
## if (value == None):
## return "None"
## if ((exclude != None) and not isinstance(value, (basestring, int))):
## for v in exclude:
## if (v is value):
## return "<recursive reference>"
## exclude.append(value)
s = toDiffableRepr(value, maxLevel)
ds = ""
i = s.find(" at 0x")
start = 0
@@ -54,22 +240,43 @@ def toDiffableString(value):
ds += s[start:i]
start = j
i = s.find(" at 0x", start)
return ds + s[start:]
ds = ds + s[start:]
i = ds.find("\\src\\")
if (i < 0):
i = ds.find("/src/")
else:
ds = ds.replace("\\", "/")
if (i > 0):
i += 4
if (ds[i:i+5] == "\\php\\"):
i += 4
elif (ds[i:i+8] == "\\python\\"):
i += 7
ds = "filepath: ..." + ds[i:]
return ds
def toString(value, options=0):
if ((options & PRINT_OBJ_DIFFABLE) > 0):
return toDiffableString(value)
elif (not isinstance(value, basestring)):
return str(value)
return value
def toTypeString(obj):
def typeToString(obj, options=0):
if (isinstance(obj, BooleanType)):
return "bool"
elif (isinstance(obj, UnicodeType)):
if ((options & PRINT_OBJ_DIFFABLE) > 0):
return "string"
return "unicode"
elif (isinstance(obj, basestring)):
return "string"
elif (isinstance(obj, IntType)):
return "int"
elif (isinstance(obj, LongType)):
if ((options & PRINT_OBJ_DIFFABLE) > 0):
return "int"
return "long"
elif (isinstance(obj, FloatType)):
return "float"
elif (type(obj) == ListType):
@@ -79,18 +286,46 @@ def toTypeString(obj):
elif (isinstance(obj, TupleType)):
return "tuple"
elif (isinstance(obj, InstanceType)):
return type(obj)
## ds = str(type(obj))
ds = "<class %s.%s> " % (obj.__module__, obj.__class__.__name__)
else:
return type(obj)
ds = str(type(obj))
if (options == 0):
import activegrid.util.aglogging
options = activegrid.util.aglogging.testMode(0, PRINT_OBJ_DIFFABLE)
if ((options & PRINT_OBJ_DIFFABLE) > 0):
if (ds.startswith("<class ")):
ix = ds.rfind(".")
if (ix < 0):
ix = 8
ds = "<class %s>" % ds[ix+1:-2]
return ds
def nameToString(name, options=0):
if (name.startswith("_v_")):
return name[3:]
if ((options & PRINT_OBJ_DIFFABLE) > 0):
ix = name.find("__")
if ((ix > 1) and name.startswith("_")):
name = name[ix:]
return toDiffableString(name)
return name
PRINT_OBJ_GETATTR = 1
PRINT_OBJ_HIDE_INTERNAL = 2
PRINT_OBJ_COMPACT = 4
PRINT_OBJ_NONONE = 8
PRINT_OBJ_DIFFABLE = 16
PRINT_OBJ_HIDE_EXCLUDED = 32
PRINT_OBJ_INTERNAL = 512
def printObject(out, object, name="", indent=0, flags=0, exclude=None, maxIndent=30):
def printObject(out, object, name=None, indent=0, flags=0, exclude=None, remove=None, maxIndent=30):
if (name == None):
name = ""
## elif (name.endswith("_") and not name.endswith("__")):
## name = name[:-1]
if ((remove != None) and (name in asDict(remove))):
return False
if ((maxIndent != None) and (indent > maxIndent)):
print >> out, " "*indent, "%s: %s" % (name, toString(str(object), flags)),
if ((flags & PRINT_OBJ_INTERNAL) == 0):
@@ -98,12 +333,11 @@ def printObject(out, object, name="", indent=0, flags=0, exclude=None, maxIndent
return True
finalNewLine = False
printed = True
## if (exclude == None):
## exclude = []
if ((flags & PRINT_OBJ_COMPACT) > 0):
if (exclude and object in exclude):
if ((flags & (PRINT_OBJ_COMPACT | PRINT_OBJ_HIDE_EXCLUDED)) > 0):
if ((exclude != None) and ((object in exclude) or (name in exclude))):
return
indent = 0
if ((flags & PRINT_OBJ_COMPACT) > 0):
indent = 0
if ((flags & PRINT_OBJ_INTERNAL) == 0):
finalNewLine = True
flags |= PRINT_OBJ_INTERNAL
@@ -113,23 +347,23 @@ def printObject(out, object, name="", indent=0, flags=0, exclude=None, maxIndent
else:
finalNewLine = False
printed = False
elif (name.startswith("_") and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0)):
elif (name.startswith("_") and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0) and not name.startswith("_v_")):
finalNewLine = False
printed = False
elif (isinstance(object, (list, tuple))):
if ((exclude != None) and object in exclude):
print >> out, " "*indent, name, " : ", toTypeString(object), " of length = ", len(object), " (already printed)",
print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = ", len(object), " (already printed)",
elif ((exclude != None) and name in exclude):
print >> out, " "*indent, name, " : ", toTypeString(object), " of length = ", len(object), " (excluded)",
print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = ", len(object), " (excluded)",
else:
if ((exclude != None) and (len(object) > 0)): exclude.append(object)
print >> out, " "*indent, name, " : ", toTypeString(object), " of length = %d" % len(object),
print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = %d" % len(object),
for i, o in enumerate(object):
print >> out
printObject(out, o, name="[%d]" % i, indent=indent+2, flags=flags, exclude=exclude, maxIndent=maxIndent)
printObject(out, o, name="[%d]" % i, indent=indent+2, flags=flags, exclude=exclude, remove=remove, maxIndent=maxIndent)
elif (isinstance(object, dict)):
if ((exclude != None) and object in exclude):
print >> out, " "*indent, name, " : ", toTypeString(object), " (already printed)",
print >> out, " "*indent, name, " : ", typeToString(object, flags), " (already printed)",
else:
if ((exclude != None) and (len(object) > 0)): exclude.append(object)
if (len(name) > 0):
@@ -147,51 +381,62 @@ def printObject(out, object, name="", indent=0, flags=0, exclude=None, maxIndent
n = key
if (not (isinstance(n, basestring))):
n = str(n)
else:
n = nameToString(n, flags)
if ((not n.startswith("_") or ((flags & PRINT_OBJ_HIDE_INTERNAL) == 0))):
if printObject(out, object[key], name=n, indent=indent+2, flags=(flags | PRINT_OBJ_INTERNAL), exclude=exclude, maxIndent=maxIndent):
if printObject(out, object[key], name=n, indent=indent+2, flags=(flags | PRINT_OBJ_INTERNAL), exclude=exclude, remove=remove, maxIndent=maxIndent):
if ((flags & PRINT_OBJ_COMPACT) == 0):
print >> out
else:
print >> out, ",",
print >> out, " "*indent, "}",
elif (hasattr(object, "__dict__")):
if ((exclude != None) and object in exclude):
print >> out, " "*indent, name, " : ", toTypeString(object), " (already printed) = ", toDiffableString(object),
if (name.startswith("_")): ## and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0)):
print >> out, " "*indent, name, " : ", typeToString(object, flags),
elif ((exclude != None) and ((object in exclude) or (object.__dict__ in exclude))):
print >> out, " "*indent, name, " : ", typeToString(object, flags), " (already printed)",
else:
if (exclude != None): exclude.append(object)
if (name.startswith("_")): ## and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0)):
print >> out, " "*indent, name, " : ", toTypeString(object),
elif ((exclude != None) and object.__dict__ in exclude):
print >> out, " "*indent, name, " : ", toTypeString(object), " (already printed)",
print >> out, " "*indent, name, " : ", typeToString(object, flags),
if ((flags & PRINT_OBJ_GETATTR) == 0):
if ((flags & PRINT_OBJ_COMPACT) == 0):
print >> out
printObject(out, object.__dict__, indent=indent, flags=flags, exclude=exclude, remove=remove, maxIndent=maxIndent)
else:
print >> out, " "*indent, name, " : ", toTypeString(object),
if ((flags & PRINT_OBJ_GETATTR) == 0):
if ((flags & PRINT_OBJ_COMPACT) == 0):
if ((flags & PRINT_OBJ_COMPACT) == 0):
print >> out
## indent += 2
print >> out, " "*indent, "{",
keys = object.__dict__.keys()
keys.sort()
printed = True
for key in keys:
if ((exclude != None) and (key in exclude)):
continue
if (printed and ((flags & PRINT_OBJ_COMPACT) == 0)):
print >> out
printObject(out, object.__dict__, indent=indent, flags=flags, exclude=exclude, maxIndent=maxIndent)
else:
keys = object.__dict__.keys()
keys.sort()
for n in keys:
if ((flags & PRINT_OBJ_COMPACT) == 0):
print >> out
printObject(out, getattr(object, n), name=n, indent=indent+2, flags=flags, exclude=exclude, maxIndent=maxIndent)
n = nameToString(key, flags)
printed = printObject(out, getattr(object, n), name=n, indent=indent+2, flags=flags, exclude=exclude, remove=remove, maxIndent=maxIndent)
if ((flags & PRINT_OBJ_COMPACT) == 0):
print >> out
print >> out, " "*indent, "}",
elif (indent < 0):
print >> out, object,
elif isinstance(object, basestring):
if ((exclude != None) and name in exclude):
print >> out, " "*indent, name, " : ", toTypeString(object), " of length = ", len(object), " (excluded)",
print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = ", len(object), " (excluded)",
elif (len(object) > 100):
print >> out, " "*indent, name, ":", toTypeString(object), "[%d] = %s...%s" % (len(object), object[:50], object[-50:]),
object = toString(object, flags)
print >> out, " "*indent, name, ":", typeToString(object, flags), "[%d] = %s...%s" % (len(object), object[:50], object[-50:]),
else:
print >> out, " "*indent, name, ":", toTypeString(object), "=", str(object),
print >> out, " "*indent, name, ":", typeToString(object, flags), "=", toString(object, flags),
## elif (isinstance(object, float)):
## val = str(object)
## if (len(val) > 17):
## val = val[:17]
## print >> out, " "*indent, name, ":", type(object), "=", val,
else:
print >> out, " "*indent, name, ":", toTypeString(object), "=", str(object),
print >> out, " "*indent, name, ":", typeToString(object, flags), "=", toString(object, flags),
if (finalNewLine):
print >> out
return printed

View File

@@ -0,0 +1,380 @@
#----------------------------------------------------------------------------
# Name: parser.py
# Purpose: parsing utilities
#
# Author: Jeff Norton
#
# Created: 8/9/05
# CVS-ID: $Id$
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
import re
from activegrid.util.lang import *
ifDefPy()
import string
import array
endIfDef()
XPATH_ROOT_VAR = '__rootObj__'
GETOBJECTPARTNAMES = ["primaryRef", "ref", "orderings", "limit"]
class Tokenizer(object):
TOKEN_IDENT = 1
TOKEN_STRING = 2
TOKEN_OP = 3
TOKEN_WS = 4
## TOKEN_PLACEHOLDER = 5
def __init__(self, text, identStart=None, tokenSep=None, ignoreWhitespace=True):
"""
Turn a string into individual tokens. Three types of tokens are recognized:
TOKEN_IDENT: identifiers (those that start with the identStart pattern)
TOKEN_STRING: quoted string
TOKEN_OP: everything else
Tokens are separated by white space or the tokenSep pattern.
Constructor parameters:
text: The string to tokenize
identStart: A regular expression describing characters which start an identifier
The default expression accepts letters, "_", and "/".
tokenSep: A regular expression describing the characters which end a token
(in addition to whitespace). The default expression accepts
anything except alpha-numerics, "_", "/", and ":".
Usage:
Invoke getNextToken (or next) to get the next token. The instance variables
token, and tokenVal will be populated with the current token type (TOKEN_IDENT,
TOKEN_STRING, or TOEKN_OP) and value respectively. nextToken and nextTokenVal
will also be available for lookahead. The next method is similar to
getNextToken but also returns the token value. A value of None signals end
of stream.
"""
self.ignoreWhitespace=ignoreWhitespace
ifDefPy()
if (isinstance(text, array.array)):
text = text.tostring()
endIfDef()
self.text = asString(text)
self.textIndex = 0
self.textLen = len(self.text)
self.token = None
self.tokenVal = None
self.nextToken = None
self.nextTokenVal = None
if (identStart == None):
identStart = "[a-zA-Z_/]"
if (tokenSep == None):
tokenSep = "[^a-zA-Z0-9_/:]"
self.identStart = re.compile(identStart)
self.tokenSep = re.compile(tokenSep)
self.getNextToken() # Prime the pump
def isEscaped(text, index):
if ((index > 0) and (text[index-1] == '\\') and ((index < 2) or (text[index-2] != '\\'))):
return True
return False
isEscaped = staticmethod(isEscaped)
def findClosingQuote(text, index, char):
index = index + 1
while True:
endIndex = text.find(char, index)
if (endIndex < 1):
return -1
if (Tokenizer.isEscaped(text, endIndex)):
index = endIndex+1
else:
break
return endIndex + 1
findClosingQuote = staticmethod(findClosingQuote)
def _findClosing(self, char):
if (self.textIndex >= self.textLen):
raise Exception("The text \"%s\" has an unmatched string starting at %d" % (self.text, self.textIndex))
index = Tokenizer.findClosingQuote(self.text, self.textIndex, char)
if (index < 0):
raise Exception("The text \"%s\" has an unmatched string starting at %d" % (self.text, self.textIndex-1))
return index
def next(self):
self.getNextToken()
if (self.token == None):
raise StopIteration()
return self.tokenVal
def getNextToken(self):
self.token = self.nextToken
self.tokenVal = self.nextTokenVal
while (self.textIndex < self.textLen):
c = self.text[self.textIndex]
if (c not in string.whitespace):
if (c == '"' or c == "'" or c == '`'):
endIndex = self._findClosing(c)
self.nextToken = self.TOKEN_STRING
self.nextTokenVal = self.text[self.textIndex:endIndex]
self.textIndex = endIndex
return
elif (self.identStart.search(c)):
endMatch = self.tokenSep.search(self.text, self.textIndex+1)
if (endMatch):
endIndex = endMatch.start()
else:
endIndex = self.textLen
self.nextToken = self.TOKEN_IDENT
self.nextTokenVal = self.text[self.textIndex:endIndex]
self.textIndex = endIndex
return
else:
self.nextToken = self.TOKEN_OP
endIndex = self.textIndex + 1
if (c == '<' or c == '>' or c == '!' or c == '='):
if ((endIndex < self.textLen) and (self.text[endIndex] == '=')):
endIndex += 1
elif ((c == '%') and (endIndex < self.textLen)):
c = self.text[endIndex]
if (c in ['d', 'i', 'o', 'u', 'x', 'X', 'e', 'E', 'f', 'F', 'g', 'G', 'c', 'r', 's', '%']):
endIndex += 1
## self.nextToken = self.TOKEN_PLACEHOLDER # Should really be this but no one can handle it yet
self.nextTokenVal = self.text[self.textIndex:endIndex]
self.textIndex = endIndex
return
elif not self.ignoreWhitespace:
self.nextToken=self.TOKEN_WS
self.nextTokenVal=""
while c in string.whitespace:
self.nextTokenVal+=c
self.textIndex+=1
if self.textIndex==len(self.text):
break
c=self.text[self.textIndex]
return
self.textIndex += 1
self.nextToken = None
self.nextTokenVal = None
def isXPathNonVar(var):
"""Returns true iff var is a string ("foo" or 'foo') or a number."""
if (var.startswith("'") and var.endswith("'")) or \
(var.startswith('"') and var.endswith('"')):
return True
# list from XPathToCode, below
if var.lower() in ["count", "empty", "true", "false", "null", "and", "or", \
"like", "not"]:
return True
try:
t=int(var)
return True
except TypeError, e:
pass
except ValueError, e:
pass
return False
def xpathToCode(xpaths, convertBracket=True):
if ((xpaths == None) or (len(xpaths) < 1)):
return "True"
if (not isinstance(xpaths, (list, tuple))):
xpaths = [xpaths]
result = []
for xpath in xpaths:
t = Tokenizer(xpath, "[a-zA-Z0-9_/:\.]", "[^a-zA-Z0-9_/:\.]", ignoreWhitespace=False)
expr = []
lastToken=None
while t.nextToken != None:
t.getNextToken()
if (t.token == Tokenizer.TOKEN_WS):
expr.append(" ")
elif (t.token == Tokenizer.TOKEN_OP):
if (t.tokenVal == "="):
expr.append("==")
elif (t.tokenVal == "[" and convertBracket):
expr.append("(")
elif (t.tokenVal == "]" and convertBracket):
expr.append(")")
else:
expr.append(t.tokenVal)
elif (t.token == Tokenizer.TOKEN_IDENT):
if (t.tokenVal == "and"):
expr.append(" and ")
elif (t.tokenVal == "or"):
expr.append(" or ")
elif (t.tokenVal == "not"):
expr.append(" not ")
elif (t.tokenVal == "like"):
# REVIEW stoens@activegrid.com 02-Nov-05 --
# This is very limited support for like:
# typically like queries look like this: "foo like 'blah%'".
# So translate this into "foo.startswith(blah)".
# We should use a regular expression to support '%'s in
# arbitrary places in the string. After 1.1.
if t.nextToken and t.nextTokenVal.endswith("%'"):
t.getNextToken() # throw away the "like" token
last = len(expr) - 1
expr[last] = "%s.startswith(%s')"\
% (expr[last], t.tokenVal[:-2])
else:
# old behavior
expr.append(t.tokenVal)
elif (t.tokenVal == "count"):
expr.append("len")
elif (t.tokenVal == 'empty'):
expr.append('ctx.isEmptyPath')
elif (t.tokenVal == 'true'):
expr.append(_parseConstantFunction(t, 'True'))
elif (t.tokenVal == 'false'):
expr.append(_parseConstantFunction(t, 'False'))
elif (t.tokenVal == 'null'):
expr.append(_parseConstantFunction(t, 'None'))
elif (-1!=t.tokenVal.find(':')):
serviceDef, args=_parseServiceFunction(t)
# XXX handle serviceDef, args being None
for i in range(len(args)):
args[i]=xpathToCode(args[i], False)
jargs="[%s]" % (",".join(args))
# XXX should be processmodel.DATASERVICE_PROCESS_NAME, not "dataservice"
if serviceDef[0]=='dataservice':
expr.append("runtimesupport.invokeDataServiceWrapper(%s, %s, ctx, locals())" % \
(serviceDef, jargs))
else:
expr.append("runtimesupport.invokeServiceWrapper(%s, %s, ctx)" % \
(serviceDef, jargs))
else:
if (lastToken==')' or lastToken==']'):
wasFunc=True
else:
wasFunc=False
if (t.tokenVal.startswith('/')) and not wasFunc:
expr.append(XPATH_ROOT_VAR)
expr.append(t.tokenVal.replace('/','.'))
lastToken=t.tokenVal
else:
expr.append(t.tokenVal)
if (len(expr) == 2 and expr[0]==" "):
expr = "".join(expr)
result.append(expr)
elif (len(expr) > 1):
expr = "".join(expr)
result.append("(%s)" % expr)
elif (len(expr) > 0):
result.append(expr[0])
return " and ".join(result)
def _parseArgs(t):
args=[]
argcon=""
if t.tokenVal!='(':
return []
if t.nextTokenVal==')':
t.getNextToken()
return []
depth=1
while(depth!=0):
if not t.nextToken:
raise Exception("parameters list with no closing ) after token: %s" % t.tokenVal)
t.getNextToken()
if t.tokenVal=='(':
depth+=1
if t.tokenVal==')':
depth-=1
if depth==0 or (depth==1 and t.tokenVal==','):
args.append(argcon)
argcon=""
else:
argcon+=t.tokenVal
return args
def _parseServiceFunction(t):
"""Parses what appears to be a service function call into serviceDefs and args lists.
Returns None, None if the serviceFunction appears to be invalid.
"""
if t.nextTokenVal!='(':
return t.tokenVal, None
serviceDef=t.tokenVal.split(':')
t.getNextToken()
args=_parseArgs(t)
return serviceDef, args
def _parseConstantFunction(t, outputValue):
firstVal = t.tokenVal
if t.nextTokenVal != '(':
return firstVal
t.getNextToken()
if t.nextTokenVal != ')':
return "%s%s" % (firstVal, '(')
t.getNextToken()
return outputValue
def parseDSPredicate(ctx, str, vars, valueList=None):
from activegrid.util.utillang import evalCode
from activegrid.util.utillang import ObjAsDict
if valueList == None:
valueList = []
indexVar=0
oldIndexVar=0
sourceStr=str
inlinedPredicate=[]
qualifications=[]
while True:
oldIndexVar = indexVar
dollarCurlForm = False
quoted = False
indexVar = sourceStr.find("bpws:getVariableData", indexVar)
if indexVar == -1:
indexVar = sourceStr.find("${", oldIndexVar)
if indexVar == -1:
break
dollarCurlForm = True
if indexVar > 0 and sourceStr[indexVar-1] in ('"',"'"):
quoted = True
if not dollarCurlForm:
openParen = sourceStr.find("(", indexVar)
if openParen == -1:
break
closeParen = sourceStr.find(")", openParen)
if closeParen == -1:
break
else:
openParen = indexVar+1
closeParen = sourceStr.find("}", openParen)
if closeParen == -1:
break
varRef = sourceStr[openParen+1: closeParen]
if varRef.startswith('"') or varRef.startswith("'"):
varRef = varRef[1:]
if varRef.endswith('"') or varRef.endswith("'"):
varRef = varRef[:-1]
if isinstance(vars, dict) or isinstance(vars, ObjAsDict):
varRefCode = xpathToCode(varRef)
value = evalCode(varRefCode, vars)
else:
value = ctx.evalPath(vars, varRef)
inlinedPredicate.append(sourceStr[oldIndexVar:indexVar])
if quoted:
inlinedPredicate.append("%s" % value)
else:
inlinedPredicate.append('%s')
valueList.append(value)
indexVar = closeParen+1
inlinedPredicate.append(sourceStr[oldIndexVar:])
qualifications.append(''.join(inlinedPredicate))
return qualifications, valueList

View File

@@ -0,0 +1,111 @@
#----------------------------------------------------------------------------
# Name: strutils.py
# Purpose: String Utilities
#
# Author: Morgan Hua
#
# Created: 11/3/05
# CVS-ID: $Id$
# Copyright: (c) 2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
def caseInsensitiveCompare(s1, s2):
""" Method used by sort() to sort values in case insensitive order """
s1L = s1.lower()
s2L = s2.lower()
if s1L == s2L:
return 0
elif s1L < s2L:
return -1
else:
return 1
def multiSplit(stringList, tokenList=[" "]):
"""Splits strings in stringList by tokens, returns list of string."""
if not stringList: return []
if isinstance(tokenList, basestring):
tokenList = [tokenList]
if isinstance(stringList, basestring):
stringList = [stringList]
rtnList = stringList
for token in tokenList:
rtnList = rtnList[:]
for string in rtnList:
if string.find(token) > -1:
rtnList.remove(string)
names = string.split(token)
for name in names:
name = name.strip()
if name:
rtnList.append(name)
return rtnList
QUOTES = ("\"", "'")
def _findArgStart(argStr):
i = -1
for c in argStr:
i += 1
if (c == " "):
continue
elif (c == ","):
continue
return i
return None
def _findArgEnd(argStr):
quotedArg = True
argEndChar = argStr[0]
if (not argEndChar in QUOTES):
argEndChar = ","
quotedArg = False
i = -1
firstChar = True
for c in argStr:
i+= 1
if (firstChar):
firstChar = False
if (quotedArg):
continue
if (c == argEndChar):
if (quotedArg):
return min(i+1, len(argStr))
else:
return i
return i
def parseArgs(argStr, stripQuotes=False):
"""
Given a str representation of method arguments, returns list arguments (as
strings).
Input: "('[a,b]', 'c', 1)" -> Output: ["'[a,b]'", "'c'", "1"].
If stripQuotes, removes quotes from quoted arg.
"""
if (argStr.startswith("(")):
argStr = argStr[1:]
if (argStr.endswith(")")):
argStr = argStr[:-1]
else:
raise AssertionError("Expected argStr to end with ')'")
rtn = []
argsStr = argStr.strip()
while (True):
startIndex = _findArgStart(argStr)
if (startIndex == None):
break
argStr = argStr[startIndex:]
endIndex = _findArgEnd(argStr)
if (endIndex == len(argStr) - 1):
rtn.append(argStr.strip())
break
t = argStr[:endIndex].strip()
if (stripQuotes and t[0] in QUOTES and t[-1] in QUOTES):
t = t[1:-1]
rtn.append(t)
argStr = argStr[endIndex:]
return rtn

View File

@@ -0,0 +1,116 @@
#----------------------------------------------------------------------------
# Name: sysutils.py
# Purpose: System Utilities
#
# Author: Joel Hare
#
# Created: 7/28/04
# CVS-ID: $Id$
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
import sys
import os
import time
# this will be set to true in IDE.py when we are running release builds.
isRelease = False
# Commented out for now.....
# Required for Unicode support with python
# Put over here because of py2exe problems
# Python suggests modifying site.py
#if hasattr(sys,"setdefaultencoding"):
# sys.setdefaultencoding("UTF-8")
MAINMODULE_DIR = "AG_MAINMODULE_DIR"
IS_RELEASE = "AG_IS_RELEASE"
IS_COMMERCIAL = "AG_IS_COMMERCIAL"
AG_SYSTEM_START_TIME_ENV_NAME = "AG_SYSTEM_START_TIME"
def isCommercial():
return os.path.exists(os.path.join(mainModuleDir,"commercial.txt")) or 'true' == (str(os.getenv(IS_COMMERCIAL)).lower())
def isRelease():
return 'true' == (str(os.getenv(IS_RELEASE)).lower())
def setRelease(value):
if value:
os.environ[IS_RELEASE]= "TRUE"
else:
os.environ[IS_RELEASE]= "FALSE"
def isWindows():
return os.name == 'nt'
__isServer = False
def setServerMode(isServer):
global __isServer
__isServer = isServer
def isServer():
global __isServer
return __isServer
def _generateMainModuleDir():
mainModuleDir = os.getenv(MAINMODULE_DIR)
if mainModuleDir: # if environment variable set, return it
return mainModuleDir
# On Mac, the python executable sometimes has a capital "P" so we need to
# lower the string first
sysExecLower = sys.executable.lower()
if sysExecLower == "/" or sysExecLower.find('python') != -1 or sysExecLower.find('apache') != -1:
utilModuleDir = os.path.dirname(__file__)
if not os.path.isabs(utilModuleDir):
utilModuleDir = os.path.join(os.getcwd(), utilModuleDir)
mainModuleDir = os.path.normpath(os.path.join(utilModuleDir, os.path.join(os.path.pardir, os.path.pardir)))
if mainModuleDir.endswith('.zip'):
mainModuleDir = os.path.dirname(mainModuleDir) # Get rid of library.zip
else:
mainModuleDir = os.path.dirname(sys.executable)
os.environ[MAINMODULE_DIR] = mainModuleDir # pythonBug: os.putenv doesn't work, set environment variable
return mainModuleDir
mainModuleDir = _generateMainModuleDir()
def _generatePythonExecPath():
# On Mac, the python executable sometimes has a capital "P" so we need to
# lower the string first
sysExecLower = sys.executable.lower()
if sysExecLower.find('python') != -1 or sysExecLower.find('apache') != -1:
pythonExecPath = sys.executable
else:
# this is where py2app puts the Python executable
if sys.platform == "darwin":
pythonExecPath = os.path.join(os.path.dirname(sys.executable), "../Frameworks/Python.Framework/Versions/2.4/Python/bin")
else:
pythonExecPath = os.path.join(os.path.dirname(sys.executable), '3rdparty\python2.4\python')
return pythonExecPath
pythonExecPath = _generatePythonExecPath()
def getCommandNameForExecPath(execPath):
if isWindows():
return '"%s"' % execPath
return execPath
def getUserName():
if isWindows():
return os.getenv('USERNAME')
else:
# 06-Feb-06 stoens@activegrid.com --
# this blows up the linux cc runs with "Inappropriate ioctl for device"
#return os.getlogin()
return os.getenv('USER')
def getCurrentTimeAsFloat():
return time.time()
systemStartTime = getCurrentTimeAsFloat()

View File

@@ -0,0 +1,146 @@
#----------------------------------------------------------------------------
# Name: utillang.py
# Purpose: Provide language specific utilities
#
# Author: Joel Hare
#
# Created: 8/23/05
# CVS-ID: $Id$
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
import os
import sys
import UserDict
import tempfile
import xml.sax.saxutils as saxutils
import activegrid.util.parser as parser
PY2WEB_codepages = {
'cp1251' : 'CP-1251',
'koi8_r' : 'KOI8-R',
}
def evalXPath(xpath, data, specialEntries=None):
codeStr = parser.xpathToCode(xpath)
return evalCode(codeStr, data, specialEntries)
def evalCode(codeStr, data, specialEntries=None):
if isinstance(data, ObjAsDict):
namespace = data
elif isinstance(data, dict):
namespace = dict(data)
else:
namespace = ObjAsDict(data)
if specialEntries:
for key, value in specialEntries.items():
namespace.addSpecialEntry(key, value)
return eval(codeStr, {}, namespace)
def deriveCharset():
charset = None
encodingString = sys.getdefaultencoding()
if encodingString != 'ascii':
charset = PY2WEB_codepages.get(encodingString.lower())
if charset == None:
charset = encodingString
return charset
def toUTF8(value):
"""
Converts all unicode and non-string values to utf-8.
This assumes string instances are already encoded in utf-8.
Note that us-ascii is a subset of utf-8.
"""
if isinstance(value, unicode):
return value.encode('utf-8')
return str(value)
def toUnicode(value):
"""
Converts all strings non-string values to unicode.
This assumes string instances are encoded in utf-8.
Note that us-ascii is a subset of utf-8.
"""
if not isinstance(value, unicode):
if not isinstance(value, str):
return unicode(value)
return unicode(value, 'utf-8')
return value
def getSystemTempDir():
return tempfile.gettempdir()
def getEnvVar(name, defaultVal=None):
if os.environ.has_key(name):
return os.environ[name]
return defaultVal
class ObjAsDict(UserDict.DictMixin):
"""
Passing this to eval as the local variables dictionary allows the
evaluated code to access properties in the wrapped object
"""
def __init__(self, obj):
self.obj = obj
self.specialEntries = {}
def __getitem__(self, key):
try:
return getattr(self.obj, key)
except AttributeError, e:
if self.specialEntries.has_key(key):
return self.specialEntries[key]
raise KeyError(e.args)
def __setitem__(self, key, item): setattr(self.obj, key, item)
def __delitem__(self, key): delattr(self.obj, key)
def keys(self):
ret=[]
for i in list(dir(self.obj)+self.specialEntries.keys()):
if i=="__doc__" or i=="__module__":
pass
elif i not in ret:
ret.append(i)
return ret
def addSpecialEntry(self, key, value):
self.specialEntries[key] = value
global saxXMLescapeDoubleQuote
saxXMLescapeDoubleQuote = {'"':'&quot;'}
global saxXMLescapesAllQuotes
# IE doesn't support &apos; but it doesn't seem like we should need this escaped at all so I took it out.
saxXMLescapesAllQuotes = {'"':'&quot;', "'":"&#039;"}
global saxXMLunescapes
saxXMLunescapes = {'&quot;':'"', "&#039;":"'"}
def escape(data, extraEscapes=None):
"""Escape ', ", &, <, and > in a string of data.
Basically, everything that saxutils.escape does (and this calls that, at
least for now), but with " and ' added as well.
TODO: make this faster; saxutils.escape() is really slow
"""
global saxXMLescapeDoubleQuote
if (extraEscapes == None):
extraEscapes = saxXMLescapeDoubleQuote
return saxutils.escape(data, extraEscapes)
def unescape(data):
"""Unescape ', ", &, <, and > in a string of data.
Basically, everything that saxutils.unescape does (and this calls that, at
least for now), but with " and ' added as well.
TODO: make this faster; saxutils.unescape() is really slow
"""
global saxXMLunescapes
return saxutils.unescape(data, saxXMLunescapes)

File diff suppressed because it is too large Load Diff

View File

@@ -9,8 +9,10 @@
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
import xml.sax
from activegrid.util.lang import *
ifDefPy()
import xml.sax
endIfDef()
class XMLPrettyPrinter(xml.sax.ContentHandler):
def __init__(self, indentationChar=' ', newlineChar='\n'):

View File

@@ -10,80 +10,258 @@
# License: wxWindows License
#----------------------------------------------------------------------------
from activegrid.util.lang import *
import os
import time
import urllib
import logging
from activegrid.util.lang import *
import activegrid.util.objutils as objutils
import activegrid.util.xmlmarshaller as xmlmarshaller
import activegrid.util.aglogging as aglogging
agKnownTypes = None
def defaultLoad(fileObject, knownTypes=None):
xml = fileObject.read()
loadedObject = unmarshal(xml, knownTypes=knownTypes)
if hasattr(fileObject, 'name'):
loadedObject.fileName = os.path.abspath(fileObject.name)
loadedObject.initialize()
xmlLogger = logging.getLogger("activegrid.util.xml")
def load(fileName, knownTypes=None, knownNamespaces=None, createGenerics=False):
loadedObject = None
fileObject = file(fileName)
timeStart = time.time()
xml = ""
try:
xml = fileObject.read()
loadedObject = unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces, xmlSource=fileName, createGenerics=createGenerics)
loadedObject.fileName = os.path.abspath(fileName)
if hasattr(loadedObject, 'initialize'):
loadedObject.initialize()
finally:
fileObject.close()
if xmlLogger.isEnabledFor(aglogging.LEVEL_INFO):
timeDone = time.time()
aglogging.info(xmlLogger, ('Load statistics for file %s (%d bytes): elapsed time = %f secs' % (fileName, len(xml), timeDone-timeStart)))
return loadedObject
def unmarshal(xml, knownTypes=None):
if not knownTypes: knownTypes = getAgKnownTypes()
return xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
def loadURI(uri, knownTypes=None, knownNamespaces=None, xmlSource=None, createGenerics=False):
loadedObject = None
timeStart = time.time()
xml = ""
try:
xml = urllib.urlopen(uri).read()
loadedObject = unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces, xmlSource=xmlSource, createGenerics=createGenerics)
loadedObject.fileName = uri
if hasattr(loadedObject, 'initialize'):
loadedObject.initialize()
finally:
if xmlLogger.isEnabledFor(aglogging.LEVEL_INFO):
timeDone = time.time()
aglogging.info(xmlLogger, ('Load statistics for URI %s (%d bytes): elapsed time = %f secs' % (uri, len(xml), timeDone-timeStart)))
return loadedObject
def defaultSave(fileObject, objectToSave, prettyPrint=True, knownTypes=None, encoding='utf-8'):
xml = marshal(objectToSave, prettyPrint=prettyPrint, knownTypes=knownTypes, encoding=encoding)
fileObject.write(xml)
fileObject.flush()
def unmarshal(xml, knownTypes=None, knownNamespaces=None, xmlSource=None, createGenerics=False):
if (knownTypes == None):
knownTypes, knownNamespaces = getAgKnownTypes()
return xmlmarshaller.unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces, xmlSource=xmlSource, createGenerics=createGenerics)
def marshal(objectToSave, prettyPrint=True, knownTypes=None, encoding='utf-8'):
if not knownTypes: knownTypes = getAgKnownTypes()
return xmlmarshaller.marshal(objectToSave, prettyPrint=prettyPrint, knownTypes=knownTypes, encoding=encoding)
def save(fileName, objectToSave, prettyPrint=True, marshalType=True, knownTypes=None, knownNamespaces=None, encoding='utf-8'):
if hasattr(objectToSave, '_xmlReadOnly') and objectToSave._xmlReadOnly == True:
raise xmlmarshaller.MarshallerException('Error marshalling object to file "%s": object is marked "readOnly" and cannot be written' % (fileName))
timeStart = time.time()
xml = marshal(objectToSave, prettyPrint=prettyPrint, marshalType=marshalType, knownTypes=knownTypes, knownNamespaces=knownNamespaces, encoding=encoding)
fileObject = file(fileName, 'w')
try:
fileObject.write(xml)
fileObject.flush()
except Exception, errorData:
fileObject.close()
raise xmlmarshaller.MarshallerException('Error marshalling object to file "%s": %s' % (fileName, str(errorData)))
fileObject.close()
timeDone = time.time()
aglogging.info(xmlLogger, ('Save statistics for file %s: elapsed time = %f secs' % (fileName, timeDone-timeStart)))
def cloneObject(objectToClone, knownTypes=None, encoding='utf-8'):
if not knownTypes: knownTypes = getAgKnownTypes()
xml = xmlmarshaller.marshal(objectToClone, prettyPrint=True, knownTypes=knownTypes, encoding=encoding)
clonedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
def marshal(objectToSave, prettyPrint=True, marshalType=True, knownTypes=None, knownNamespaces=None, encoding='utf-8'):
if (knownTypes == None):
knownTypes, knownNamespaces = getAgKnownTypes()
return xmlmarshaller.marshal(objectToSave, prettyPrint=prettyPrint, marshalType=marshalType, knownTypes=knownTypes, knownNamespaces=knownNamespaces, encoding=encoding)
def addNSAttribute(xmlDoc, shortNamespace, longNamespace):
if not hasattr(xmlDoc, "__xmlnamespaces__"):
xmlDoc.__xmlnamespaces__ = {shortNamespace:longNamespace}
elif shortNamespace not in xmlDoc.__xmlnamespaces__:
if (hasattr(xmlDoc.__class__, "__xmlnamespaces__")
and (xmlDoc.__xmlnamespaces__ is xmlDoc.__class__.__xmlnamespaces__)):
xmlDoc.__xmlnamespaces__ = dict(xmlDoc.__xmlnamespaces__)
xmlDoc.__xmlnamespaces__[shortNamespace] = longNamespace
def genShortNS(xmlDoc, longNamespace=None):
if not hasattr(xmlDoc, "__xmlnamespaces__"):
return "ns1"
elif longNamespace != None and longNamespace in xmlDoc.__xmlnamespaces__.items():
for key, value in xmlDoc.__xmlnamespaces__.iteritems():
if value == longNamespace:
return key
i = 1
while ("ns%d" % i) in xmlDoc.__xmlnamespaces__:
i += 1
return ("ns%d" % i)
def genTargetNS(fileName, applicationName=None, type=None):
if (applicationName != None):
if (type != None):
tns = "urn:%s:%s:%s" % (applicationName, type, fileName)
else:
tns = "urn:%s:%s" % (applicationName, fileName)
else:
tns = "urn:%s" % fileName
return tns
def splitType(typeName):
index = typeName.rfind(':')
if index != -1:
ns = typeName[:index]
complexTypeName = typeName[index+1:]
else:
ns = None
complexTypeName = typeName
return (ns, complexTypeName)
def cloneObject(objectToClone, knownTypes=None, marshalType=True, knownNamespaces=None, encoding='utf-8'):
if (knownTypes == None):
knownTypes, knownNamespaces = getAgKnownTypes()
xml = xmlmarshaller.marshal(objectToClone, prettyPrint=True, marshalType=marshalType, knownTypes=knownTypes, knownNamespaces=knownNamespaces, encoding=encoding)
clonedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces)
if hasattr(objectToClone, 'fileName'):
clonedObject.fileName = objectToClone.fileName
if hasattr(objectToClone, "_parentDoc"):
clonedObject._parentDoc = objectToClone._parentDoc
try:
clonedObject.initialize()
except AttributeError:
pass
return clonedObject
def getAgKnownTypes():
import activegrid.model.processmodel
import activegrid.model.schema
import activegrid.data.dataservice
import activegrid.server.deployment
global agKnownTypes
if agKnownTypes == None:
tmpAgKnownTypes = {}
AG_TYPE_MAPPING = {
def getAgVersion(fileName):
fileObject = file(fileName)
try:
xml = fileObject.read()
finally:
fileObject.close()
i = xml.find(' ag:version=')
if i >= 0:
i += 12
else:
i2 = xml.find('<ag:')
if i2 >= 0:
i = xml.find(' version=', i2)
if i > 0:
i += 9
elif xml.find('<project version="10"') >= 0:
return "10"
else:
return None
version = None
if xml[i:i+1] == '"':
j = xml.find('"', i+1)
if (j > i+1):
version = xml[i+1:j]
return version
AG_NS_URL = "http://www.activegrid.com/ag.xsd"
BPEL_NS_URL = "http://schemas.xmlsoap.org/ws/2003/03/business-process"
HTTP_WSDL_NS_URL = "http://schemas.xmlsoap.org/wsdl/http/"
MIME_WSDL_NS_URL = "http://schemas.xmlsoap.org/wsdl/mime/"
SOAP_NS_URL = "http://schemas.xmlsoap.org/wsdl/soap/"
SOAP12_NS_URL = "http://schemas.xmlsoap.org/wsdl/soap12/"
SOAP_NS_ENCODING = "http://schemas.xmlsoap.org/soap/encoding/"
WSDL_NS_URL = "http://schemas.xmlsoap.org/wsdl/"
WSSE_NS_URL = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
XFORMS_NS_URL = "http://www.w3c.org/xform.xsd"
XMLSCHEMA_NS_URL = "http://www.w3.org/2001/XMLSchema"
XSI_NS_URL = "http://www.w3.org/2001/XMLSchema-instance"
XACML_NS_URL = "urn:oasis:names:tc:xacml:2.0:policy:schema:os"
KNOWN_NAMESPACES = { AG_NS_URL : "ag",
BPEL_NS_URL : "bpws",
HTTP_WSDL_NS_URL : "http",
MIME_WSDL_NS_URL : "mime",
SOAP_NS_URL : "soap",
SOAP12_NS_URL : "soap12",
WSDL_NS_URL : "wsdl",
WSSE_NS_URL : "wsse",
XFORMS_NS_URL : "xforms",
XMLSCHEMA_NS_URL : "xs",
XACML_NS_URL : "xacml",
}
global agXsdToClassName
agXsdToClassName = None
def getAgXsdToClassName():
global agXsdToClassName
if (agXsdToClassName == None):
agXsdToClassName = {
"ag:append" : "activegrid.model.processmodel.AppendOperation",
"ag:attribute" : "activegrid.model.identitymodel.Attribute",
"ag:body" : "activegrid.model.processmodel.Body",
"ag:cssRule" : "activegrid.model.processmodel.CssRule",
"ag:category_substitutions" : "activegrid.server.layoutrenderer.CategorySubstitutions",
"ag:command" : "activegrid.model.wsdl.Command",
"ag:setElement" : "activegrid.model.processmodel.SetElementOperation",
"ag:css" : "activegrid.server.layoutrenderer.CSS",
"ag:databaseService" : "activegrid.server.deployment.DatabaseService",
"ag:datasource" : "activegrid.data.dataservice.DataSource",
"ag:dataObjectList" : "activegrid.data.datalang.DataObjectList",
"ag:debug" : "activegrid.model.processmodel.DebugOperation",
"ag:deployment" : "activegrid.server.deployment.Deployment",
"ag:glue" : "activegrid.model.processmodel.Glue",
"ag:formData" : "activegrid.model.processmodel.FormData",
"ag:formVar" : "activegrid.model.processmodel.FormVar",
"ag:generator" : "activegrid.server.layoutrenderer.SerializableGenerator",
"ag:head" : "activegrid.server.layoutrenderer.Head",
"ag:hr" : "activegrid.model.processmodel.HorizontalRow",
"ag:identity" : "activegrid.model.identitymodel.Identity",
"ag:identityref" : "activegrid.server.deployment.IdentityRef",
"ag:image" : "activegrid.model.processmodel.Image",
"ag:inputs" : "activegrid.model.processmodel.Inputs",
"ag:inputPart" : "activegrid.model.processmodel.InputPart",
"ag:keystore" : "activegrid.model.identitymodel.KeyStore",
"ag:label" : "activegrid.model.processmodel.Label",
"ag:processmodel" : "activegrid.model.processmodel.ProcessModel",
"ag:processmodelref" : "activegrid.server.deployment.ProcessModelRef",
"ag:layout" : "activegrid.server.layoutrenderer.Layout",
"ag:layouts" : "activegrid.server.layoutrenderer.Layouts",
"ag:ldapsource" : "activegrid.model.identitymodel.LDAPSource",
"ag:localService" : "activegrid.server.deployment.LocalService",
"ag:parameter" : "activegrid.server.layoutrenderer.Parameter",
"ag:parameters" : "activegrid.server.layoutrenderer.Parameters",
"ag:postInitialize" : "activegrid.model.processmodel.PostInitialize",
"ag:processref" : "activegrid.server.deployment.ProcessRef",
"ag:query" : "activegrid.model.processmodel.Query",
"ag:restParameter" : "activegrid.server.deployment.RestParameter",
"ag:soapService" : "activegrid.server.deployment.SoapService",
"ag:redirect" : "activegrid.server.layoutrenderer.Redirect",
"ag:requiredFile" : "activegrid.server.layoutrenderer.RequiredFile",
"ag:resource" : "activegrid.model.identitymodel.IDResource",
"ag:restService" : "activegrid.server.deployment.RestService",
"ag:rewrite" : "activegrid.model.wsdl.Rewrite",
"ag:role" : "activegrid.model.identitymodel.IDRole",
"ag:roledefn" : "activegrid.model.identitymodel.RoleDefn",
"ag:rssService" : "activegrid.server.deployment.RssService",
"ag:rule" : "activegrid.model.identitymodel.IDRule",
"ag:schemaOptions" : "activegrid.model.schema.SchemaOptions",
"ag:schemaref" : "activegrid.server.deployment.SchemaRef",
"ag:serviceCache" : "activegrid.server.deployment.ServiceCache",
"ag:serviceExtension": "activegrid.model.wsdl.ServiceExtension",
"ag:serviceExtensions": "activegrid.model.wsdl.ServiceExtensions",
"ag:serviceParameter": "activegrid.server.deployment.ServiceParameter",
"ag:serviceref" : "activegrid.server.deployment.ServiceRef",
"ag:set" : "activegrid.model.processmodel.SetOperation",
"ag:skinref" : "activegrid.server.deployment.SkinRef",
"ag:skin" : "activegrid.server.layoutrenderer.Skin",
"ag:skin_element_ref": "activegrid.server.layoutrenderer.SkinElementRef",
"ag:skin_element" : "activegrid.server.layoutrenderer.SkinElement",
"ag:skins" : "activegrid.server.layoutrenderer.Skins",
"ag:substitution" : "activegrid.server.layoutrenderer.Substitution",
"ag:text" : "activegrid.model.processmodel.Text",
"ag:title" : "activegrid.model.processmodel.Title",
"ag:view" : "activegrid.model.processmodel.View",
"ag:usertemplate" : "activegrid.model.identitymodel.UserTemplate",
"ag:xformref" : "activegrid.server.deployment.XFormRef",
"bpws:case" : "activegrid.model.processmodel.BPELCase",
"bpws:catch" : "activegrid.model.processmodel.BPELCatch",
"bpws:faultHandlers" : "activegrid.model.processmodel.BPELFaultHandlers",
"bpws:flow" : "activegrid.model.processmodel.BPELFlow",
"bpws:invoke" : "activegrid.model.processmodel.BPELInvoke",
"bpws:onMessage" : "activegrid.model.processmodel.BPELOnMessage",
"bpws:otherwise" : "activegrid.model.processmodel.BPELOtherwise",
@@ -98,31 +276,128 @@ def getAgKnownTypes():
"bpws:variable" : "activegrid.model.processmodel.BPELVariable",
"bpws:variables" : "activegrid.model.processmodel.BPELVariables",
"bpws:while" : "activegrid.model.processmodel.BPELWhile",
"wsdl:message" : "activegrid.model.processmodel.WSDLMessage",
"wsdl:part" : "activegrid.model.processmodel.WSDLPart",
"http:address" : "activegrid.model.wsdl.HttpAddress",
"http:binding" : "activegrid.model.wsdl.HttpBinding",
"http:operation" : "activegrid.model.wsdl.HttpOperation",
"http:urlEncoded" : "activegrid.model.wsdl.HttpUrlEncoded",
"mime:content" : "activegrid.model.wsdl.MimeContent",
"mime:mimeXml" : "activegrid.model.wsdl.MimeMimeXml",
"soap:address" : "activegrid.model.wsdl.SoapAddress",
"soap:binding" : "activegrid.model.wsdl.SoapBinding",
"soap:body" : "activegrid.model.wsdl.SoapBody",
"soap:fault" : "activegrid.model.wsdl.SoapFault",
"soap:header" : "activegrid.model.wsdl.SoapHeader",
"soap:operation" : "activegrid.model.wsdl.SoapOperation",
"soap12:address" : "activegrid.model.wsdl.Soap12Address",
"soap12:binding" : "activegrid.model.wsdl.Soap12Binding",
"soap12:body" : "activegrid.model.wsdl.Soap12Body",
"soap12:fault" : "activegrid.model.wsdl.Soap12Fault",
"soap12:header" : "activegrid.model.wsdl.Soap12Header",
"soap12:operation" : "activegrid.model.wsdl.Soap12Operation",
"wsdl:binding" : "activegrid.model.wsdl.WsdlBinding",
"wsdl:definitions" : "activegrid.model.wsdl.WsdlDocument",
"wsdl:documentation" : "activegrid.model.wsdl.WsdlDocumentation",
"wsdl:fault" : "activegrid.model.wsdl.WsdlFault",
"wsdl:import" : "activegrid.model.wsdl.WsdlImport",
"wsdl:input" : "activegrid.model.wsdl.WsdlInput",
"wsdl:message" : "activegrid.model.wsdl.WsdlMessage",
"wsdl:operation" : "activegrid.model.wsdl.WsdlOperation",
"wsdl:output" : "activegrid.model.wsdl.WsdlOutput",
"wsdl:part" : "activegrid.model.wsdl.WsdlPart",
"wsdl:port" : "activegrid.model.wsdl.WsdlPort",
"wsdl:portType" : "activegrid.model.wsdl.WsdlPortType",
"wsdl:service" : "activegrid.model.wsdl.WsdlService",
"wsdl:types" : "activegrid.model.wsdl.WsdlTypes",
"xacml:Action" : "activegrid.model.identitymodel.XACMLAction",
"xacml:ActionAttributeDesignator" : "activegrid.model.identitymodel.XACMLActionAttributeDesignator",
"xacml:ActionMatch" : "activegrid.model.identitymodel.XACMLActionMatch",
"xacml:Actions" : "activegrid.model.identitymodel.XACMLActions",
"xacml:AttributeValue" : "activegrid.model.identitymodel.XACMLAttributeValue",
"xacml:Policy" : "activegrid.model.identitymodel.XACMLPolicy",
"xacml:Resource" : "activegrid.model.identitymodel.XACMLResource",
"xacml:ResourceAttributeDesignator" : "activegrid.model.identitymodel.XACMLResourceAttributeDesignator",
"xacml:ResourceMatch" : "activegrid.model.identitymodel.XACMLResourceMatch",
"xacml:Resources" : "activegrid.model.identitymodel.XACMLResources",
"xacml:Rule" : "activegrid.model.identitymodel.XACMLRule",
"xacml:Target" : "activegrid.model.identitymodel.XACMLTarget",
"xforms:copy" : "activegrid.model.processmodel.XFormsCopy",
"xforms:group" : "activegrid.model.processmodel.XFormsGroup",
"xforms:include" : "activegrid.model.processmodel.XFormsInclude",
"xforms:input" : "activegrid.model.processmodel.XFormsInput",
"xforms:item" : "activegrid.model.processmodel.XFormsItem",
"xforms:itemset" : "activegrid.model.processmodel.XFormsItemset",
"xforms:label" : "activegrid.model.processmodel.XFormsLabel",
"xforms:model" : "activegrid.model.processmodel.XFormsModel",
"xforms:output" : "activegrid.model.processmodel.XFormsOutput",
"xforms:secret" : "activegrid.model.processmodel.XFormsSecret",
"xforms:select1" : "activegrid.model.processmodel.XFormsSelect1",
"xforms:submission" : "activegrid.model.processmodel.XFormsSubmission",
"xforms:submit" : "activegrid.model.processmodel.XFormsSubmit",
"xforms:value" : "activegrid.model.processmodel.XFormsValue",
"xforms:xform" : "activegrid.model.processmodel.View",
"xforms:xforms" : "activegrid.model.processmodel.XFormsRoot",
"xs:all" : "activegrid.model.schema.XsdSequence",
"xs:any" : "activegrid.model.schema.XsdAny",
"xs:anyAttribute" : "activegrid.model.schema.XsdAnyAttribute",
"xs:attribute" : "activegrid.model.schema.XsdAttribute",
"xs:choice" : "activegrid.model.schema.XsdChoice",
"xs:complexContent" : "activegrid.model.schema.XsdComplexContent",
"xs:complexType" : "activegrid.model.schema.XsdComplexType",
"xs:documentation" : "activegrid.model.schema.XsdDocumentation",
"xs:element" : "activegrid.model.schema.XsdElement",
"xs:enumeration" : "activegrid.model.schema.XsdFacetEnumeration",
"xs:extension" : "activegrid.model.schema.XsdExtension",
"xs:fractionDigits" : "activegrid.model.schema.XsdFacetFractionDigits",
"xs:field" : "activegrid.model.schema.XsdKeyField",
"xs:import" : "activegrid.model.schema.XsdInclude",
"xs:include" : "activegrid.model.schema.XsdInclude",
"xs:key" : "activegrid.model.schema.XsdKey",
"xs:keyref" : "activegrid.model.schema.XsdKeyRef",
"xs:length" : "activegrid.model.schema.XsdFacetLength",
"xs:list" : "activegrid.model.schema.XsdList",
"xs:maxExclusive" : "activegrid.model.schema.XsdFacetMaxExclusive",
"xs:maxInclusive" : "activegrid.model.schema.XsdFacetMaxInclusive",
"xs:maxLength" : "activegrid.model.schema.XsdFacetMaxLength",
"xs:minExclusive" : "activegrid.model.schema.XsdFacetMinExclusive",
"xs:minInclusive" : "activegrid.model.schema.XsdFacetMinInclusive",
"xs:minLength" : "activegrid.model.schema.XsdFacetMinLength",
"xs:pattern" : "activegrid.model.schema.XsdFacetPattern",
"xs:restriction" : "activegrid.model.schema.XsdRestriction",
"xs:schema" : "activegrid.model.schema.Schema",
"xs:selector" : "activegrid.model.schema.XsdKeySelector",
"xs:sequence" : "activegrid.model.schema.XsdSequence",
}
for keyName, className in AG_TYPE_MAPPING.iteritems():
try:
tmpAgKnownTypes[keyName] = objutils.classForName(className)
except KeyError:
print "Error mapping knownType", className
pass
if len(tmpAgKnownTypes) > 0:
agKnownTypes = tmpAgKnownTypes
return agKnownTypes
"xs:simpleContent" : "activegrid.model.schema.XsdSimpleContent",
"xs:simpleType" : "activegrid.model.schema.XsdSimpleType",
"xs:totalDigits" : "activegrid.model.schema.XsdFacetTotalDigits",
"xs:whiteSpace" : "activegrid.model.schema.XsdFacetWhiteSpace",
}
return agXsdToClassName
global agKnownTypes
agKnownTypes = None
def getAgKnownTypes():
global agKnownTypes
if agKnownTypes == None:
try:
tmpAgKnownTypes = {}
import activegrid.model.processmodel
import activegrid.model.schema
import activegrid.server.deployment
import activegrid.model.wsdl
ifDefPy()
import activegrid.data.dataservice
endIfDef()
for keyName, className in getAgXsdToClassName().iteritems():
classType = objutils.classForName(className)
if (classType == None):
raise Exception("Cannot get class type for %s" % className)
else:
tmpAgKnownTypes[keyName] = classType
if len(tmpAgKnownTypes) > 0:
agKnownTypes = tmpAgKnownTypes
except ImportError:
agKnownTypes = {}
if len(agKnownTypes) == 0: # standalone IDE and XmlMarshaller don't contain known AG types
noKnownNamespaces = {}
return agKnownTypes, noKnownNamespaces
return agKnownTypes, KNOWN_NAMESPACES