From c5a8968bd3b0b33fd12898f9a2b6c722a8abe4ec Mon Sep 17 00:00:00 2001
From: Gaetan Delannay
Date: Mon, 5 Dec 2011 15:11:29 +0100
Subject: [PATCH] appy.gen: Refactoring due to De-Plonization.
---
bin/generate.py | 36 +++-------
gen/__init__.py | 51 +++++----------
gen/descriptors.py | 86 ++++++++++++------------
gen/generator.py | 50 ++++++--------
gen/installer.py | 16 ++---
gen/migrator.py | 3 +-
gen/mixins/TestMixin.py | 4 +-
gen/mixins/ToolMixin.py | 19 +++---
gen/mixins/__init__.py | 22 +++----
gen/model.py | 101 ++++++++++++++---------------
gen/notifier.py | 18 ++---
gen/odt/__init__.py | 0
gen/odt/generator.py | 54 ---------------
gen/odt/templates/basic.odt | Bin 10487 -> 0 bytes
gen/plone25/__init__.py | 0
gen/templates/Class.py | 4 +-
gen/templates/Styles.css.dtml | 90 -------------------------
gen/templates/__init__.py | 4 +-
gen/templates/config.py | 4 +-
gen/templates/configure.zcml | 6 --
gen/templates/testAll.py | 10 +--
gen/templates/wrappers.py | 10 +--
gen/ui/import.pt | 32 +++------
gen/ui/page.pt | 32 ++++-----
gen/ui/portlet.pt | 4 +-
gen/ui/result.pt | 5 +-
gen/ui/widgets/action.pt | 5 +-
gen/ui/widgets/boolean.pt | 4 +-
gen/ui/widgets/file.pt | 11 ++--
gen/ui/widgets/ref.pt | 5 +-
gen/utils.py | 23 ++++---
gen/wrappers/GroupWrapper.py | 2 +-
gen/wrappers/ToolWrapper.py | 2 +-
gen/wrappers/TranslationWrapper.py | 2 +-
gen/wrappers/UserWrapper.py | 2 +-
35 files changed, 237 insertions(+), 480 deletions(-)
delete mode 100644 gen/odt/__init__.py
delete mode 100644 gen/odt/generator.py
delete mode 100644 gen/odt/templates/basic.odt
delete mode 100644 gen/plone25/__init__.py
delete mode 100644 gen/templates/Styles.css.dtml
delete mode 100644 gen/templates/configure.zcml
diff --git a/bin/generate.py b/bin/generate.py
index 72375e4..c92faf2 100644
--- a/bin/generate.py
+++ b/bin/generate.py
@@ -3,18 +3,15 @@
# ------------------------------------------------------------------------------
import sys, os.path
from optparse import OptionParser
-from appy.gen.generator import GeneratorError
+from appy.gen.generator import GeneratorError, ZopeGenerator
from appy.shared.utils import LinesCounter
import appy.version
# ------------------------------------------------------------------------------
ERROR_CODE = 1
-VALID_PRODUCT_TYPES = ('zope', 'odt')
APP_NOT_FOUND = 'Application not found at %s.'
WRONG_NG_OF_ARGS = 'Wrong number of arguments.'
WRONG_OUTPUT_FOLDER = 'Output folder not found. Please create it first.'
-PRODUCT_TYPE_ERROR = 'Wrong product type. Product type may be one of the ' \
- 'following: %s' % str(VALID_PRODUCT_TYPES)
C_OPTION = 'Removes from i18n files all labels that are not automatically ' \
'generated from your gen-application. It can be useful during ' \
'development, when you do lots of name changes (classes, ' \
@@ -37,7 +34,7 @@ S_OPTION = 'Sorts all i18n labels. If you use this option, among the ' \
'set of translation files.'
class GeneratorScript:
- '''usage: %prog [options] app productType outputFolder
+ '''usage: %prog [options] app outputFolder
"app" is the path to your Appy application, which must be a
Python package (= a folder containing a file named
@@ -47,44 +44,29 @@ class GeneratorScript:
generated product, stored or symlinked in
/Products.
- "productType" is the kind of product you want to generate. "zope" is
- the only available production-ready target.
- "odt" is experimental.
-
"outputFolder" is the folder where the Zope product will be generated.
For example, if you develop your application in
/home/gdy/MyProject/MyProject, you typically specify
"/home/gdy/MyProject/zope" as outputFolder.
'''
-
- def generateProduct(self, options, application, productType, outputFolder):
- if productType == 'odt':
- exec 'from appy.gen.odt.generator import Generator'
- else:
- from appy.gen.generator import ZopeGenerator as Generator
- Generator(application, outputFolder, options).run()
-
def manageArgs(self, parser, options, args):
# Check number of args
- if len(args) != 3:
+ if len(args) != 2:
print WRONG_NG_OF_ARGS
parser.print_help()
sys.exit(ERROR_CODE)
- # Check productType
- if args[1] not in VALID_PRODUCT_TYPES:
- print PRODUCT_TYPE_ERROR
- sys.exit(ERROR_CODE)
# Check existence of application
if not os.path.exists(args[0]):
print APP_NOT_FOUND % args[0]
sys.exit(ERROR_CODE)
- # Check existence of outputFolder basic type
- if not os.path.exists(args[2]):
+ # Check existence of outputFolder
+ if not os.path.exists(args[1]):
print WRONG_OUTPUT_FOLDER
sys.exit(ERROR_CODE)
# Convert all paths in absolute paths
- for i in (0,2):
+ for i in (0,1):
args[i] = os.path.abspath(args[i])
+
def run(self):
optParser = OptionParser(usage=GeneratorScript.__doc__)
optParser.add_option("-c", "--i18n-clean", action='store_true',
@@ -95,8 +77,8 @@ class GeneratorScript:
try:
self.manageArgs(optParser, options, args)
print 'Appy version:', appy.version.verbose
- print 'Generating %s product in %s...' % (args[1], args[2])
- self.generateProduct(options, *args)
+ print 'Generating Zope product in %s...' % args[1]
+ ZopeGenerator(args[0], args[1], options).run()
# Give the user some statistics about its code
LinesCounter(args[0]).run()
except GeneratorError, ge:
diff --git a/gen/__init__.py b/gen/__init__.py
index 5c88e7b..6322b28 100644
--- a/gen/__init__.py
+++ b/gen/__init__.py
@@ -1026,8 +1026,7 @@ class String(Type):
it will be given by the Appy validation machinery, so it must be
specified as parameter. The function returns True if the check is
successful.'''
- if not value: return True # Plone calls me erroneously for
- # non-mandatory fields.
+ if not value: return True
# First, remove any non-digit char
v = ''
for c in value:
@@ -1058,8 +1057,7 @@ class String(Type):
'''Checks that p_value corresponds to a valid IBAN number. IBAN stands
for International Bank Account Number (ISO 13616). If the number is
valid, the method returns True.'''
- if not value: return True # Plone calls me erroneously for
- # non-mandatory fields.
+ if not value: return True
# First, remove any non-digit or non-letter char
v = ''
for c in value:
@@ -1088,8 +1086,7 @@ class String(Type):
'''Checks that p_value corresponds to a valid BIC number. BIC stands
for Bank Identifier Code (ISO 9362). If the number is valid, the
method returns True.'''
- if not value: return True # Plone calls me erroneously for
- # non-mandatory fields.
+ if not value: return True
# BIC number must be 8 or 11 chars
if len(value) not in (8, 11): return False
# 4 first chars, representing bank name, must be letters
@@ -1176,15 +1173,7 @@ class String(Type):
else: return value
if isinstance(value, basestring) and self.isMultiValued():
value = [value]
- # Some backward compatibilities with Archetypes.
- elif value.__class__.__name__ == 'BaseUnit':
- try:
- value = unicode(value)
- except UnicodeDecodeError:
- value = str(value)
elif isinstance(value, tuple):
- # When Appy storage was based on Archetype, multivalued string
- # fields stored values as tuples of unicode strings.
value = list(value)
return value
@@ -1207,12 +1196,6 @@ class String(Type):
res = [t('%s_list_%s' % (self.labelId, v)) for v in value]
else:
res = t('%s_list_%s' % (self.labelId, value))
- elif not isinstance(value, basestring):
- # Archetypes "Description" fields may hold a BaseUnit instance.
- try:
- res = unicode(value)
- except UnicodeDecodeError:
- res = str(value)
# If value starts with a carriage return, add a space; else, it will
# be ignored.
if isinstance(res, basestring) and \
@@ -1384,8 +1367,8 @@ class Boolean(Type):
return value
def getFormattedValue(self, obj, value):
- if value: res = obj.translate('yes', domain='plone')
- else: res = obj.translate('no', domain='plone')
+ if value: res = obj.translate('yes')
+ else: res = obj.translate('no')
return res
def getStorableValue(self, value):
@@ -1517,7 +1500,7 @@ class File(Type):
def getFormattedValue(self, obj, value):
if not value: return value
- return value._atFile
+ return value._zopeFile
def getRequestValue(self, request):
return request.get('%s_file' % self.name)
@@ -1591,7 +1574,7 @@ class File(Type):
elif isinstance(value, OFSImageFile):
setattr(obj, self.name, value)
elif isinstance(value, FileWrapper):
- setattr(obj, self.name, value._atFile)
+ setattr(obj, self.name, value._zopeFile)
elif isinstance(value, basestring):
setattr(obj, self.name, File.getFileObject(value, zope=True))
elif type(value) in sequenceTypes:
@@ -2189,7 +2172,7 @@ class Pod(Type):
def store(self, obj, value):
'''Stores (=freezes) a document (in p_value) in the field.'''
if isinstance(value, FileWrapper):
- value = value._atFile
+ value = value._zopeFile
setattr(obj, self.name, value)
class List(Type):
@@ -2283,19 +2266,18 @@ appyToZopePermissions = {
class Role:
'''Represents a role.'''
- ploneRoles = ('Manager', 'Member', 'Owner', 'Reviewer', 'Anonymous',
- 'Authenticated')
- ploneLocalRoles = ('Owner',)
- ploneUngrantableRoles = ('Anonymous', 'Authenticated')
+ zopeRoles = ('Manager', 'Owner', 'Anonymous', 'Authenticated')
+ zopeLocalRoles = ('Owner',)
+ zopeUngrantableRoles = ('Anonymous', 'Authenticated')
def __init__(self, name, local=False, grantable=True):
self.name = name
self.local = local # True if it can be used as local role only.
- # It is a standard Plone role or an application-specific one?
- self.plone = name in self.ploneRoles
- if self.plone and (name in self.ploneLocalRoles):
+ # It is a standard Zope role or an application-specific one?
+ self.zope = name in self.zopeRoles
+ if self.zope and (name in self.zopeLocalRoles):
self.local = True
self.grantable = grantable
- if self.plone and (name in self.ploneUngrantableRoles):
+ if self.zope and (name in self.zopeUngrantableRoles):
self.grantable = False
# An ungrantable role is one that is, like the Anonymous or
# Authenticated roles, automatically attributed to a user.
@@ -2575,8 +2557,7 @@ class Transition:
# Return a message to the user if needed
if not doSay or (transitionName == '_init_'): return
if not msg:
- msg = obj.translate(u'Your content\'s status has been modified.',
- domain='plone')
+ msg = obj.translate(u'Changes saved.')
obj.say(msg)
class Permission:
diff --git a/gen/descriptors.py b/gen/descriptors.py
index 3459b05..40b05dd 100644
--- a/gen/descriptors.py
+++ b/gen/descriptors.py
@@ -4,7 +4,7 @@
# ------------------------------------------------------------------------------
import types, copy
-from appy.gen import State, Transition, Type
+import appy.gen as gen
from po import PoMessage
from model import ModelClass, toolFieldPrefixes
from utils import produceNiceMessage, getClassName
@@ -27,8 +27,7 @@ class ClassDescriptor(Descriptor):
'''This class gives information about an Appy class.'''
def __init__(self, klass, orderedAttributes, generator):
- appy.gen.descriptors.ClassDescriptor.__init__(self, klass,
- orderedAttributes, generator)
+ Descriptor.__init__(self, klass, orderedAttributes, generator)
self.methods = '' # Needed method definitions will be generated here
# We remember here encountered pages and groups defined in the Appy
# type. Indeed, after having parsed all application classes, we will
@@ -70,7 +69,7 @@ class ClassDescriptor(Descriptor):
except AttributeError:
attrValue = getattr(self.modelClass, attrName)
hookClass = self.modelClass
- if isinstance(attrValue, Type):
+ if isinstance(attrValue, gen.Type):
if not condition or eval(condition):
attrs.append( (attrName, attrValue, hookClass) )
# Then, add attributes from parent classes
@@ -142,7 +141,7 @@ class ClassDescriptor(Descriptor):
attrValue = getattr(self.klass, attrName)
except AttributeError:
attrValue = getattr(self.modelClass, attrName)
- if isinstance(attrValue, Type):
+ if isinstance(attrValue, gen.Type):
if configClass:
attrValue = copy.copy(attrValue)
attrValue.optional = False
@@ -184,13 +183,13 @@ class ClassDescriptor(Descriptor):
res = []
if self.klass.__dict__.has_key('creators') and self.klass.creators:
for creator in self.klass.creators:
- if isinstance(creator, Role):
+ if isinstance(creator, gen.Role):
if creator.local:
raise 'Local role "%s" cannot be used as a creator.' % \
creator.name
res.append(creator)
else:
- res.append(Role(creator))
+ res.append(gen.Role(creator))
return res
def getCreateMean(self, type='Import'):
@@ -213,13 +212,17 @@ class ClassDescriptor(Descriptor):
res = []
if klass.__dict__.has_key('search'):
searches = klass.__dict__['search']
- if isinstance(searches, basestring): res.append(Search(searches))
- elif isinstance(searches, Search): res.append(searches)
+ if isinstance(searches, basestring):
+ res.append(gen.Search(searches))
+ elif isinstance(searches, gen.Search):
+ res.append(searches)
else:
# It must be a list of searches.
for search in searches:
- if isinstance(search, basestring):res.append(Search(search))
- else: res.append(search)
+ if isinstance(search, basestring):
+ res.append(gen.Search(search))
+ else:
+ res.append(search)
return res
@staticmethod
@@ -268,11 +271,10 @@ class FieldDescriptor:
'''This class gathers information about a specific typed attribute defined
in a gen-class.'''
- singleValuedTypes = ('Integer', 'Float', 'Boolean', 'Date', 'File')
# Although Appy allows to specify a multiplicity[0]>1 for those types, it is
- # not supported by Archetypes. So we will always generate single-valued type
- # definitions for them.
- specialParams = ('title', 'description')
+ # not currently. So we will always generate single-valued type definitions
+ # for them.
+ singleValuedTypes = ('Integer', 'Float', 'Boolean', 'Date', 'File')
def __init__(self, fieldName, appyType, classDescriptor):
self.appyType = appyType
@@ -387,8 +389,7 @@ class FieldDescriptor:
if self.appyType.editDefault:
self.generator.tool.addDefaultField(self)
# - put an index on this field?
- if self.appyType.indexed and \
- (self.fieldName not in ('title', 'description')):
+ if self.appyType.indexed and (self.fieldName != 'title'):
self.classDescr.addIndexMethod(self)
# i18n labels
messages = self.generator.labels
@@ -477,7 +478,7 @@ class ToolClassDescriptor(ClassDescriptor):
self.addField(fieldName, fieldType)
fieldType.validator.append(fieldDescr.fieldName)
fieldType.page.name = 'data'
- fieldType.group = Group(fieldDescr.classDescr.klass.__name__)
+ fieldType.group = gen.Group(fieldDescr.classDescr.klass.__name__)
def addDefaultField(self, fieldDescr):
className = fieldDescr.classDescr.name
@@ -485,22 +486,22 @@ class ToolClassDescriptor(ClassDescriptor):
fieldType = fieldDescr.appyType.clone()
self.addField(fieldName, fieldType)
fieldType.page.name = 'data'
- fieldType.group = Group(fieldDescr.classDescr.klass.__name__)
+ fieldType.group = gen.Group(fieldDescr.classDescr.klass.__name__)
def addPodRelatedFields(self, fieldDescr):
'''Adds the fields needed in the Tool for configuring a Pod field.'''
className = fieldDescr.classDescr.name
# On what page and group to display those fields ?
pg = {'page': 'documentGeneration',
- 'group': Group(fieldDescr.classDescr.klass.__name__, ['50%']*2)}
+ 'group':gen.Group(fieldDescr.classDescr.klass.__name__,['50%']*2)}
# Add the field that will store the pod template.
fieldName = 'podTemplateFor%s_%s' % (className, fieldDescr.fieldName)
- fieldType = File(**pg)
+ fieldType = gen.File(**pg)
self.addField(fieldName, fieldType)
# Add the field that will store the output format(s)
fieldName = 'formatsFor%s_%s' % (className, fieldDescr.fieldName)
- fieldType = String(validator=Selection('getPodOutputFormats'),
- multiplicity=(1,None), default=('odt',), **pg)
+ fieldType = gen.String(validator=gen.Selection('getPodOutputFormats'),
+ multiplicity=(1,None), default=('odt',), **pg)
self.addField(fieldName, fieldType)
def addQueryResultColumns(self, classDescr):
@@ -508,7 +509,7 @@ class ToolClassDescriptor(ClassDescriptor):
to select what default columns will be shown on query results.'''
className = classDescr.name
fieldName = 'resultColumnsFor%s' % className
- fieldType = String(multiplicity=(0,None), validator=Selection(
+ fieldType = gen.String(multiplicity=(0,None), validator=gen.Selection(
'_appy_getAllFields*%s' % className), page='userInterface',
group=classDescr.klass.__name__)
self.addField(fieldName, fieldType)
@@ -520,21 +521,21 @@ class ToolClassDescriptor(ClassDescriptor):
# Field that defines if advanced search is enabled for class
# p_classDescr or not.
fieldName = 'enableAdvancedSearchFor%s' % className
- fieldType = Boolean(default=True, page='userInterface',
- group=classDescr.klass.__name__)
+ fieldType = gen.Boolean(default=True, page='userInterface',
+ group=classDescr.klass.__name__)
self.addField(fieldName, fieldType)
# Field that defines how many columns are shown on the custom search
# screen.
fieldName = 'numberOfSearchColumnsFor%s' % className
- fieldType = Integer(default=3, page='userInterface',
- group=classDescr.klass.__name__)
+ fieldType = gen.Integer(default=3, page='userInterface',
+ group=classDescr.klass.__name__)
self.addField(fieldName, fieldType)
# Field that allows to select, among all indexed fields, what fields
# must really be used in the search screen.
fieldName = 'searchFieldsFor%s' % className
defaultValue = [a[0] for a in classDescr.getOrderedAppyAttributes(
condition='attrValue.indexed')]
- fieldType = String(multiplicity=(0,None), validator=Selection(
+ fieldType = gen.String(multiplicity=(0,None), validator=gen.Selection(
'_appy_getSearchableFields*%s' % className), default=defaultValue,
page='userInterface', group=classDescr.klass.__name__)
self.addField(fieldName, fieldType)
@@ -546,8 +547,8 @@ class ToolClassDescriptor(ClassDescriptor):
# Field that defines the path of the files to import.
fieldName = 'importPathFor%s' % className
defValue = classDescr.getCreateMean('Import').path
- fieldType = String(page='data', multiplicity=(1,1), default=defValue,
- group=classDescr.klass.__name__)
+ fieldType = gen.String(page='data', multiplicity=(1,1),
+ default=defValue,group=classDescr.klass.__name__)
self.addField(fieldName, fieldType)
def addWorkflowFields(self, classDescr):
@@ -560,13 +561,13 @@ class ToolClassDescriptor(ClassDescriptor):
if classDescr.isRoot() or issubclass(classDescr.klass, ModelClass):
defaultValue = True
fieldName = 'showWorkflowFor%s' % className
- fieldType = Boolean(default=defaultValue, page='userInterface',
- group=groupName)
+ fieldType = gen.Boolean(default=defaultValue, page='userInterface',
+ group=groupName)
self.addField(fieldName, fieldType)
# Adds the boolean field for showing or not the field "enter comments".
fieldName = 'showWorkflowCommentFieldFor%s' % className
- fieldType = Boolean(default=defaultValue, page='userInterface',
- group=groupName)
+ fieldType = gen.Boolean(default=defaultValue, page='userInterface',
+ group=groupName)
self.addField(fieldName, fieldType)
# Adds the boolean field for showing all states in current state or not.
# If this boolean is True but the current phase counts only one state,
@@ -577,13 +578,12 @@ class ToolClassDescriptor(ClassDescriptor):
if len(classDescr.getPhases()) > 1:
defaultValue = True
fieldName = 'showAllStatesInPhaseFor%s' % className
- fieldType = Boolean(default=defaultValue, page='userInterface',
- group=groupName)
+ fieldType = gen.Boolean(default=defaultValue, page='userInterface',
+ group=groupName)
self.addField(fieldName, fieldType)
class UserClassDescriptor(ClassDescriptor):
- '''Represents an Archetypes-compliant class that corresponds to the User
- for the generated application.'''
+ '''Appy-specific class for representing a user.'''
def __init__(self, klass, generator):
ClassDescriptor.__init__(self,klass,klass._appy_attributes[:],generator)
self.modelClass = self.klass
@@ -649,8 +649,8 @@ class TranslationClassDescriptor(ClassDescriptor):
def addLabelField(self, messageId, page):
'''Adds a Computed field that will display, in the source language, the
content of the text to translate.'''
- field = Computed(method=self.modelClass.label, plainText=False,
- page=page, show=self.modelClass.show, layouts='f')
+ field = gen.Computed(method=self.modelClass.label, plainText=False,
+ page=page, show=self.modelClass.show, layouts='f')
self.addField('%s_label' % messageId, field)
def addMessageField(self, messageId, page, i18nFiles):
@@ -683,7 +683,7 @@ class TranslationClassDescriptor(ClassDescriptor):
params['width'] = width
else:
# This is a multi-line field, or a very-long-single-lined field
- params['format'] = String.TEXT
+ params['format'] = gen.String.TEXT
params['height'] = height
- self.addField(messageId, String(**params))
+ self.addField(messageId, gen.String(**params))
# ------------------------------------------------------------------------------
diff --git a/gen/generator.py b/gen/generator.py
index fd7c58d..8ca3c75 100644
--- a/gen/generator.py
+++ b/gen/generator.py
@@ -2,7 +2,7 @@
import os, os.path, re, sys, parser, symbol, token, types
import appy.pod, appy.pod.renderer
from appy.shared.utils import FolderDeleter
-#from appy.gen import *
+import appy.gen as gen
from po import PoMessage, PoFile, PoParser
from descriptors import *
from utils import produceNiceMessage, getClassName
@@ -140,7 +140,7 @@ class Generator:
self.user = None
self.workflows = []
self.initialize()
- self.config = Config.getDefault()
+ self.config = gen.Config.getDefault()
self.modulesWithTests = set()
self.totalNumberOfTests = 0
@@ -152,9 +152,9 @@ class Generator:
workflow.'''
res = 'none'
for attrValue in klass.__dict__.itervalues():
- if isinstance(attrValue, Type):
+ if isinstance(attrValue, gen.Type):
res = 'class'
- elif isinstance(attrValue, State):
+ elif isinstance(attrValue, gen.State):
res = 'workflow'
if not res:
for baseClass in klass.__bases__:
@@ -219,13 +219,13 @@ class Generator:
attrs = astClasses[moduleElem.__name__].attributes
if appyType == 'class':
# Determine the class type (standard, tool, user...)
- if issubclass(moduleElem, Tool):
+ if issubclass(moduleElem, gen.Tool):
if not self.tool:
klass = self.descriptorClasses['tool']
self.tool = klass(moduleElem, attrs, self)
else:
self.tool.update(moduleElem, attrs)
- elif issubclass(moduleElem, User):
+ elif issubclass(moduleElem, gen.User):
if not self.user:
klass = self.descriptorClasses['user']
self.user = klass(moduleElem, attrs, self)
@@ -244,7 +244,7 @@ class Generator:
self.workflows.append(descriptor)
if self.containsTests(moduleElem):
self.modulesWithTests.add(moduleObj.__name__)
- elif isinstance(moduleElem, Config):
+ elif isinstance(moduleElem, gen.Config):
self.config = moduleElem
# Walk potential sub-modules
@@ -461,7 +461,6 @@ class ZopeGenerator(Generator):
self.generateTool()
self.generateInit()
self.generateTests()
- self.generateConfigureZcml()
# Create version.txt
f = open(os.path.join(self.outputFolder, 'version.txt'), 'w')
f.write(self.version)
@@ -536,13 +535,13 @@ class ZopeGenerator(Generator):
self.generateWrappers()
self.generateConfig()
- def getAllUsedRoles(self, plone=None, local=None, grantable=None):
+ def getAllUsedRoles(self, zope=None, local=None, grantable=None):
'''Produces a list of all the roles used within all workflows and
classes defined in this application.
- If p_plone is True, it keeps only Plone-standard roles; if p_plone
+ If p_zope is True, it keeps only Zope-standard roles; if p_zope
is False, it keeps only roles which are specific to this application;
- if p_plone is None it has no effect (so it keeps both roles).
+ if p_zope is None it has no effect (so it keeps both roles).
If p_local is True, it keeps only local roles (ie, roles that can
only be granted locally); if p_local is False, it keeps only "global"
@@ -557,8 +556,8 @@ class ZopeGenerator(Generator):
for wfDescr in self.workflows:
for attr in dir(wfDescr.klass):
attrValue = getattr(wfDescr.klass, attr)
- if isinstance(attrValue, State) or \
- isinstance(attrValue, Transition):
+ if isinstance(attrValue, gen.State) or \
+ isinstance(attrValue, gen.Transition):
for role in attrValue.getUsedRoles():
if role.name not in allRoles:
allRoles[role.name] = role
@@ -569,7 +568,7 @@ class ZopeGenerator(Generator):
allRoles[role.name] = role
res = allRoles.values()
# Filter the result according to parameters
- for p in ('plone', 'local', 'grantable'):
+ for p in ('zope', 'local', 'grantable'):
if eval(p) != None:
res = [r for r in res if eval('r.%s == %s' % (p, p))]
return res
@@ -613,17 +612,6 @@ class ZopeGenerator(Generator):
res = configClasses
return res
- def generateConfigureZcml(self):
- '''Generates file configure.zcml.'''
- repls = self.repls.copy()
- # Note every class as "deprecated".
- depr = ''
- for klass in self.getClasses(include='all'):
- depr += '\n' % \
- (klass.name, klass.name)
- repls['deprecated'] = depr
- self.copyFile('configure.zcml', repls)
-
def generateConfig(self):
repls = self.repls.copy()
# Get some lists of classes
@@ -677,9 +665,9 @@ class ZopeGenerator(Generator):
attributes.append('"%s":[%s]' % (classDescr.name, ','.join(qNames)))
repls['attributes'] = ',\n '.join(attributes)
# Compute list of used roles for registering them if needed
- specificRoles = self.getAllUsedRoles(plone=False)
+ specificRoles = self.getAllUsedRoles(zope=False)
repls['roles'] = ','.join(['"%s"' % r.name for r in specificRoles])
- globalRoles = self.getAllUsedRoles(plone=False, local=False)
+ globalRoles = self.getAllUsedRoles(zope=False, local=False)
repls['gRoles'] = ','.join(['"%s"' % r.name for r in globalRoles])
grantableRoles = self.getAllUsedRoles(local=False, grantable=True)
repls['grRoles'] = ','.join(['"%s"' % r.name for r in grantableRoles])
@@ -780,7 +768,7 @@ class ZopeGenerator(Generator):
self.copyFile('testAll.py', repls, destFolder='tests')
def generateTool(self):
- '''Generates the Plone tool that corresponds to this application.'''
+ '''Generates the tool that corresponds to this application.'''
Msg = PoMessage
# Create Tool-related i18n-related messages
msg = Msg(self.tool.name, '', Msg.CONFIG % self.applicationName)
@@ -874,7 +862,7 @@ class ZopeGenerator(Generator):
poMsg.produceNiceDefault()
if poMsg not in self.labels:
self.labels.append(poMsg)
- # Generate the resulting Archetypes class.
+ # Generate the resulting Zope class.
self.copyFile('Class.py', repls, destName=fileName)
def generateWorkflow(self, wfDescr):
@@ -886,14 +874,14 @@ class ZopeGenerator(Generator):
wfName = WorkflowDescriptor.getWorkflowName(wfDescr.klass)
# Add i18n messages for states
for name in dir(wfDescr.klass):
- if not isinstance(getattr(wfDescr.klass, name), State): continue
+ if not isinstance(getattr(wfDescr.klass, name), gen.State): continue
poMsg = PoMessage('%s_%s' % (wfName, name), '', name)
poMsg.produceNiceDefault()
self.labels.append(poMsg)
# Add i18n messages for transitions
for name in dir(wfDescr.klass):
transition = getattr(wfDescr.klass, name)
- if not isinstance(transition, Transition): continue
+ if not isinstance(transition, gen.Transition): continue
poMsg = PoMessage('%s_%s' % (wfName, name), '', name)
poMsg.produceNiceDefault()
self.labels.append(poMsg)
diff --git a/gen/installer.py b/gen/installer.py
index 3ade52e..d32db31 100644
--- a/gen/installer.py
+++ b/gen/installer.py
@@ -5,7 +5,7 @@
import os, os.path, time
import appy
import appy.version
-from appy.gen import Type, Ref, String, File
+import appy.gen as gen
from appy.gen.po import PoParser
from appy.gen.utils import updateRolesForPermission, createObject
from appy.shared.data import languages
@@ -110,7 +110,7 @@ class ZopeInstaller:
for name in files:
baseName, ext = os.path.splitext(name)
f = file(j(root, name))
- if ext in File.imageExts:
+ if ext in gen.File.imageExts:
zopeFolder.manage_addImage(name, f)
elif ext == '.pt':
manage_addPageTemplate(zopeFolder, baseName, '', f.read())
@@ -302,13 +302,11 @@ class ZopeInstaller:
# "po" file on disk.
appFolder = self.config.diskFolder
appName = self.config.PROJECTNAME
- dn = os.path.dirname
- jn = os.path.join
- i18nFolder = jn(jn(jn(dn(dn(dn(appFolder))),'Products'),appName),'i18n')
+ i18nFolder = os.path.join(appFolder, 'tr')
for translation in appyTool.translations:
# Get the "po" file
poName = '%s-%s.po' % (appName, translation.id)
- poFile = PoParser(jn(i18nFolder, poName)).parse()
+ poFile = PoParser(os.path.join(i18nFolder, poName)).parse()
for message in poFile.messages:
setattr(translation, message.id, message.getMessage())
appyTool.log('Translation "%s" updated from "%s".' % \
@@ -359,7 +357,7 @@ class ZopeInstaller:
wrapperClass = klass.wrapperClass
if not hasattr(wrapperClass, 'title'):
# Special field "type" is mandatory for every class.
- title = String(multiplicity=(1,1), show='edit', indexed=True)
+ title = gen.String(multiplicity=(1,1), show='edit',indexed=True)
title.init('title', None, 'appy')
setattr(wrapperClass, 'title', title)
names = self.config.attributes[wrapperClass.__name__[:-8]]
@@ -368,8 +366,8 @@ class ZopeInstaller:
for baseClass in klass.wrapperClass.__bases__:
if baseClass.__name__ == 'AbstractWrapper': continue
for name, appyType in baseClass.__dict__.iteritems():
- if not isinstance(appyType, Type) or \
- (isinstance(appyType, Ref) and appyType.isBack):
+ if not isinstance(appyType, gen.Type) or \
+ (isinstance(appyType, gen.Ref) and appyType.isBack):
continue # Back refs are initialised within fw refs
appyType.init(name, baseClass, appName)
diff --git a/gen/migrator.py b/gen/migrator.py
index a3db7b1..29d8386 100644
--- a/gen/migrator.py
+++ b/gen/migrator.py
@@ -9,8 +9,7 @@ class Migrator:
self.installer = installer
def migrateTo_0_7_1(self):
- '''Appy 0.7.1 has its own management of Ref fields and does not use
- Archetypes references and the reference catalog anymore. So we must
+ '''Appy 0.7.1 has its own management of Ref fields. So we must
update data structures that store Ref info on instances.'''
ins = self.installer
ins.info('Migrating to Appy 0.7.1...')
diff --git a/gen/mixins/TestMixin.py b/gen/mixins/TestMixin.py
index c46337e..cafc4a7 100644
--- a/gen/mixins/TestMixin.py
+++ b/gen/mixins/TestMixin.py
@@ -3,7 +3,7 @@ import os, os.path, sys
# ------------------------------------------------------------------------------
class TestMixin:
- '''This class is mixed in with any PloneTestCase.'''
+ '''This class is mixed in with any ZopeTestCase.'''
def createUser(self, userId, roles):
'''Creates a user with id p_userId with some p_roles.'''
self.acl_users.addMember(userId, 'password', [], [])
@@ -59,7 +59,7 @@ class TestMixin:
def beforeTest(test):
'''Is executed before every test.'''
g = test.globs
- g['tool'] = test.app.plone.get('portal_%s' % g['appName'].lower()).appy()
+ g['tool'] = test.app.config.appy()
cfg = g['tool'].o.getProductConfig()
g['appFolder'] = cfg.diskFolder
moduleOrClassName = g['test'].name # Not used yet.
diff --git a/gen/mixins/ToolMixin.py b/gen/mixins/ToolMixin.py
index 5d6f73e..86cef2a 100644
--- a/gen/mixins/ToolMixin.py
+++ b/gen/mixins/ToolMixin.py
@@ -6,9 +6,9 @@ from appy.shared.data import languages
import appy.gen
from appy.gen import Type, Search, Selection
from appy.gen.utils import SomeObjects, sequenceTypes, getClassName
-from appy.gen.plone25.mixins import BaseMixin
-from appy.gen.plone25.wrappers import AbstractWrapper
-from appy.gen.plone25.descriptors import ClassDescriptor
+from appy.gen.mixins import BaseMixin
+from appy.gen.wrappers import AbstractWrapper
+from appy.gen.descriptors import ClassDescriptor
try:
from AccessControl.ZopeSecurityPolicy import _noroles
except ImportError:
@@ -411,7 +411,7 @@ class ToolMixin(BaseMixin):
def getCreateMeans(self, contentTypeOrAppyClass):
'''Gets the different ways objects of p_contentTypeOrAppyClass (which
- can be a Plone content type or a Appy class) can be created
+ can be a Zope content type or a Appy class) can be created
(via a web form, by importing external data, etc). Result is a
dict whose keys are strings (ie "form", "import"...) and whose
values are additional data bout the particular mean.'''
@@ -810,7 +810,7 @@ class ToolMixin(BaseMixin):
9: 'month_sep', 10: 'month_oct', 11: 'month_nov', 12: 'month_dec'}
def getMonthName(self, monthNumber):
'''Gets the translated month name of month numbered p_monthNumber.'''
- return self.translate(self.monthsIds[int(monthNumber)], domain='plone')
+ return self.translate(self.monthsIds[int(monthNumber)])
# --------------------------------------------------------------------------
# Authentication-related methods
@@ -824,7 +824,7 @@ class ToolMixin(BaseMixin):
if jsEnabled and not cookiesEnabled:
msg = self.translate(u'You must enable cookies before you can ' \
- 'log in.', domain='plone')
+ 'log in.')
return self.goto(urlBack, msg.encode('utf-8'))
# Perform the Zope-level authentication
login = rq.get('__ac_name', '')
@@ -835,11 +835,10 @@ class ToolMixin(BaseMixin):
user = self.acl_users.validate(rq)
if self.userIsAnon():
rq.RESPONSE.expireCookie('__ac', path='/')
- msg = self.translate(u'Login failed', domain='plone')
+ msg = self.translate(u'Login failed')
logMsg = 'Authentication failed (tried with login "%s")' % login
else:
- msg = self.translate(u'Welcome! You are now logged in.',
- domain='plone')
+ msg = self.translate(u'Welcome! You are now logged in.')
logMsg = 'User "%s" has been logged in.' % login
msg = msg.encode('utf-8')
self.log(logMsg)
@@ -865,7 +864,7 @@ class ToolMixin(BaseMixin):
session.invalidate()
self.log('User "%s" has been logged out.' % userId)
# Remove user from variable "loggedUsers"
- from appy.gen.plone25.installer import loggedUsers
+ from appy.gen.installer import loggedUsers
if loggedUsers.has_key(userId): del loggedUsers[userId]
return self.goto(self.getApp().absolute_url())
diff --git a/gen/mixins/__init__.py b/gen/mixins/__init__.py
index e1528b2..9dbee23 100644
--- a/gen/mixins/__init__.py
+++ b/gen/mixins/__init__.py
@@ -1,17 +1,14 @@
'''This package contains mixin classes that are mixed in with generated classes:
- - mixins/BaseMixin is mixed in with Standard Archetypes classes;
+ - mixins/BaseMixin is mixed in with standard Zope classes;
- mixins/ToolMixin is mixed in with the generated application Tool class.'''
# ------------------------------------------------------------------------------
import os, os.path, sys, types, mimetypes, urllib, cgi
from appy import Object
-import appy.gen
-from appy.gen import Type, String, Selection, Role, No, WorkflowAnonymous, \
- Transition, Permission
+import appy.gen as gen
from appy.gen.utils import *
from appy.gen.layout import Table, defaultPageLayouts
-from appy.gen.descriptors import WorkflowDescriptor
-from appy.gen.plone25.descriptors import ClassDescriptor
+from appy.gen.descriptors import WorkflowDescriptor, ClassDescriptor
# ------------------------------------------------------------------------------
class BaseMixin:
@@ -187,8 +184,7 @@ class BaseMixin:
fields in the database.'''
rq = self.REQUEST
tool = self.getTool()
- errorMessage = self.translate(
- 'Please correct the indicated errors.', domain='plone')
+ errorMessage = self.translate('Please correct the indicated errors.')
isNew = rq.get('is_new') == 'True'
# If this object is created from an initiator, get info about him.
initiator = None
@@ -209,7 +205,7 @@ class BaseMixin:
urlBack = tool.getSiteUrl()
else:
urlBack = self.getUrl()
- self.say(self.translate('Changes canceled.', domain='plone'))
+ self.say(self.translate('Changes canceled.'))
return self.goto(urlBack)
# Object for storing validation errors
@@ -245,7 +241,7 @@ class BaseMixin:
obj, msg = self.createOrUpdate(isNew, values, initiator, initiatorField)
# Redirect the user to the appropriate page
- if not msg: msg = obj.translate('Changes saved.', domain='plone')
+ if not msg: msg = obj.translate('Changes saved.')
# If the object has already been deleted (ie, it is a kind of transient
# object like a one-shot form and has already been deleted in method
# onEdit), redirect to the main site page.
@@ -711,7 +707,7 @@ class BaseMixin:
if not includeFake:
includeIt = mayTrigger
else:
- includeIt = mayTrigger or isinstance(mayTrigger, No)
+ includeIt = mayTrigger or isinstance(mayTrigger, gen.No)
if not includeNotShowable:
includeIt = includeIt and transition.isShowable(wf, self)
if not includeIt: continue
@@ -864,7 +860,7 @@ class BaseMixin:
# Get the initial workflow state
initialState = self.State(name=False)
# Create a Transition instance representing the initial transition.
- initialTransition = Transition((initialState, initialState))
+ initialTransition = gen.Transition((initialState, initialState))
initialTransition.trigger('_init_', self, wf, '')
def getWorkflow(self, name=False, className=None):
@@ -875,7 +871,7 @@ class BaseMixin:
else:
appyClass = self.getTool().getAppyClass(className)
if hasattr(appyClass, 'workflow'): wf = appyClass.workflow
- else: wf = WorkflowAnonymous
+ else: wf = gen.WorkflowAnonymous
if not name: return wf
return WorkflowDescriptor.getWorkflowName(wf)
diff --git a/gen/model.py b/gen/model.py
index a42045c..0fafbc6 100644
--- a/gen/model.py
+++ b/gen/model.py
@@ -1,14 +1,10 @@
'''This file contains basic classes that will be added into any user
application for creating the basic structure of the application "Tool" which
- is the set of web pages used for configuring the application. The "Tool" is
- available to administrators under the standard Plone link "site setup". Plone
- itself is shipped with several tools used for conguring the various parts of
- Plone (content types, catalogs, workflows, etc.)'''
+ is the set of web pages used for configuring the application.'''
# ------------------------------------------------------------------------------
import types
-from appy.gen import *
-Grp=Group # Avoid name clash between appy.gen.Group and class Group below
+import appy.gen as gen
# Prototypical instances of every type -----------------------------------------
class Protos:
@@ -73,7 +69,7 @@ class ModelClass:
value = appyType.getInputLayouts()
elif isinstance(value, basestring):
value = '"%s"' % value
- elif isinstance(value, Ref):
+ elif isinstance(value, gen.Ref):
if not value.isBack: continue
value = klass._appy_getTypeBody(value, wrapperName)
elif type(value) == type(ModelClass):
@@ -82,11 +78,11 @@ class ModelClass:
value = value.__name__
else:
value = '%s.%s' % (moduleName, value.__name__)
- elif isinstance(value, Selection):
+ elif isinstance(value, gen.Selection):
value = 'Selection("%s")' % value.methodName
- elif isinstance(value, Grp):
+ elif isinstance(value, gen.Group):
value = 'Grp("%s")' % value.name
- elif isinstance(value, Page):
+ elif isinstance(value, gen.Page):
value = 'pages["%s"]' % value.name
elif callable(value):
value = '%s.%s' % (wrapperName, value.__name__)
@@ -135,20 +131,22 @@ class User(ModelClass):
_appy_attributes = ['title', 'name', 'firstName', 'login', 'password1',
'password2', 'roles']
# All methods defined below are fake. Real versions are in the wrapper.
- title = String(show=False, indexed=True)
+ title = gen.String(show=False, indexed=True)
gm = {'group': 'main', 'multiplicity': (1,1), 'width': 25}
- name = String(**gm)
- firstName = String(**gm)
+ name = gen.String(**gm)
+ firstName = gen.String(**gm)
def showLogin(self): pass
def validateLogin(self): pass
- login = String(show=showLogin, validator=validateLogin, indexed=True, **gm)
+ login = gen.String(show=showLogin, validator=validateLogin,
+ indexed=True, **gm)
def showPassword(self): pass
def validatePassword(self): pass
- password1 = String(format=String.PASSWORD, show=showPassword,
- validator=validatePassword, **gm)
- password2 = String(format=String.PASSWORD, show=showPassword, **gm)
+ password1 = gen.String(format=gen.String.PASSWORD, show=showPassword,
+ validator=validatePassword, **gm)
+ password2 = gen.String(format=gen.String.PASSWORD, show=showPassword, **gm)
gm['multiplicity'] = (0, None)
- roles = String(validator=Selection('getGrantableRoles'), indexed=True, **gm)
+ roles = gen.String(validator=gen.Selection('getGrantableRoles'),
+ indexed=True, **gm)
# The Group class --------------------------------------------------------------
class Group(ModelClass):
@@ -156,25 +154,25 @@ class Group(ModelClass):
_appy_attributes = ['title', 'login', 'roles', 'users']
# All methods defined below are fake. Real versions are in the wrapper.
m = {'group': 'main', 'width': 25, 'indexed': True}
- title = String(multiplicity=(1,1), **m)
+ title = gen.String(multiplicity=(1,1), **m)
def showLogin(self): pass
def validateLogin(self): pass
- login = String(show=showLogin, validator=validateLogin,
- multiplicity=(1,1), **m)
- roles = String(validator=Selection('getGrantableRoles'),
- multiplicity=(0,None), **m)
- users = Ref(User, multiplicity=(0,None), add=False, link=True,
- back=Ref(attribute='groups', show=True),
- showHeaders=True, shownInfo=('title', 'login'))
+ login = gen.String(show=showLogin, validator=validateLogin,
+ multiplicity=(1,1), **m)
+ roles = gen.String(validator=gen.Selection('getGrantableRoles'),
+ multiplicity=(0,None), **m)
+ users = gen.Ref(User, multiplicity=(0,None), add=False, link=True,
+ back=gen.Ref(attribute='groups', show=True),
+ showHeaders=True, shownInfo=('title', 'login'))
# The Translation class --------------------------------------------------------
class Translation(ModelClass):
_appy_attributes = ['po', 'title']
# All methods defined below are fake. Real versions are in the wrapper.
def getPoFile(self): pass
- po = Action(action=getPoFile, page=Page('actions', show='view'),
- result='filetmp')
- title = String(show=False, indexed=True)
+ po = gen.Action(action=getPoFile, page=gen.Page('actions', show='view'),
+ result='filetmp')
+ title = gen.String(show=False, indexed=True)
def label(self): pass
def show(self, name): pass
@@ -195,30 +193,31 @@ class Tool(ModelClass):
# Tool attributes
def validPythonWithUno(self, value): pass # Real method in the wrapper
- unoEnabledPython = String(group="connectionToOpenOffice",
- validator=validPythonWithUno)
- openOfficePort = Integer(default=2002, group="connectionToOpenOffice")
- numberOfResultsPerPage = Integer(default=30, show=False)
- listBoxesMaximumWidth = Integer(default=100, show=False)
- appyVersion = String(show=False, layouts='f')
+ unoEnabledPython = gen.String(group="connectionToOpenOffice",
+ validator=validPythonWithUno)
+ openOfficePort = gen.Integer(default=2002, group="connectionToOpenOffice")
+ numberOfResultsPerPage = gen.Integer(default=30, show=False)
+ listBoxesMaximumWidth = gen.Integer(default=100, show=False)
+ appyVersion = gen.String(show=False, layouts='f')
def refreshSecurity(self): pass # Real method in the wrapper
- refreshSecurity = Action(action=refreshSecurity, confirm=True)
+ refreshSecurity = gen.Action(action=refreshSecurity, confirm=True)
# Ref(User) will maybe be transformed into Ref(CustomUserClass).
- users = Ref(User, multiplicity=(0,None), add=True, link=False,
- back=Ref(attribute='toTool', show=False),
- page=Page('users', show='view'),
- queryable=True, queryFields=('title', 'login'),
- showHeaders=True, shownInfo=('title', 'login', 'roles'))
- groups = Ref(Group, multiplicity=(0,None), add=True, link=False,
- back=Ref(attribute='toTool2', show=False),
- page=Page('groups', show='view'),
- queryable=True, queryFields=('title', 'login'),
- showHeaders=True, shownInfo=('title', 'login', 'roles'))
- translations = Ref(Translation, multiplicity=(0,None),add=False,link=False,
- back=Ref(attribute='trToTool', show=False), show='view',
- page=Page('translations', show='view'))
- enableNotifications = Boolean(default=True,
- page=Page('notifications', show=False))
+ users = gen.Ref(User, multiplicity=(0,None), add=True, link=False,
+ back=gen.Ref(attribute='toTool', show=False),
+ page=gen.Page('users', show='view'),
+ queryable=True, queryFields=('title', 'login'),
+ showHeaders=True, shownInfo=('title', 'login', 'roles'))
+ groups = gen.Ref(Group, multiplicity=(0,None), add=True, link=False,
+ back=gen.Ref(attribute='toTool2', show=False),
+ page=gen.Page('groups', show='view'),
+ queryable=True, queryFields=('title', 'login'),
+ showHeaders=True, shownInfo=('title', 'login', 'roles'))
+ translations = gen.Ref(Translation, multiplicity=(0,None), add=False,
+ link=False, show='view',
+ back=gen.Ref(attribute='trToTool', show=False),
+ page=gen.Page('translations', show='view'))
+ enableNotifications = gen.Boolean(default=True,
+ page=gen.Page('notifications', show=False))
@classmethod
def _appy_clean(klass):
diff --git a/gen/notifier.py b/gen/notifier.py
index f5e2990..cdc273f 100644
--- a/gen/notifier.py
+++ b/gen/notifier.py
@@ -41,8 +41,8 @@ def sendMail(obj, transition, transitionName, workflow):
'''Sends mail about p_transition that has been triggered on p_obj that is
controlled by p_workflow.'''
wfName = WorkflowDescriptor.getWorkflowName(workflow.__class__)
- ploneObj = obj.o
- portal = ploneObj.portal_url.getPortalObject()
+ zopeObj = obj.o
+ tool = zopeObj.getTool()
mailInfo = transition.notify(workflow, obj)
if not mailInfo[0]: return # Send a mail to nobody.
# mailInfo may be one of the following:
@@ -54,15 +54,15 @@ def sendMail(obj, transition, transitionName, workflow):
# address or one role) or sequences of strings.
# Determine mail subject and body.
if len(mailInfo) <= 2:
- # The user didn't mention mail body and subject. We will use
- # those defined from i18n labels.
- wfHistory = ploneObj.getWorkflowHistory()
+ # The user didn't mention mail body and subject. We will use those
+ # defined from i18n labels.
+ wfHistory = zopeObj.getHistory()
labelPrefix = '%s_%s' % (wfName, transitionName)
tName = obj.translate(labelPrefix)
- keys = {'siteUrl': portal.absolute_url(),
- 'siteTitle': portal.Title(),
- 'objectUrl': ploneObj.absolute_url(),
- 'objectTitle': ploneObj.Title(),
+ keys = {'siteUrl': tool.getPath('/').absolute_url(),
+ 'siteTitle': tool.getAppName(),
+ 'objectUrl': zopeObj.absolute_url(),
+ 'objectTitle': zopeObj.Title(),
'transitionName': tName,
'transitionComment': wfHistory[0]['comments']}
mailSubject = obj.translate(labelPrefix + '_mail_subject', keys)
diff --git a/gen/odt/__init__.py b/gen/odt/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/gen/odt/generator.py b/gen/odt/generator.py
deleted file mode 100644
index b4b4d89..0000000
--- a/gen/odt/generator.py
+++ /dev/null
@@ -1,54 +0,0 @@
-'''This file contains the main Generator class used for generating an
- ODT file from an Appy application.'''
-
-# ------------------------------------------------------------------------------
-import os, os.path
-from appy.gen import Page
-from appy.gen.utils import produceNiceMessage
-from appy.gen.generator import Generator as AbstractGenerator
-
-# ------------------------------------------------------------------------------
-class Generator(AbstractGenerator):
- '''This generator generates ODT files from an Appy application.'''
-
- def __init__(self, *args, **kwargs):
- AbstractGenerator.__init__(self, *args, **kwargs)
- self.repls = {'generator': self}
-
- def finalize(self):
- pass
-
- def getOdtFieldLabel(self, fieldName):
- '''Given a p_fieldName, this method creates the label as it will appear
- in the ODT file.'''
- return '%s' % \
- (fieldName, produceNiceMessage(fieldName))
-
- def generateClass(self, classDescr):
- '''Is called each time an Appy class is found in the application.'''
- repls = self.repls.copy()
- repls['classDescr'] = classDescr
- self.copyFile('basic.odt', repls,
- destName='%sEdit.odt' % classDescr.klass.__name__, isPod=True)
-
- def fieldIsStaticallyInvisible(self, field):
- '''This method determines if p_field is always invisible. It can be
- verified for example if field.type.show is the boolean value False or
- if the page where the field must be displayed has a boolean attribute
- "show" having the boolean value False.'''
- if (type(field.show) == bool) and not field.show: return True
- if (type(field.page.show) == bool) and not field.page.show: return True
- return False
-
- undumpable = ('Ref', 'Action', 'File', 'Computed')
- def getRelevantAttributes(self, classDescr):
- '''Some fields, like computed fields or actions, should not be dumped
- into the ODT file. This method returns the list of "dumpable"
- fields.'''
- res = []
- for fieldName, field, klass in classDescr.getOrderedAppyAttributes():
- if (field.type not in self.undumpable) and \
- (not self.fieldIsStaticallyInvisible(field)):
- res.append((fieldName, field))
- return res
-# ------------------------------------------------------------------------------
diff --git a/gen/odt/templates/basic.odt b/gen/odt/templates/basic.odt
deleted file mode 100644
index 7f3816a3b8ddb3cc478342b58de608603fc1be79..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 10487
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
diff --git a/gen/plone25/__init__.py b/gen/plone25/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/gen/templates/Class.py b/gen/templates/Class.py
index 2ec361c..38dec98 100644
--- a/gen/templates/Class.py
+++ b/gen/templates/Class.py
@@ -4,8 +4,8 @@ from OFS.Folder import Folder
from appy.gen.utils import createObject
from AccessControl import ClassSecurityInfo
import Products..config as cfg
-from appy.gen.plone25.mixins import BaseMixin
-from appy.gen.plone25.mixins.ToolMixin import ToolMixin
+from appy.gen.mixins import BaseMixin
+from appy.gen.mixins.ToolMixin import ToolMixin
from wrappers import _Wrapper as Wrapper
def manage_add(self, id, title='', REQUEST=None):
diff --git a/gen/templates/Styles.css.dtml b/gen/templates/Styles.css.dtml
deleted file mode 100644
index 70f4dd9..0000000
--- a/gen/templates/Styles.css.dtml
+++ /dev/null
@@ -1,90 +0,0 @@
-#importedElem { color: grey; font-style: italic; }
-.appyPod { float:right; }
-.appyFocus { color: #900101; }
-
-.appyChanges th {
- font-style: italic;
- background-color: transparent;
- border: 0 none transparent;
- padding: 0.1em 0.1em 0.1em 0.1em;
-}
-
-.appyChanges td {
- padding: 0.1em 0.2em 0.1em 0.2em !important;
- border-top: 1px dashed #8CACBB !important;
- border-right: 0 none transparent !important;
- border-left: 0 none transparent !important;
- border-bottom: 0 none transparent !important;
-}
-
-/* Tooltip */
-a.tooltip span {
- display:none;
- padding:2px 3px;
- margin-top: 25px;
-}
-a.rtip span { margin-left:3px; }
-a.ltip span { margin-left:-150px }
-a.tooltip:hover span {
- display: inline;
- position: absolute;
- border: 1px solid grey;
- background-color: white;
- color: #dd;
-}
-
-/* Table styles */
-fieldset {
- line-height: 1em;
- border: 2px solid #8CACBB;
- margin: 0.5em 0em 0.5em 0em;
- padding: 0 0.7em 0.5em;
-}
-
-.noPadding {
- padding-right: 0em !important;
- padding-left: 0em !important;
- padding-top: 0em !important;
- padding-bottom: 0em !important;
-}
-
-.appyButton {
- background: &dtml-globalBackgroundColor; url(&dtml-portal_url;/linkOpaque.gif) 5px 1px no-repeat;
- cursor: pointer;
- font-size: &dtml-fontSmallSize;;
- padding: 1px 1px 1px 12px;
- text-transform: &dtml-textTransform;;
- /* overflow: visible; IE produces ugly results with this */
-}
-
-.fakeButton {
- background: #ffd5c0 url(&dtml-portal_url;/ui/fakeTransition.gif) 5px 1px no-repeat;
- padding: 3px 4px 3px 12px;
-}
-
-/* Portlet elements */
-.portletHeader {
- text-transform: none;
- padding: 1px 0.5em;
-}
-.portletSearch {
- padding: 0 0 0 0.6em;
- font-style: normal;
- font-size: 95%;
-}
-.portletGroup {
- font-variant: small-caps;
- font-weight: bold;
- font-style: normal;
-}
-
-.portletGroupItem { padding-left: 0.8em; font-style: italic; }
-.portletMenu { margin-bottom: 0.4em; }
-
-/* image-right, but without border */
-.image-right {
- border:0px solid Black;
- clear:both;
- float:right;
- margin:0.5em;
-}
diff --git a/gen/templates/__init__.py b/gen/templates/__init__.py
index 4d20f53..3452a0f 100644
--- a/gen/templates/__init__.py
+++ b/gen/templates/__init__.py
@@ -1,7 +1,7 @@
# Test coverage-related stuff --------------------------------------------------
import sys
-from appy.gen.plone25.mixins.TestMixin import TestMixin
+from appy.gen.mixins.TestMixin import TestMixin
covFolder = TestMixin.getCovFolder()
# The previous method checks in sys.argv whether Zope was lauched for performing
# coverage tests or not.
@@ -26,7 +26,7 @@ def countTest():
# ------------------------------------------------------------------------------
import config
-from appy.gen.plone25.installer import ZopeInstaller
+from appy.gen.installer import ZopeInstaller
# Zope-level installation of the generated product. ----------------------------
def initialize(context):
diff --git a/gen/templates/config.py b/gen/templates/config.py
index 4d56cc9..b640024 100644
--- a/gen/templates/config.py
+++ b/gen/templates/config.py
@@ -5,9 +5,7 @@ import wrappers
# The following imports are here for allowing mixin classes to access those
-# elements without being statically dependent on Plone/Zope packages. Indeed,
-# every Archetype instance has a method "getProductConfig" that returns this
-# module.
+# elements without being statically dependent on Zope packages.
from persistent.list import PersistentList
from zExceptions import BadRequest
from ZPublisher.HTTPRequest import BaseRequest
diff --git a/gen/templates/configure.zcml b/gen/templates/configure.zcml
deleted file mode 100644
index be6e398..0000000
--- a/gen/templates/configure.zcml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
diff --git a/gen/templates/testAll.py b/gen/templates/testAll.py
index 4edff9f..0e34d74 100644
--- a/gen/templates/testAll.py
+++ b/gen/templates/testAll.py
@@ -3,17 +3,13 @@
from unittest import TestSuite
from Testing import ZopeTestCase
from Testing.ZopeTestCase import ZopeDocTestSuite
-from Products.PloneTestCase import PloneTestCase
-from appy.gen.plone25.mixins.TestMixin import TestMixin, beforeTest, afterTest
+from appy.gen.mixins.TestMixin import TestMixin, beforeTest, afterTest
-# Initialize Zope & Plone test systems -----------------------------------------
-ZopeTestCase.installProduct('PloneLanguageTool')
+# Initialize the Zope test system ----------------------------------------------
ZopeTestCase.installProduct('')
-PloneTestCase.setupPloneSite(products=['PloneLanguageTool',
- ''])
-class Test(PloneTestCase.PloneTestCase, TestMixin):
+class Test(ZopeTestCase.ZopeTestCase, TestMixin):
'''Base test class for test cases.'''
# Data needed for defining the tests -------------------------------------------
diff --git a/gen/templates/wrappers.py b/gen/templates/wrappers.py
index 9149b7f..92f85b7 100644
--- a/gen/templates/wrappers.py
+++ b/gen/templates/wrappers.py
@@ -1,11 +1,11 @@
# ------------------------------------------------------------------------------
from appy.gen import *
Grp = Group # Avoid name clashes with the Group class below and appy.gen.Group
-from appy.gen.plone25.wrappers import AbstractWrapper
-from appy.gen.plone25.wrappers.ToolWrapper import ToolWrapper as WTool
-from appy.gen.plone25.wrappers.UserWrapper import UserWrapper as WUser
-from appy.gen.plone25.wrappers.GroupWrapper import GroupWrapper as WGroup
-from appy.gen.plone25.wrappers.TranslationWrapper import TranslationWrapper as WT
+from appy.gen.wrappers import AbstractWrapper
+from appy.gen.wrappers.ToolWrapper import ToolWrapper as WTool
+from appy.gen.wrappers.UserWrapper import UserWrapper as WUser
+from appy.gen.wrappers.GroupWrapper import GroupWrapper as WGroup
+from appy.gen.wrappers.TranslationWrapper import TranslationWrapper as WT
from Globals import InitializeClass
from AccessControl import ClassSecurityInfo
tfw = {"edit":"f","cell":"f","view":"f"} # Layout for Translation fields
diff --git a/gen/ui/import.pt b/gen/ui/import.pt
index 500956b..6f34d2c 100644
--- a/gen/ui/import.pt
+++ b/gen/ui/import.pt
@@ -1,23 +1,9 @@
-
-
-Disable standard Plone green tabs
-
diff --git a/gen/utils.py b/gen/utils.py
index 94872fd..5389cfd 100644
--- a/gen/utils.py
+++ b/gen/utils.py
@@ -247,30 +247,30 @@ CONVERSION_ERROR = 'An error occurred while executing command "%s". %s'
class FileWrapper:
'''When you get, from an appy object, the value of a File attribute, you
get an instance of this class.'''
- def __init__(self, atFile):
+ def __init__(self, zopeFile):
'''This constructor is only used by Appy to create a nice File instance
- from a Plone/Zope corresponding instance (p_atFile). If you need to
+ from a Zope corresponding instance (p_zopeFile). If you need to
create a new file and assign it to a File attribute, use the
attribute setter, do not create yourself an instance of this
class.'''
d = self.__dict__
- d['_atFile'] = atFile # Not for you!
- d['name'] = atFile.filename
- d['content'] = atFile.data
- d['mimeType'] = atFile.content_type
- d['size'] = atFile.size # In bytes
+ d['_zopeFile'] = zopeFile # Not for you!
+ d['name'] = zopeFile.filename
+ d['content'] = zopeFile.data
+ d['mimeType'] = zopeFile.content_type
+ d['size'] = zopeFile.size # In bytes
def __setattr__(self, name, v):
d = self.__dict__
if name == 'name':
- self._atFile.filename = v
+ self._zopeFile.filename = v
d['name'] = v
elif name == 'content':
- self._atFile.update_data(v, self.mimeType, len(v))
+ self._zopeFile.update_data(v, self.mimeType, len(v))
d['content'] = v
d['size'] = len(v)
elif name == 'mimeType':
- self._atFile.content_type = self.mimeType = v
+ self._zopeFile.content_type = self.mimeType = v
else:
raise 'Impossible to set attribute %s. "Settable" attributes ' \
'are "name", "content" and "mimeType".' % name
@@ -326,8 +326,7 @@ def getClassName(klass, appName=None):
Zope class. For some classes, name p_appName is required: it is
part of the class name.'''
moduleName = klass.__module__
- if (moduleName == 'appy.gen.plone25.model') or \
- moduleName.endswith('.wrappers'):
+ if (moduleName == 'appy.gen.model') or moduleName.endswith('.wrappers'):
# This is a model (generation time or run time)
res = appName + klass.__name__
elif klass.__bases__ and (klass.__bases__[-1].__module__ == 'appy.gen'):
diff --git a/gen/wrappers/GroupWrapper.py b/gen/wrappers/GroupWrapper.py
index 32bd3f8..47c2ee7 100644
--- a/gen/wrappers/GroupWrapper.py
+++ b/gen/wrappers/GroupWrapper.py
@@ -1,5 +1,5 @@
# ------------------------------------------------------------------------------
-from appy.gen.plone25.wrappers import AbstractWrapper
+from appy.gen.wrappers import AbstractWrapper
# ------------------------------------------------------------------------------
class GroupWrapper(AbstractWrapper):
diff --git a/gen/wrappers/ToolWrapper.py b/gen/wrappers/ToolWrapper.py
index 949bab2..c240fe8 100644
--- a/gen/wrappers/ToolWrapper.py
+++ b/gen/wrappers/ToolWrapper.py
@@ -2,7 +2,7 @@
import os.path
import appy
from appy.shared.utils import executeCommand
-from appy.gen.plone25.wrappers import AbstractWrapper
+from appy.gen.wrappers import AbstractWrapper
# ------------------------------------------------------------------------------
_PY = 'Please specify a file corresponding to a Python interpreter ' \
diff --git a/gen/wrappers/TranslationWrapper.py b/gen/wrappers/TranslationWrapper.py
index 3a91233..d1ed616 100644
--- a/gen/wrappers/TranslationWrapper.py
+++ b/gen/wrappers/TranslationWrapper.py
@@ -1,6 +1,6 @@
# ------------------------------------------------------------------------------
import os.path
-from appy.gen.plone25.wrappers import AbstractWrapper
+from appy.gen.wrappers import AbstractWrapper
from appy.gen.po import PoFile, PoMessage
from appy.shared.utils import getOsTempFolder
diff --git a/gen/wrappers/UserWrapper.py b/gen/wrappers/UserWrapper.py
index 1d6c310..8c53709 100644
--- a/gen/wrappers/UserWrapper.py
+++ b/gen/wrappers/UserWrapper.py
@@ -1,5 +1,5 @@
# ------------------------------------------------------------------------------
-from appy.gen.plone25.wrappers import AbstractWrapper
+from appy.gen.wrappers import AbstractWrapper
# ------------------------------------------------------------------------------
class UserWrapper(AbstractWrapper):