add python3 suppport based on 2to3 script
This commit is contained in:
parent
caef0e85d0
commit
4f91a30fec
68 changed files with 597 additions and 576 deletions
|
@ -5,9 +5,9 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
import types, copy
|
||||
import appy.gen as gen
|
||||
import po
|
||||
from model import ModelClass
|
||||
from utils import produceNiceMessage, getClassName
|
||||
from . import po
|
||||
from .model import ModelClass
|
||||
from .utils import produceNiceMessage, getClassName
|
||||
TABS = 4 # Number of blanks in a Python indentation.
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -130,7 +130,7 @@ class ClassDescriptor(Descriptor):
|
|||
def isAbstract(self):
|
||||
'''Is self.klass abstract?'''
|
||||
res = False
|
||||
if self.klass.__dict__.has_key('abstract'):
|
||||
if 'abstract' in self.klass.__dict__:
|
||||
res = self.klass.__dict__['abstract']
|
||||
return res
|
||||
|
||||
|
@ -139,7 +139,7 @@ class ClassDescriptor(Descriptor):
|
|||
concept into the application. For example, creating instances
|
||||
of such classes will be easy from the user interface.'''
|
||||
res = False
|
||||
if self.klass.__dict__.has_key('root'):
|
||||
if 'root' in self.klass.__dict__:
|
||||
res = self.klass.__dict__['root']
|
||||
return res
|
||||
|
||||
|
@ -150,7 +150,7 @@ class ClassDescriptor(Descriptor):
|
|||
theClass = self.klass
|
||||
if klass:
|
||||
theClass = klass
|
||||
if theClass.__dict__.has_key('folder'):
|
||||
if 'folder' in theClass.__dict__:
|
||||
res = theClass.__dict__['folder']
|
||||
else:
|
||||
if theClass.__bases__:
|
||||
|
@ -176,14 +176,14 @@ class ClassDescriptor(Descriptor):
|
|||
def getCreateMean(self, type='Import'):
|
||||
'''Returns the mean for this class that corresponds to p_type, or
|
||||
None if the class does not support this create mean.'''
|
||||
if not self.klass.__dict__.has_key('create'): return
|
||||
if 'create' not in self.klass.__dict__: return
|
||||
else:
|
||||
means = self.klass.create
|
||||
if not means: return
|
||||
if not isinstance(means, tuple) and not isinstance(means, list):
|
||||
means = [means]
|
||||
for mean in means:
|
||||
exec 'found = isinstance(mean, %s)' % type
|
||||
exec('found = isinstance(mean, %s)' % type)
|
||||
if found: return mean
|
||||
|
||||
@staticmethod
|
||||
|
@ -192,7 +192,7 @@ class ClassDescriptor(Descriptor):
|
|||
p_tool is given, we are at execution time (not a generation time),
|
||||
and we may potentially execute search.show methods that allow to
|
||||
conditionnaly include a search or not.'''
|
||||
if klass.__dict__.has_key('search'):
|
||||
if 'search' in klass.__dict__:
|
||||
searches = klass.__dict__['search']
|
||||
if not tool: return searches
|
||||
# Evaluate attributes "show" for every search.
|
||||
|
@ -229,10 +229,10 @@ class ClassDescriptor(Descriptor):
|
|||
|
||||
def addField(self, fieldName, fieldType):
|
||||
'''Adds a new field to the Tool.'''
|
||||
exec "self.modelClass.%s = fieldType" % fieldName
|
||||
exec("self.modelClass.%s = fieldType" % fieldName)
|
||||
if fieldName in self.modelClass._appy_attributes:
|
||||
print('Warning, field "%s" is already existing on class "%s"' % \
|
||||
(fieldName, self.modelClass.__name__))
|
||||
print(('Warning, field "%s" is already existing on class "%s"' % \
|
||||
(fieldName, self.modelClass.__name__)))
|
||||
return
|
||||
self.modelClass._appy_attributes.append(fieldName)
|
||||
self.orderedAttributes.append(fieldName)
|
||||
|
@ -488,9 +488,9 @@ class TranslationClassDescriptor(ClassDescriptor):
|
|||
maxLine = 100 # We suppose a line is 100 characters long.
|
||||
width = 0
|
||||
height = 0
|
||||
for fileName, poFile in i18nFiles.iteritems():
|
||||
for fileName, poFile in i18nFiles.items():
|
||||
if not fileName.startswith('%s-' % appName) or \
|
||||
not i18nFiles[fileName].messagesDict.has_key(messageId):
|
||||
messageId not in i18nFiles[fileName].messagesDict:
|
||||
# In this case this is not one of our Appy-managed translation
|
||||
# files.
|
||||
continue
|
||||
|
|
|
@ -3,10 +3,11 @@ import os, os.path, re, sys, parser, symbol, token, types
|
|||
import appy, appy.pod.renderer
|
||||
from appy.shared.utils import FolderDeleter
|
||||
import appy.gen as gen
|
||||
import po
|
||||
from descriptors import *
|
||||
from utils import getClassName
|
||||
from model import ModelClass, User, Group, Tool, Translation, Page
|
||||
from . import po
|
||||
from .descriptors import *
|
||||
from .utils import getClassName
|
||||
from .model import ModelClass, User, Group, Tool, Translation, Page
|
||||
import collections
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
class GeneratorError(Exception): pass
|
||||
|
@ -160,7 +161,7 @@ class Generator:
|
|||
appy.fields.Field, it will be considered a gen-class. If p_klass
|
||||
declares at least one static attribute that is a appy.gen.State,
|
||||
it will be considered a gen-workflow.'''
|
||||
for attr in klass.__dict__.itervalues():
|
||||
for attr in klass.__dict__.values():
|
||||
if isinstance(attr, gen.Field): return 'class'
|
||||
elif isinstance(attr, gen.State): return 'workflow'
|
||||
|
||||
|
@ -173,11 +174,11 @@ class Generator:
|
|||
self.totalNumberOfTests += 1
|
||||
res = True
|
||||
# Count also docstring in methods
|
||||
if type(moduleOrClass) == types.ClassType:
|
||||
for name, elem in moduleOrClass.__dict__.iteritems():
|
||||
if type(moduleOrClass) == type:
|
||||
for name, elem in moduleOrClass.__dict__.items():
|
||||
if type(elem) in (staticmethod, classmethod):
|
||||
elem = elem.__get__(name)
|
||||
if callable(elem) and (type(elem) != types.ClassType) and \
|
||||
if isinstance(elem, collections.Callable) and (type(elem) != type) and \
|
||||
hasattr(elem, '__doc__') and elem.__doc__ and \
|
||||
(elem.__doc__.find('>>>') != -1):
|
||||
res = True
|
||||
|
@ -198,8 +199,8 @@ class Generator:
|
|||
self.modulesWithTests.add(module.__name__)
|
||||
classType = type(Generator)
|
||||
# Find all classes in this module
|
||||
for name in module.__dict__.keys():
|
||||
exec 'moduleElem = module.%s' % name
|
||||
for name in list(module.__dict__.keys()):
|
||||
exec('moduleElem = module.%s' % name)
|
||||
# Ignore non-classes module elements or classes that were imported
|
||||
# from other modules.
|
||||
if (type(moduleElem) != classType) or \
|
||||
|
@ -213,7 +214,7 @@ class Generator:
|
|||
# Collect non-parsable attrs = back references added
|
||||
# programmatically
|
||||
moreAttrs = []
|
||||
for eName, eValue in moduleElem.__dict__.iteritems():
|
||||
for eName, eValue in moduleElem.__dict__.items():
|
||||
if isinstance(eValue, gen.Field) and (eName not in attrs):
|
||||
moreAttrs.append(eName)
|
||||
# Sort them in alphabetical order: else, order would be random
|
||||
|
@ -257,7 +258,7 @@ class Generator:
|
|||
# What is the name of the application ?
|
||||
appName = os.path.basename(self.application)
|
||||
# Get the app-specific config if any
|
||||
exec 'import %s as appModule' % appName
|
||||
exec('import %s as appModule' % appName)
|
||||
if hasattr (appModule, 'Config'):
|
||||
self.config = appModule.Config
|
||||
if not issubclass(self.config, gen.Config):
|
||||
|
@ -273,7 +274,7 @@ class Generator:
|
|||
# Ignore non Python files
|
||||
if not fileName.endswith('.py'): continue
|
||||
moduleName = '%s.%s' % (appName, os.path.splitext(fileName)[0])
|
||||
exec 'import %s' % moduleName
|
||||
exec('import %s' % moduleName)
|
||||
modules.append(eval(moduleName))
|
||||
# Parse imported modules
|
||||
for module in modules:
|
||||
|
@ -321,7 +322,7 @@ class Generator:
|
|||
fileContent = f.read()
|
||||
f.close()
|
||||
if not fileName.endswith('.png'):
|
||||
for rKey, rValue in replacements.iteritems():
|
||||
for rKey, rValue in replacements.items():
|
||||
fileContent = fileContent.replace(
|
||||
'<!%s!>' % rKey, str(rValue))
|
||||
f = file(resultPath, 'w')
|
||||
|
@ -343,7 +344,7 @@ class Generator:
|
|||
msg = ''
|
||||
if self.totalNumberOfTests:
|
||||
msg = ' (number of tests found: %d)' % self.totalNumberOfTests
|
||||
print('Done%s.' % msg)
|
||||
print(('Done%s.' % msg))
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
class ZopeGenerator(Generator):
|
||||
|
@ -413,7 +414,7 @@ class ZopeGenerator(Generator):
|
|||
f.close()
|
||||
# Generate i18n pot file
|
||||
potFileName = '%s.pot' % self.applicationName
|
||||
if self.i18nFiles.has_key(potFileName):
|
||||
if potFileName in self.i18nFiles:
|
||||
potFile = self.i18nFiles[potFileName]
|
||||
else:
|
||||
fullName = os.path.join(self.application, 'tr', potFileName)
|
||||
|
@ -427,14 +428,14 @@ class ZopeGenerator(Generator):
|
|||
self.options.i18nClean, keepExistingOrder=False)
|
||||
potFile.generate()
|
||||
if removedLabels:
|
||||
print('Warning: %d messages were removed from translation ' \
|
||||
'files: %s' % (len(removedLabels), str(removedLabels)))
|
||||
print(('Warning: %d messages were removed from translation ' \
|
||||
'files: %s' % (len(removedLabels), str(removedLabels))))
|
||||
# Generate i18n po files
|
||||
for language in self.config.languages:
|
||||
# I must generate (or update) a po file for the language(s)
|
||||
# specified in the configuration.
|
||||
poFileName = potFile.getPoFileName(language)
|
||||
if self.i18nFiles.has_key(poFileName):
|
||||
if poFileName in self.i18nFiles:
|
||||
poFile = self.i18nFiles[poFileName]
|
||||
else:
|
||||
fullName = os.path.join(self.application, 'tr', poFileName)
|
||||
|
@ -501,7 +502,7 @@ class ZopeGenerator(Generator):
|
|||
for role in creators:
|
||||
if role.name not in allRoles:
|
||||
allRoles[role.name] = role
|
||||
res = allRoles.values()
|
||||
res = list(allRoles.values())
|
||||
# Filter the result according to parameters
|
||||
for p in ('appy', 'local', 'grantable'):
|
||||
if eval(p) != None:
|
||||
|
@ -621,12 +622,12 @@ class ZopeGenerator(Generator):
|
|||
else:
|
||||
# If a child of this class is already present, we must insert
|
||||
# this klass before it.
|
||||
lowestChildIndex = sys.maxint
|
||||
lowestChildIndex = sys.maxsize
|
||||
for resClass in resClasses:
|
||||
if klass in resClass.__bases__:
|
||||
lowestChildIndex = min(lowestChildIndex,
|
||||
resClasses.index(resClass))
|
||||
if lowestChildIndex != sys.maxint:
|
||||
if lowestChildIndex != sys.maxsize:
|
||||
res.insert(lowestChildIndex, classDescr)
|
||||
resClasses.insert(lowestChildIndex, klass)
|
||||
else:
|
||||
|
@ -745,7 +746,7 @@ class ZopeGenerator(Generator):
|
|||
'''Is called each time an Appy class is found in the application, for
|
||||
generating the corresponding Archetype class.'''
|
||||
k = classDescr.klass
|
||||
print('Generating %s.%s (gen-class)...' % (k.__module__, k.__name__))
|
||||
print(('Generating %s.%s (gen-class)...' % (k.__module__, k.__name__)))
|
||||
# Determine base Zope class
|
||||
isFolder = classDescr.isFolder()
|
||||
baseClass = isFolder and 'Folder' or 'SimpleItem'
|
||||
|
@ -772,7 +773,7 @@ class ZopeGenerator(Generator):
|
|||
'''This method creates the i18n labels related to the workflow described
|
||||
by p_wfDescr.'''
|
||||
k = wfDescr.klass
|
||||
print('Generating %s.%s (gen-workflow)...' % (k.__module__, k.__name__))
|
||||
print(('Generating %s.%s (gen-workflow)...' % (k.__module__, k.__name__)))
|
||||
# Identify workflow name
|
||||
wfName = WorkflowDescriptor.getWorkflowName(wfDescr.klass)
|
||||
# Add i18n messages for states
|
||||
|
|
|
@ -33,7 +33,7 @@ def updateIndexes(installer, indexInfo):
|
|||
'''This function updates the indexes defined in the catalog.'''
|
||||
catalog = installer.app.catalog
|
||||
logger = installer.logger
|
||||
for indexName, indexType in indexInfo.iteritems():
|
||||
for indexName, indexType in indexInfo.items():
|
||||
indexRealType = indexType
|
||||
if indexType in ('XhtmlIndex', 'TextIndex', 'ListIndex'):
|
||||
indexRealType = 'ZCTextIndex'
|
||||
|
|
|
@ -43,7 +43,7 @@ class FakeZCatalog:
|
|||
def onDelSession(sessionObject, container):
|
||||
'''This function is called when a session expires.'''
|
||||
rq = container.REQUEST
|
||||
if rq.cookies.has_key('_appy_') and rq.cookies.has_key('_ZopeId') and \
|
||||
if '_appy_' in rq.cookies and '_ZopeId' in rq.cookies and \
|
||||
(rq['_ZopeId'] == sessionObject.token):
|
||||
# The request comes from a guy whose session has expired.
|
||||
resp = rq.RESPONSE
|
||||
|
@ -155,7 +155,7 @@ class ZopeInstaller:
|
|||
# Create or update Appy-wide indexes and field-related indexes
|
||||
indexInfo = defaultIndexes.copy()
|
||||
tool = self.app.config
|
||||
for className in self.config.attributes.iterkeys():
|
||||
for className in self.config.attributes.keys():
|
||||
wrapperClass = tool.getAppyClass(className, wrapper=True)
|
||||
indexInfo.update(wrapperClass.getIndexes(includeDefaults=False))
|
||||
updateIndexes(self, indexInfo)
|
||||
|
@ -196,7 +196,7 @@ class ZopeInstaller:
|
|||
if hasattr(appyTool, 'beforeInstall'): appyTool.beforeInstall()
|
||||
|
||||
# Create the default users if they do not exist.
|
||||
for login, roles in self.defaultUsers.iteritems():
|
||||
for login, roles in self.defaultUsers.items():
|
||||
if not appyTool.count('User', noSecurity=True, login=login):
|
||||
appyTool.create('users', noSecurity=True, id=login, login=login,
|
||||
password3=login, password4=login,
|
||||
|
@ -277,7 +277,7 @@ class ZopeInstaller:
|
|||
name = klass.__name__
|
||||
module = klass.__module__
|
||||
wrapper = klass.wrapperClass
|
||||
exec 'from %s import manage_add%s as ctor' % (module, name)
|
||||
exec('from %s import manage_add%s as ctor' % (module, name))
|
||||
self.zopeContext.registerClass(meta_type=name,
|
||||
constructors = (ctor,), permission = None)
|
||||
# Create workflow prototypical instances in __instance__ attributes
|
||||
|
@ -316,7 +316,7 @@ class ZopeInstaller:
|
|||
# Post-initialise every Appy type
|
||||
for baseClass in klass.wrapperClass.__bases__:
|
||||
if baseClass.__name__ == 'AbstractWrapper': continue
|
||||
for name, appyType in baseClass.__dict__.iteritems():
|
||||
for name, appyType in baseClass.__dict__.items():
|
||||
if not isinstance(appyType, gen.Field) or \
|
||||
(isinstance(appyType, gen.Ref) and appyType.isBack):
|
||||
continue # Back refs are initialised within fw refs
|
||||
|
|
|
@ -39,9 +39,9 @@
|
|||
|
||||
# ------------------------------------------------------------------------------
|
||||
rowDelimiters = {'-':'middle', '=':'top', '_':'bottom'}
|
||||
rowDelms = ''.join(rowDelimiters.keys())
|
||||
rowDelms = ''.join(list(rowDelimiters.keys()))
|
||||
cellDelimiters = {'|': 'center', ';': 'left', '!': 'right'}
|
||||
cellDelms = ''.join(cellDelimiters.keys())
|
||||
cellDelms = ''.join(list(cellDelimiters.keys()))
|
||||
|
||||
pxDict = {
|
||||
# Page-related elements
|
||||
|
@ -138,7 +138,7 @@ class Table:
|
|||
# Initialise simple params, either from the true params, either from
|
||||
# the p_other Table instance.
|
||||
for param in Table.simpleParams:
|
||||
exec 'self.%s = %s%s' % (param, source, param)
|
||||
exec('self.%s = %s%s' % (param, source, param))
|
||||
# The following attribute will store a special Row instance used for
|
||||
# defining column properties.
|
||||
self.headerRow = None
|
||||
|
|
|
@ -120,10 +120,10 @@ def sendMail(config, to, subject, body, attachments=None, log=None):
|
|||
if res and log:
|
||||
log('could not send mail to some recipients. %s' % str(res),
|
||||
type='warning')
|
||||
except smtplib.SMTPException, e:
|
||||
except smtplib.SMTPException as e:
|
||||
if log:
|
||||
log('%s: mail sending failed (%s)' % (config, str(e)), type='error')
|
||||
except socket.error, se:
|
||||
except socket.error as se:
|
||||
if log:
|
||||
log('%s: mail sending failed (%s)' % (config, str(se)),type='error')
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -38,10 +38,10 @@ class Migrator:
|
|||
if frozen.data.__class__.__name__ == 'Pdata':
|
||||
# The file content is splitted in several chunks.
|
||||
f.write(frozen.data.data)
|
||||
nextPart = frozen.data.next
|
||||
nextPart = frozen.data.__next__
|
||||
while nextPart:
|
||||
f.write(nextPart.data)
|
||||
nextPart = nextPart.next
|
||||
nextPart = nextPart.__next__
|
||||
else:
|
||||
# Only one chunk
|
||||
f.write(frozen.data)
|
||||
|
|
|
@ -13,18 +13,18 @@ class TestMixin:
|
|||
'''Returns the list of sub-modules of p_app that are non-empty.'''
|
||||
res = []
|
||||
try:
|
||||
exec 'import %s' % moduleName
|
||||
exec 'moduleObj = %s' % moduleName
|
||||
exec('import %s' % moduleName)
|
||||
exec('moduleObj = %s' % moduleName)
|
||||
moduleFile = moduleObj.__file__
|
||||
if moduleFile.endswith('.pyc'):
|
||||
moduleFile = moduleFile[:-1]
|
||||
except ImportError, ie:
|
||||
except ImportError as ie:
|
||||
return res
|
||||
except SyntaxError, se:
|
||||
except SyntaxError as se:
|
||||
return res
|
||||
# Include the module if not empty. "Emptyness" is determined by the
|
||||
# absence of names beginning with other chars than "__".
|
||||
for elem in moduleObj.__dict__.iterkeys():
|
||||
for elem in moduleObj.__dict__.keys():
|
||||
if not elem.startswith('__'):
|
||||
res.append(moduleObj)
|
||||
break
|
||||
|
@ -66,10 +66,10 @@ def afterTest(test):
|
|||
'''Is executed after every test.'''
|
||||
g = test.globs
|
||||
appName = g['tool'].o.getAppName()
|
||||
exec 'from Products.%s import cov, covFolder, totalNumberOfTests, ' \
|
||||
'countTest' % appName
|
||||
exec('from Products.%s import cov, covFolder, totalNumberOfTests, ' \
|
||||
'countTest' % appName)
|
||||
countTest()
|
||||
exec 'from Products.%s import numberOfExecutedTests' % appName
|
||||
exec('from Products.%s import numberOfExecutedTests' % appName)
|
||||
if cov and (numberOfExecutedTests == totalNumberOfTests):
|
||||
cov.stop()
|
||||
appModules = test.getNonEmptySubModules(appName)
|
||||
|
|
|
@ -13,6 +13,7 @@ from appy.shared import mimeTypes
|
|||
from appy.shared import utils as sutils
|
||||
from appy.shared.data import languages
|
||||
from appy.shared.ldap_connector import LdapConnector
|
||||
import collections
|
||||
try:
|
||||
from AccessControl.ZopeSecurityPolicy import _noroles
|
||||
except ImportError:
|
||||
|
@ -36,7 +37,7 @@ class ToolMixin(BaseMixin):
|
|||
p_metaTypeOrAppyType.'''
|
||||
appName = self.getProductConfig().PROJECTNAME
|
||||
res = metaTypeOrAppyClass
|
||||
if not isinstance(metaTypeOrAppyClass, basestring):
|
||||
if not isinstance(metaTypeOrAppyClass, str):
|
||||
res = gutils.getClassName(metaTypeOrAppyClass, appName)
|
||||
if res.find('_wrappers') != -1:
|
||||
elems = res.split('_')
|
||||
|
@ -439,7 +440,7 @@ class ToolMixin(BaseMixin):
|
|||
|
||||
def quote(self, s, escapeWithEntity=True):
|
||||
'''Returns the quoted version of p_s.'''
|
||||
if not isinstance(s, basestring): s = str(s)
|
||||
if not isinstance(s, str): s = str(s)
|
||||
repl = escapeWithEntity and ''' or "\\'"
|
||||
s = s.replace('\r\n', '').replace('\n', '').replace("'", repl)
|
||||
return "'%s'" % s
|
||||
|
@ -452,7 +453,7 @@ class ToolMixin(BaseMixin):
|
|||
|
||||
def getZopeClass(self, name):
|
||||
'''Returns the Zope class whose name is p_name.'''
|
||||
exec 'from Products.%s.%s import %s as C'% (self.getAppName(),name,name)
|
||||
exec('from Products.%s.%s import %s as C'% (self.getAppName(),name,name))
|
||||
return C
|
||||
|
||||
def getAppyClass(self, zopeName, wrapper=False):
|
||||
|
@ -476,12 +477,12 @@ class ToolMixin(BaseMixin):
|
|||
'''Gets the different ways objects of p_klass can be created (currently:
|
||||
via a web form or programmatically only). Result is a list.'''
|
||||
res = []
|
||||
if not klass.__dict__.has_key('create'):
|
||||
if 'create' not in klass.__dict__:
|
||||
return ['form']
|
||||
else:
|
||||
means = klass.create
|
||||
if means:
|
||||
if isinstance(means, basestring): res = [means]
|
||||
if isinstance(means, str): res = [means]
|
||||
else: res = means
|
||||
return res
|
||||
|
||||
|
@ -511,7 +512,7 @@ class ToolMixin(BaseMixin):
|
|||
else:
|
||||
creators = self.getProductConfig().appConfig.defaultCreators
|
||||
# Resolve case (3): if "creators" is a method, execute it.
|
||||
if callable(creators): creators = creators(self.appy())
|
||||
if isinstance(creators, collections.Callable): creators = creators(self.appy())
|
||||
# Resolve case (2)
|
||||
if isinstance(creators, bool) or not creators: return creators
|
||||
# Resolve case (1): checks whether the user has at least one of the
|
||||
|
@ -595,7 +596,7 @@ class ToolMixin(BaseMixin):
|
|||
rq = self.REQUEST
|
||||
# Store the search criteria in the session
|
||||
criteria = self._getDefaultSearchCriteria()
|
||||
for name in rq.form.keys():
|
||||
for name in list(rq.form.keys()):
|
||||
if name.startswith('w_') and not self._searchValueIsEmpty(name):
|
||||
hasStar = name.find('*') != -1
|
||||
fieldName = not hasStar and name[2:] or name[2:name.find('*')]
|
||||
|
@ -609,17 +610,17 @@ class ToolMixin(BaseMixin):
|
|||
# The type of the value is encoded after char "*".
|
||||
name, type = name.split('*')
|
||||
if type == 'bool':
|
||||
exec 'value = %s' % value
|
||||
exec('value = %s' % value)
|
||||
elif type in ('int', 'float'):
|
||||
# Get the "from" value
|
||||
if not value: value = None
|
||||
else:
|
||||
exec 'value = %s(value)' % type
|
||||
exec('value = %s(value)' % type)
|
||||
# Get the "to" value
|
||||
toValue = rq.form['%s_to' % name[2:]].strip()
|
||||
if not toValue: toValue = None
|
||||
else:
|
||||
exec 'toValue = %s(toValue)' % type
|
||||
exec('toValue = %s(toValue)' % type)
|
||||
value = (value, toValue)
|
||||
elif type == 'date':
|
||||
prefix = name[2:]
|
||||
|
@ -640,8 +641,8 @@ class ToolMixin(BaseMixin):
|
|||
if len(type) > 6:
|
||||
transform = type.split('-')[1]
|
||||
if (transform != 'none') and value:
|
||||
exec 'value = value.%s()' % \
|
||||
self.transformMethods[transform]
|
||||
exec('value = value.%s()' % \
|
||||
self.transformMethods[transform])
|
||||
if isinstance(value, list):
|
||||
# It is a list of values. Check if we have an operator for
|
||||
# the field, to see if we make an "and" or "or" for all
|
||||
|
@ -697,7 +698,7 @@ class ToolMixin(BaseMixin):
|
|||
it among search criteria in the session.'''
|
||||
if not refInfo and (self.REQUEST.get('search', None) == 'customSearch'):
|
||||
criteria = self.REQUEST.SESSION.get('searchCriteria', None)
|
||||
if criteria and criteria.has_key('_ref'): refInfo = criteria['_ref']
|
||||
if criteria and '_ref' in criteria: refInfo = criteria['_ref']
|
||||
if not refInfo: return None, None
|
||||
objectUid, fieldName = refInfo.split(':')
|
||||
obj = self.getObject(objectUid)
|
||||
|
@ -856,7 +857,7 @@ class ToolMixin(BaseMixin):
|
|||
try:
|
||||
creds = creds.split(' ')[-1]
|
||||
login, password = base64.decodestring(creds).split(':', 1)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
pass
|
||||
# b. Identify the user from the authentication cookie.
|
||||
if not login:
|
||||
|
@ -968,7 +969,7 @@ class ToolMixin(BaseMixin):
|
|||
# Invalidate the user session.
|
||||
try:
|
||||
sdm = self.session_data_manager
|
||||
except AttributeError, ae:
|
||||
except AttributeError as ae:
|
||||
# When ran in test mode, session_data_manager is not there.
|
||||
sdm = None
|
||||
if sdm:
|
||||
|
@ -977,7 +978,7 @@ class ToolMixin(BaseMixin):
|
|||
session.invalidate()
|
||||
self.log('logged out.')
|
||||
# Remove user from variable "loggedUsers"
|
||||
if self.loggedUsers.has_key(userId): del self.loggedUsers[userId]
|
||||
if userId in self.loggedUsers: del self.loggedUsers[userId]
|
||||
return self.goto(self.getApp().absolute_url())
|
||||
|
||||
# This dict stores, for every logged user, the date/time of its last access
|
||||
|
@ -1247,7 +1248,7 @@ class ToolMixin(BaseMixin):
|
|||
if hasattr(klass, 'popup'):
|
||||
res.target = 'appyIFrame'
|
||||
d = klass.popup
|
||||
if isinstance(d, basestring):
|
||||
if isinstance(d, str):
|
||||
# Width only
|
||||
params = d[:-2]
|
||||
else:
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
- mixins/ToolMixin is mixed in with the generated application Tool class.'''
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
import os, os.path, re, sys, types, urllib, cgi
|
||||
import os, os.path, re, sys, types, urllib.request, urllib.parse, urllib.error, cgi
|
||||
from appy import Object
|
||||
from appy.px import Px
|
||||
from appy.fields.workflow import UiTransition
|
||||
|
@ -15,6 +15,7 @@ from appy.shared import utils as sutils
|
|||
from appy.shared.data import rtlLanguages
|
||||
from appy.shared.xml_parser import XmlMarshaller, XmlUnmarshaller
|
||||
from appy.shared.diff import HtmlDiff
|
||||
import collections
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
NUMBERED_ID = re.compile('.+\d{4}$')
|
||||
|
@ -371,9 +372,9 @@ class BaseMixin:
|
|||
# p_errors object. Within this object, for every error message that is
|
||||
# not a string, we replace it with the standard validation error for the
|
||||
# corresponding field.
|
||||
for key, value in errors.__dict__.iteritems():
|
||||
for key, value in errors.__dict__.items():
|
||||
resValue = value
|
||||
if not isinstance(resValue, basestring):
|
||||
if not isinstance(resValue, str):
|
||||
resValue = self.translate('field_invalid')
|
||||
setattr(errors, key, resValue)
|
||||
return msg
|
||||
|
@ -419,7 +420,7 @@ class BaseMixin:
|
|||
# Trigger field-specific validation
|
||||
self.intraFieldValidation(errors, values)
|
||||
if errors.__dict__:
|
||||
for k,v in errors.__dict__.iteritems(): rq.set('%s_error' % k, v)
|
||||
for k,v in errors.__dict__.items(): rq.set('%s_error' % k, v)
|
||||
self.say(errorMessage)
|
||||
return self.gotoEdit()
|
||||
|
||||
|
@ -427,7 +428,7 @@ class BaseMixin:
|
|||
msg = self.interFieldValidation(errors, values)
|
||||
if not msg: msg = errorMessage
|
||||
if errors.__dict__:
|
||||
for k,v in errors.__dict__.iteritems(): rq.set('%s_error' % k, v)
|
||||
for k,v in errors.__dict__.items(): rq.set('%s_error' % k, v)
|
||||
self.say(msg)
|
||||
return self.gotoEdit()
|
||||
|
||||
|
@ -506,7 +507,7 @@ class BaseMixin:
|
|||
# Get the list of indexes that apply on this object. Else, Zope
|
||||
# will reindex all indexes defined in the catalog, and through
|
||||
# acquisition, wrong methods can be called on wrong objects.
|
||||
iNames = self.wrapperClass.getIndexes().keys()
|
||||
iNames = list(self.wrapperClass.getIndexes().keys())
|
||||
catalog.catalog_object(self, path, idxs=iNames)
|
||||
|
||||
def xml(self, action=None):
|
||||
|
@ -529,14 +530,14 @@ class BaseMixin:
|
|||
elif isinstance(methodRes, file):
|
||||
res = methodRes.read()
|
||||
methodRes.close()
|
||||
elif isinstance(methodRes, basestring) and \
|
||||
elif isinstance(methodRes, str) and \
|
||||
methodRes.startswith('<?xml'): # Already XML
|
||||
return methodRes
|
||||
else:
|
||||
marshaller = XmlMarshaller()
|
||||
oType = isinstance(methodRes, Object) and 'popo' or 'appy'
|
||||
res = marshaller.marshall(methodRes, objectType=oType)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
tb = sutils.Traceback.get()
|
||||
res = XmlMarshaller(rootTag='exception').marshall(tb)
|
||||
self.log(tb, type='error')
|
||||
|
@ -548,7 +549,7 @@ class BaseMixin:
|
|||
'''Prints a p_msg in the user interface. p_logLevel may be "info",
|
||||
"warning" or "error".'''
|
||||
rq = self.REQUEST
|
||||
if 'messages' not in rq.SESSION.keys():
|
||||
if 'messages' not in list(rq.SESSION.keys()):
|
||||
plist = self.getProductConfig().PersistentList
|
||||
messages = rq.SESSION['messages'] = plist()
|
||||
else:
|
||||
|
@ -619,7 +620,7 @@ class BaseMixin:
|
|||
For a multilingual string field, p_changes can contain a key for
|
||||
every language, of the form <field name>-<language>.'''
|
||||
# Add to the p_changes dict the field labels
|
||||
for name in changes.keys():
|
||||
for name in list(changes.keys()):
|
||||
# "name" can contain the language for multilingual fields.
|
||||
if '-' in name:
|
||||
fieldName, lg = name.split('-')
|
||||
|
@ -646,7 +647,7 @@ class BaseMixin:
|
|||
historized fields, while p_self already contains the (potentially)
|
||||
modified values.'''
|
||||
# Remove from previousData all values that were not changed
|
||||
for name in previousData.keys():
|
||||
for name in list(previousData.keys()):
|
||||
field = self.getAppyType(name)
|
||||
prev = previousData[name]
|
||||
curr = field.getValue(self)
|
||||
|
@ -655,7 +656,7 @@ class BaseMixin:
|
|||
((prev == '') and (curr == None)):
|
||||
del previousData[name]
|
||||
continue
|
||||
except UnicodeDecodeError, ude:
|
||||
except UnicodeDecodeError as ude:
|
||||
# The string comparisons above may imply silent encoding-related
|
||||
# conversions that may produce this exception.
|
||||
continue
|
||||
|
@ -743,15 +744,15 @@ class BaseMixin:
|
|||
else:
|
||||
klass = self.appy().klass
|
||||
moduleName = klass.__module__
|
||||
exec 'import %s' % moduleName
|
||||
exec 'reload(%s)' % moduleName
|
||||
exec 'res = %s.%s' % (moduleName, klass.__name__)
|
||||
exec('import %s' % moduleName)
|
||||
exec('reload(%s)' % moduleName)
|
||||
exec('res = %s.%s' % (moduleName, klass.__name__))
|
||||
# More manipulations may have occurred in m_update
|
||||
if hasattr(res, 'update'):
|
||||
parentName= res.__bases__[-1].__name__
|
||||
moduleName= 'Products.%s.wrappers' % self.getTool().getAppName()
|
||||
exec 'import %s' % moduleName
|
||||
exec 'parent = %s.%s' % (moduleName, parentName)
|
||||
exec('import %s' % moduleName)
|
||||
exec('parent = %s.%s' % (moduleName, parentName))
|
||||
res.update(parent)
|
||||
return res
|
||||
|
||||
|
@ -839,15 +840,15 @@ class BaseMixin:
|
|||
req = self.REQUEST
|
||||
for field in self.getAllAppyTypes():
|
||||
if field.page.name != pageName: continue
|
||||
if field.masterValue and callable(field.masterValue):
|
||||
if field.masterValue and isinstance(field.masterValue, collections.Callable):
|
||||
# We have a slave field that is updated via ajax requests.
|
||||
name = field.name
|
||||
# Remember the request value for this field if present.
|
||||
if req.has_key(name) and req[name]:
|
||||
if name in req and req[name]:
|
||||
requestValues[name] = req[name]
|
||||
# Remember the validation error for this field if present.
|
||||
errorKey = '%s_error' % name
|
||||
if req.has_key(errorKey):
|
||||
if errorKey in req:
|
||||
errors[name] = req[errorKey]
|
||||
return sutils.getStringDict(requestValues), sutils.getStringDict(errors)
|
||||
|
||||
|
@ -899,7 +900,7 @@ class BaseMixin:
|
|||
del phases[res[i].name]
|
||||
del res[i]
|
||||
# Compute next/previous phases of every phase
|
||||
for ph in phases.itervalues():
|
||||
for ph in phases.values():
|
||||
ph.computeNextPrevious(res)
|
||||
ph.totalNbOfPhases = len(res)
|
||||
# Restrict the result to the current phase if required
|
||||
|
@ -1208,7 +1209,7 @@ class BaseMixin:
|
|||
# fields' old values by their formatted counterparts.
|
||||
event = history[i].copy()
|
||||
event['changes'] = {}
|
||||
for name, oldValue in history[i]['changes'].iteritems():
|
||||
for name, oldValue in history[i]['changes'].items():
|
||||
# "name" can specify a language-specific part in a
|
||||
# multilingual field. "oldValue" is a tuple
|
||||
# (value, fieldName).
|
||||
|
@ -1455,7 +1456,7 @@ class BaseMixin:
|
|||
# Add users or groups having, locally, this role on this object.
|
||||
localRoles = getattr(self.aq_base, '__ac_local_roles__', None)
|
||||
if not localRoles: return res
|
||||
for id, roles in localRoles.iteritems():
|
||||
for id, roles in localRoles.items():
|
||||
for role in roles:
|
||||
if role in res:
|
||||
usr = 'user:%s' % id
|
||||
|
@ -1465,7 +1466,7 @@ class BaseMixin:
|
|||
def showState(self):
|
||||
'''Must I show self's current state ?'''
|
||||
stateShow = self.State(name=False).show
|
||||
if callable(stateShow):
|
||||
if isinstance(stateShow, collections.Callable):
|
||||
return stateShow(self.getWorkflow(), self.appy())
|
||||
return stateShow
|
||||
|
||||
|
@ -1479,7 +1480,7 @@ class BaseMixin:
|
|||
if not hasattr(klass, 'showTransitions'): return (layoutType=='view')
|
||||
showValue = klass.showTransitions
|
||||
# This value can be a single value or a tuple/list of values.
|
||||
if isinstance(showValue, basestring): return layoutType == showValue
|
||||
if isinstance(showValue, str): return layoutType == showValue
|
||||
return layoutType in showValue
|
||||
|
||||
getUrlDefaults = {'page':True, 'nav':True}
|
||||
|
@ -1524,8 +1525,8 @@ class BaseMixin:
|
|||
if 'nav' not in kwargs: kwargs['nav'] = True
|
||||
# Create URL parameters from kwargs
|
||||
params = []
|
||||
for name, value in kwargs.iteritems():
|
||||
if isinstance(value, basestring):
|
||||
for name, value in kwargs.items():
|
||||
if isinstance(value, str):
|
||||
params.append('%s=%s' % (name, value))
|
||||
elif self.REQUEST.get(name, ''):
|
||||
params.append('%s=%s' % (name, self.REQUEST[name]))
|
||||
|
@ -1601,7 +1602,7 @@ class BaseMixin:
|
|||
# Find the name of the method to call.
|
||||
methodName = rq.QUERY_STRING.split('=')[1]
|
||||
return self.xml(action=methodName)
|
||||
elif rq.has_key('do'):
|
||||
elif 'do' in rq:
|
||||
# The user wants to call a method on this object and get its result
|
||||
# as XML.
|
||||
return self.xml(action=rq['do'])
|
||||
|
@ -1672,7 +1673,7 @@ class BaseMixin:
|
|||
if field.type != 'group':
|
||||
fieldMapping = field.mapping[label]
|
||||
if fieldMapping:
|
||||
if callable(fieldMapping):
|
||||
if isinstance(fieldMapping, collections.Callable):
|
||||
fieldMapping = field.callMethod(self, fieldMapping)
|
||||
mapping.update(fieldMapping)
|
||||
label = getattr(field, '%sId' % label)
|
||||
|
@ -1697,15 +1698,15 @@ class BaseMixin:
|
|||
# Perform replacements, according to p_format.
|
||||
res = self.formatText(res, format)
|
||||
# Perform variable replacements
|
||||
for name, repl in mapping.iteritems():
|
||||
if not isinstance(repl, basestring): repl = str(repl)
|
||||
for name, repl in mapping.items():
|
||||
if not isinstance(repl, str): repl = str(repl)
|
||||
res = res.replace('${%s}' % name, repl)
|
||||
return res
|
||||
|
||||
def getPageLayout(self, layoutType):
|
||||
'''Returns the layout corresponding to p_layoutType for p_self.'''
|
||||
res = self.wrapperClass.getPageLayouts()[layoutType]
|
||||
if isinstance(res, basestring): res = Table(res)
|
||||
if isinstance(res, str): res = Table(res)
|
||||
return res
|
||||
|
||||
def download(self, name=None):
|
||||
|
|
21
gen/model.py
21
gen/model.py
|
@ -5,6 +5,7 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
import types
|
||||
import appy.gen as gen
|
||||
import collections
|
||||
|
||||
# Prototypical instances of every type -----------------------------------------
|
||||
class Protos:
|
||||
|
@ -49,7 +50,7 @@ class ModelClass:
|
|||
'''This method returns the code declaration for p_appyType.'''
|
||||
typeArgs = ''
|
||||
proto = Protos.get(appyType)
|
||||
for name, value in appyType.__dict__.iteritems():
|
||||
for name, value in appyType.__dict__.items():
|
||||
# Some attrs can't be given to the constructor
|
||||
if name in Protos.notInit: continue
|
||||
# If the given value corresponds to the default value, don't give it
|
||||
|
@ -74,7 +75,7 @@ class ModelClass:
|
|||
# defined. So we initialize it to None. The post-init of the
|
||||
# field must be done manually in wrappers.py.
|
||||
value = 'None'
|
||||
elif isinstance(value, basestring):
|
||||
elif isinstance(value, str):
|
||||
value = '"%s"' % value
|
||||
elif isinstance(value, gen.Ref):
|
||||
if not value.isBack: continue
|
||||
|
@ -91,10 +92,10 @@ class ModelClass:
|
|||
value = 'Grp("%s")' % value.name
|
||||
elif isinstance(value, gen.Page):
|
||||
value = 'pges["%s"]' % value.name
|
||||
elif callable(value):
|
||||
elif isinstance(value, collections.Callable):
|
||||
className = wrapperName
|
||||
if (appyType.type == 'Ref') and appyType.isBack:
|
||||
className = value.im_class.__name__
|
||||
className = value.__self__.__class__.__name__
|
||||
value = '%s.%s' % (className, value.__name__)
|
||||
typeArgs += '%s=%s,' % (name, value)
|
||||
return '%s(%s)' % (appyType.__class__.__name__, typeArgs)
|
||||
|
@ -118,17 +119,17 @@ class ModelClass:
|
|||
pages = {}
|
||||
layouts = []
|
||||
for name in klass._appy_attributes:
|
||||
exec 'appyType = klass.%s' % name
|
||||
exec('appyType = klass.%s' % name)
|
||||
if appyType.page.name not in pages:
|
||||
pages[appyType.page.name] = appyType.page
|
||||
res += ' pges = {'
|
||||
for page in pages.itervalues():
|
||||
for page in pages.values():
|
||||
# Determine page "show" attributes
|
||||
pShow = ''
|
||||
for attr in ('',) + page.subElements:
|
||||
attrName = 'show%s' % attr.capitalize()
|
||||
pageShow = getattr(page, attrName)
|
||||
if isinstance(pageShow, basestring): pageShow='"%s"' % pageShow
|
||||
if isinstance(pageShow, str): pageShow='"%s"' % pageShow
|
||||
elif callable(pageShow):
|
||||
pageShow = '%s.%s' % (wrapperName, pageShow.__name__)
|
||||
if pageShow != True:
|
||||
|
@ -142,7 +143,7 @@ class ModelClass:
|
|||
res += '}\n'
|
||||
# Secondly, dump every (not Ref.isBack) attribute
|
||||
for name in klass._appy_attributes:
|
||||
exec 'appyType = klass.%s' % name
|
||||
exec('appyType = klass.%s' % name)
|
||||
if (appyType.type == 'Ref') and appyType.isBack: continue
|
||||
typeBody = klass._appy_getTypeBody(appyType, wrapperName)
|
||||
res += ' %s=%s\n' % (name, typeBody)
|
||||
|
@ -305,12 +306,12 @@ class Tool(ModelClass):
|
|||
@classmethod
|
||||
def _appy_clean(klass):
|
||||
toClean = []
|
||||
for k, v in klass.__dict__.iteritems():
|
||||
for k, v in klass.__dict__.items():
|
||||
if not k.startswith('__') and (not k.startswith('_appy_')):
|
||||
if k not in defaultToolFields:
|
||||
toClean.append(k)
|
||||
for k in toClean:
|
||||
exec 'del klass.%s' % k
|
||||
exec('del klass.%s' % k)
|
||||
klass._appy_attributes = list(defaultToolFields)
|
||||
klass.folder = True
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
import os, re, time, copy
|
||||
from utils import produceNiceMessage
|
||||
from .utils import produceNiceMessage
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
poHeader = '''msgid ""
|
||||
|
@ -213,7 +213,7 @@ class PoFile:
|
|||
if keepExistingOrder:
|
||||
# Update existing messages and add inexistent messages to the end.
|
||||
for newMsg in newMessages:
|
||||
if self.messagesDict.has_key(newMsg.id):
|
||||
if newMsg.id in self.messagesDict:
|
||||
msg = self.messagesDict[newMsg.id]
|
||||
else:
|
||||
msg = self.addMessage(newMsg)
|
||||
|
@ -224,7 +224,7 @@ class PoFile:
|
|||
notNewMessages = [m for m in self.messages if m.id not in newIds]
|
||||
del self.messages[:]
|
||||
for newMsg in newMessages:
|
||||
if self.messagesDict.has_key(newMsg.id):
|
||||
if newMsg.id in self.messagesDict:
|
||||
msg = self.messagesDict[newMsg.id]
|
||||
self.messages.append(msg)
|
||||
else:
|
||||
|
@ -240,7 +240,7 @@ class PoFile:
|
|||
fb = ''
|
||||
if not self.isPot:
|
||||
# I must add fallbacks
|
||||
if fallbacks.has_key(self.language):
|
||||
if self.language in fallbacks:
|
||||
fb = '"X-is-fallback-for: %s\\n"' % fallbacks[self.language]
|
||||
f.write(poHeader % (self.applicationName, creationTime,
|
||||
self.language, self.language, self.domain, fb))
|
||||
|
|
21
gen/utils.py
21
gen/utils.py
|
@ -1,7 +1,8 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
import re, os, os.path, base64, urllib
|
||||
import re, os, os.path, base64, urllib.request, urllib.parse, urllib.error
|
||||
from appy.px import Px
|
||||
from appy.shared import utils as sutils
|
||||
import collections
|
||||
|
||||
# Function for creating a Zope object ------------------------------------------
|
||||
def createObject(folder, id, className, appName, wf=True, noSecurity=False):
|
||||
|
@ -10,8 +11,8 @@ def createObject(folder, id, className, appName, wf=True, noSecurity=False):
|
|||
creation of the config object), computing workflow-related info is not
|
||||
possible at this time. This is why this function can be called with
|
||||
p_wf=False.'''
|
||||
exec 'from Products.%s.%s import %s as ZopeClass' % \
|
||||
(appName, className, className)
|
||||
exec('from Products.%s.%s import %s as ZopeClass' % \
|
||||
(appName, className, className))
|
||||
# Get the tool. It may not be present yet, maybe are we creating it now.
|
||||
if folder.meta_type.endswith('Folder'):
|
||||
# p_folder is a standard Zope (temp) folder.
|
||||
|
@ -178,7 +179,7 @@ def callMethod(obj, method, klass=None, cache=True):
|
|||
if methodType == 'staticmethod':
|
||||
method = method.__get__(klass)
|
||||
elif methodType == 'instancemethod':
|
||||
method = method.im_func
|
||||
method = method.__func__
|
||||
# Call the method if cache is not needed
|
||||
if not cache: return method(obj)
|
||||
# If first arg of method is named "tool" instead of the traditional "self",
|
||||
|
@ -187,7 +188,7 @@ def callMethod(obj, method, klass=None, cache=True):
|
|||
# Every method call, even on different instances, will be cached in a unique
|
||||
# key.
|
||||
cheat = False
|
||||
if not klass and (method.func_code.co_varnames[0] == 'tool'):
|
||||
if not klass and (method.__code__.co_varnames[0] == 'tool'):
|
||||
prefix = obj.klass.__name__
|
||||
obj = obj.tool
|
||||
cheat = True
|
||||
|
@ -200,7 +201,7 @@ def callMethod(obj, method, klass=None, cache=True):
|
|||
else:
|
||||
prefix = obj.uid
|
||||
# Second part of the key: p_method name
|
||||
key = '%s:%s' % (prefix, method.func_name)
|
||||
key = '%s:%s' % (prefix, method.__name__)
|
||||
# Return the cached value if present in the method cache.
|
||||
if key in rq.methodCache:
|
||||
return rq.methodCache[key]
|
||||
|
@ -216,20 +217,20 @@ def readCookie(request):
|
|||
(None, None).'''
|
||||
cookie = request.get('_appy_', None)
|
||||
if not cookie: return None, None
|
||||
cookieValue = base64.decodestring(urllib.unquote(cookie))
|
||||
cookieValue = base64.decodestring(urllib.parse.unquote(cookie))
|
||||
if ':' in cookieValue: return cookieValue.split(':')
|
||||
return None, None
|
||||
|
||||
def writeCookie(login, password, request):
|
||||
'''Encode p_login and p_password into the cookie set in the p_request.'''
|
||||
cookieValue = base64.encodestring('%s:%s' % (login, password)).rstrip()
|
||||
cookieValue = urllib.quote(cookieValue)
|
||||
cookieValue = urllib.parse.quote(cookieValue)
|
||||
request.RESPONSE.setCookie('_appy_', cookieValue, path='/')
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def initMasterValue(v):
|
||||
'''Standardizes p_v as a list of strings, excepted if p_v is a method.'''
|
||||
if callable(v): return v
|
||||
if isinstance(v, collections.Callable): return v
|
||||
if not isinstance(v, bool) and not v: res = []
|
||||
elif type(v) not in sutils.sequenceTypes: res = [v]
|
||||
else: res = v
|
||||
|
@ -243,7 +244,7 @@ class No:
|
|||
instead. When creating such an instance, you can specify an error
|
||||
message.'''
|
||||
def __init__(self, msg): self.msg = msg
|
||||
def __nonzero__(self): return False
|
||||
def __bool__(self): return False
|
||||
def __repr__(self): return '<No: %s>' % self.msg
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -424,7 +424,7 @@ class ToolWrapper(AbstractWrapper):
|
|||
'<tr><th></th><th>%s</th></tr>' % \
|
||||
self.translate('last_user_access')
|
||||
rows = []
|
||||
for userId, lastAccess in self.o.loggedUsers.items():
|
||||
for userId, lastAccess in list(self.o.loggedUsers.items()):
|
||||
user = self.search1('User', noSecurity=True, login=userId)
|
||||
if not user: continue # Could have been deleted in the meanwhile
|
||||
fmt = '%s (%s)' % (self.dateFormat, self.hourFormat)
|
||||
|
@ -515,7 +515,7 @@ class ToolWrapper(AbstractWrapper):
|
|||
failed += subFailed
|
||||
try:
|
||||
startObject.reindex()
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
failed.append(startObject)
|
||||
return nb, failed
|
||||
|
||||
|
|
|
@ -343,7 +343,7 @@ class UserWrapper(AbstractWrapper):
|
|||
if not localRoles: return res
|
||||
# Gets the logins of this user and all its groups.
|
||||
logins = self.getLogins()
|
||||
for login, roles in localRoles.iteritems():
|
||||
for login, roles in localRoles.items():
|
||||
# Ignore logins not corresponding to this user.
|
||||
if login not in logins: continue
|
||||
for role in roles:
|
||||
|
@ -388,7 +388,7 @@ class UserWrapper(AbstractWrapper):
|
|||
if not localRoles: return
|
||||
# Gets the logins of this user and all its groups.
|
||||
userLogins = self.getLogins()
|
||||
for login, roles in localRoles.iteritems():
|
||||
for login, roles in localRoles.items():
|
||||
# Ignore logins not corresponding to this user.
|
||||
if login not in userLogins: continue
|
||||
for role in roles:
|
||||
|
|
|
@ -861,7 +861,7 @@ class AbstractWrapper(object):
|
|||
if len(self.__class__.__bases__) > 1:
|
||||
# There is a custom user class
|
||||
custom = self.__class__.__bases__[-1]
|
||||
if custom.__dict__.has_key(methodName):
|
||||
if methodName in custom.__dict__:
|
||||
return custom.__dict__[methodName]
|
||||
|
||||
def _callCustom(self, methodName, *args, **kwargs):
|
||||
|
@ -973,7 +973,7 @@ class AbstractWrapper(object):
|
|||
present, will not be called; any other defined method will not be
|
||||
called neither (ie, Ref.insert, Ref.beforeLink, Ref.afterLink...).
|
||||
'''
|
||||
isField = isinstance(fieldNameOrClass, basestring)
|
||||
isField = isinstance(fieldNameOrClass, str)
|
||||
tool = self.tool.o
|
||||
# Determine the class of the object to create
|
||||
if isField:
|
||||
|
@ -984,7 +984,7 @@ class AbstractWrapper(object):
|
|||
klass = fieldNameOrClass
|
||||
portalType = tool.getPortalType(klass)
|
||||
# Determine object id
|
||||
if kwargs.has_key('id'):
|
||||
if 'id' in kwargs:
|
||||
objId = kwargs['id']
|
||||
del kwargs['id']
|
||||
else:
|
||||
|
@ -1002,7 +1002,7 @@ class AbstractWrapper(object):
|
|||
noSecurity=noSecurity)
|
||||
appyObj = zopeObj.appy()
|
||||
# Set object attributes
|
||||
for attrName, attrValue in kwargs.iteritems():
|
||||
for attrName, attrValue in kwargs.items():
|
||||
try:
|
||||
setattr(appyObj, attrName, attrValue)
|
||||
except AttributeError, ae:
|
||||
|
@ -1183,8 +1183,8 @@ class AbstractWrapper(object):
|
|||
# Get the Appy object from the brain
|
||||
if noSecurity: method = '_unrestrictedGetObject'
|
||||
else: method = 'getObject'
|
||||
exec 'obj = brain.%s().appy()' % method
|
||||
exec expression
|
||||
exec('obj = brain.%s().appy()' % method)
|
||||
exec(expression)
|
||||
return ctx
|
||||
|
||||
def reindex(self, fields=None, unindex=False):
|
||||
|
@ -1249,7 +1249,7 @@ class AbstractWrapper(object):
|
|||
else:
|
||||
return xml
|
||||
elif format == 'csv':
|
||||
if isinstance(at, basestring):
|
||||
if isinstance(at, str):
|
||||
marshaller = CsvMarshaller(include=include, exclude=exclude)
|
||||
return marshaller.marshall(self)
|
||||
else:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue