This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
glasnost/shared/common/kinds.py

3895 lines
126 KiB
Python
Raw Normal View History

# -*- coding: iso-8859-15 -*-
2002-10-19 15:00:35 +02:00
# Glasnost
# By: Odile B<>nassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapi<70>s <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
2002-10-19 15:00:35 +02:00
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# C<>dric Musso <cmusso@easter-eggs.org>
# Fr<46>d<EFBFBD>ric P<>ters <fpeters@entrouvert.be>
2002-10-19 15:00:35 +02:00
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# S<>bastien R<>gnier <regnier@codelutin.com>
2002-10-19 15:00:35 +02:00
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
2003-01-06 19:49:32 +01:00
# Copyright (C) 2002 Odile B<>nassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Fr<46>d<EFBFBD>ric P<>ters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Th<54>ridion
# Copyright (C) 2003 Odile B<>nassy, Romain Chantereau, Nicolas Clapi<70>s,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, C<>dric Musso, Ouvaton, Fr<46>d<EFBFBD>ric P<>ters,
# Benjamin Poussin, Rodolphe Qui<75>deville, Emmanuel Raviart, S<>bastien
# R<>gnier, Emmanuel Saracco, Th<54>ridion & Vecam
2002-10-19 15:00:35 +02:00
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2003-03-21 17:01:04 +01:00
from __future__ import nested_scopes
2002-10-19 15:00:35 +02:00
__doc__ = """Glasnost Common Kinds"""
__version__ = '$Revision$'[11:-2]
2002-10-19 15:00:35 +02:00
import base64
import copy
import cStringIO
2002-10-19 15:00:35 +02:00
import locale
2003-05-29 17:46:46 +02:00
import marshal
import re
import string
import sys
import time
import traceback
2002-10-19 15:00:35 +02:00
import types
import jails
2002-10-19 15:00:35 +02:00
import slots
import translation
import things
import system
2002-10-19 15:00:35 +02:00
from tools import *
import tools_new as commonTools
2002-10-19 15:00:35 +02:00
## import connectors # Do not remove!
import functions # Do not remove!
import modes # Do not remove!
import properties # Do not remove!
import uploads # Do not remove!
import values # Do not remove!
import widgets # Do not remove!
2002-10-19 15:00:35 +02:00
register = things.register
class BaseKind(things.BaseThing):
balloonHelp = None
class balloonHelp_kindClass:
_kindName = 'String'
label = N_('Balloon Help')
stateInViewMode = 'read-only/hidden-if-empty'
widget_rows = 4
widgetName = 'TextArea'
containerNames = None
class containerNames_kindClass:
_kindName = 'Sequence'
importExport = 'private'
itemKind_valueName = 'KindName'
label = N_('Containers')
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
defaultValue = None
defaultValue_kind_importExport = 'private'
defaultValue_kind_label = N_('Default Value')
defaultValue_kind_stateInEditMode = 'hidden'
defaultValue_kind_stateInViewMode = 'hidden'
defaultValue_kindName = None # To override
2003-08-11 17:05:58 +02:00
## helpAlias = None
## class helpAlias_kindClass:
## _kindName = 'Alias'
## label = N_('Help Alias')
getter = None
importExport = 'public'
class importExport_kindClass:
_kindName = 'Choice'
importExport = 'private'
isRequired = 1
label = N_('Protection')
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
labels = {
'from-server-only': N_('Read Only'),
'private': N_('Private'),
'public': N_('Read/Write'),
'to-server-only': N_('Write Only'),
}
values = [
'private',
'to-server-only',
'from-server-only',
'public',
]
isAutomaticallyModified = 0
class isAutomaticallyModified_kindClass:
_kindName = 'Boolean'
importExport = 'private'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
# When isModifiable is false, the slot can only be set once and not
# modified.
isModifiable = 1
class isModifiable_kindClass:
_kindName = 'Boolean'
importExport = 'private'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
# When false, isPractical means that the kind can not be used to describe
# a real value, but only to describe an expected value.
isPractical = 1
class isPractical_kindClass:
_kindName = 'Boolean'
importExport = 'private'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
2002-10-19 15:00:35 +02:00
isRequired = 0
class isRequired_kindClass:
_kindName = 'Boolean'
label = N_('Mandatory')
## labels = {
## '0': N_('Optional'),
## '1': N_('Required'),
## }
2002-10-19 15:00:35 +02:00
isRequiredInEditMode = 0
class isRequiredInEditMode_kindClass:
_kindName = 'Boolean'
importExport = 'private'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
2002-10-19 15:00:35 +02:00
isTranslatable = 0
class isTranslatable_kindClass:
_kindName = 'Boolean'
importExport = 'private'
label = N_('Translatable')
## labels = {
## '0': N_('Invariant'),
## '1': N_('Translatable'),
## }
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
2002-10-19 15:00:35 +02:00
label = None
class label_kindClass:
_kindName = 'String'
balloonHelp = N_('Enter a user-friendly field name')
label = N_('Field Label')
stateInViewMode = 'read-only/hidden-if-empty'
labelPlural = None
class labelPlural_kindClass:
_kindName = 'String'
importExport = 'private'
label = N_('Label (plural form)')
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
possibleWidgetNames = None
class possibleWidgetNames_kindClass:
_kindName = 'Sequence'
importExport = 'private'
itemKind_valueName = 'WidgetName'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
pythonStorageType = None
# not defined as a kind since it would require a new kind PythonType that
# would only be useful here.
stateInCreateMode = None
class stateInCreateMode_kindClass:
_kindName = 'Choice'
importExport = 'private'
label = N_('Creation Mode')
labels = {
'': N_('Same As Edition Mode'),
'hidden': N_('Hidden'),
'read-only': N_('Read Only'),
'read-only/hidden-if-empty': N_('Read Only / Hidden If Empty'),
'read-write': N_('Read/Write'),
}
sortLabels = 0
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
values = [
None,
'hidden',
'read-only/hidden-if-empty',
'read-only',
'read-write',
]
stateInEditMode = 'read-write'
class stateInEditMode_kindClass:
_kindName = 'Choice'
importExport = 'private'
isRequired = 1
label = N_('Edition Mode')
labels = {
'hidden': N_('Hidden'),
'read-only': N_('Read Only'),
'read-only/hidden-if-empty': N_('Read Only / Hidden If Empty'),
'read-write': N_('Read/Write'),
}
sortLabels = 0
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
values = [
'hidden',
'read-only/hidden-if-empty',
'read-only',
'read-write',
]
stateInViewMode = 'read-only/hidden-if-empty'
class stateInViewMode_kindClass:
_kindName = 'Choice'
importExport = 'private'
isRequired = 1
label = N_('View Mode')
labels = {
'hidden': N_('Hidden'),
'read-only': N_('Read Only'),
'read-only/hidden-if-empty': N_('Read Only / Hidden If Empty'),
}
sortLabels = 0
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
values = [
'hidden',
'read-only/hidden-if-empty',
'read-only',
]
tagInCreateMode = None
class tagInCreateMode_kindClass:
_kindName = 'Choice'
importExport = 'private'
label = N_('Creation Aspect')
labels = {
'': N_('Same As Edition Aspect'),
'div': N_('Standard Without Label'),
'div-with-label': N_('Standard With Label'),
'h1': N_('Header 1'),
'h2': N_('Header 2'),
'h3': N_('Header 3'),
'h4': N_('Header 4'),
'h5': N_('Header 5'),
'h6': N_('Header 6'),
}
sortLabels = 0
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
values = [
None,
'div-with-label',
'div',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
]
tagInEditMode = 'div-with-label'
class tagInEditMode_kindClass:
_kindName = 'Choice'
importExport = 'private'
isRequired = 1
label = N_('Edition Aspect')
labels = {
'div': N_('Standard Without Label'),
'div-with-label': N_('Standard With Label'),
'h1': N_('Header 1'),
'h2': N_('Header 2'),
'h3': N_('Header 3'),
'h4': N_('Header 4'),
'h5': N_('Header 5'),
'h6': N_('Header 6'),
}
sortLabels = 0
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
values = [
'div-with-label',
'div',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
]
tagInViewMode = 'div-with-label'
class tagInViewMode_kindClass:
_kindName = 'Choice'
importExport = 'private'
isRequired = 1
label = N_('View Aspect')
labels = {
'div': N_('Standard Without Label'),
'div-with-label': N_('Standard With Label'),
'h1': N_('Header 1'),
'h2': N_('Header 2'),
'h3': N_('Header 3'),
'h4': N_('Header 4'),
'h5': N_('Header 5'),
'h6': N_('Header 6'),
}
sortLabels = 0
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
values = [
'div-with-label',
'div',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
]
textFormat = None
class textFormat_kindClass:
_kindName = 'Choice'
importExport = 'private'
label = N_('Text Format')
labels = {
'': N_('Text'),
'docbook': N_('DocBook'),
'html': N_('HTML'),
'rst': N_('reStructuredText'),
'spip': N_('SPIP'),
'text': N_('Preformatted Text'),
}
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
values = [
None,
'docbook',
'html',
'rst',
'spip',
'text',
]
textMaxLength = None
class textMaxLength_kindClass:
_kindName = 'Integer'
importExport = 'private'
label = N_('Maximum Number of Characters')
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
thingCategory = 'kind'
thingPublicCategory_kind_stateInEditMode = 'read-only/hidden-if-empty'
thingPublicCategory_kind_stateInViewMode = 'read-only/hidden-if-empty'
thingPublicName_kind_label = N_('Type')
thingPublicName_kind_stateInEditMode = 'read-only/hidden-if-empty'
thingPublicName_kind_stateInViewMode = 'read-only/hidden-if-empty'
useCustomStorage = 0
class useCustomStorage_kindClass:
_kindName = 'Boolean'
importExport = 'private'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
useFileStorage = 0
class useFileStorage_kindClass:
_kindName = 'Boolean'
importExport = 'from-server-only'
label = N_('Storage')
labels = {
'0': N_('Internal'),
'1': N_('In External File'),
}
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
2002-10-19 15:00:35 +02:00
widget = None
class widget_kindClass:
_kindName = 'Widget'
isRequired = 1
label = N_('Widget')
def getGroupedValues(self, slot):
return None
def getter(self, slot):
return slot.getContainer().getModelWidget(slot.parent)
def getValues(self, slot):
values = slot.getContainer().getPossibleWidgetNames()
if values:
return values
else:
return ['InputText']
2002-10-19 15:00:35 +02:00
widgetName = 'InputText'
class widgetName_kindClass:
_kindName = 'WidgetName'
importExport = 'private'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
2002-10-19 15:00:35 +02:00
def __init__(self, **attributes):
things.BaseThing.__init__(self)
for name, value in attributes.items():
# Ensure that each argument has been declared as an attribute.
if not hasattr(self.__class__, name):
raise Exception('Undeclared attribute %s for %s' % (
name, self.__class__.__name__))
if getattr(self, name) == value:
continue
setattr(self, name, value)
def accepts(self, kind):
"""Test whether the given kind is always compatible with self.
For example:
- Integer accepts Integer.
- Number accepts Integer.
- Integer doesn't accept Number.
"""
return self.includes(kind)
def acquireNonCoreValue(self, slot, objectDirectoryPath):
pass
def buildOptions(self, options):
for name, value in options.items():
# Ensure that each option has been declared as an attribute.
nameBase = name.split('_')[0]
if not hasattr(self.__class__, nameBase):
raise Exception('Undeclared attribute %s for %s' % (
name, self.__class__.__name__))
if hasattr(self, name) and getattr(self, name) == value:
continue
setattr(self, name, value)
def checkModelValue(self, slot, value):
assert self.isPractical
if self.isRequired and value is None:
raise faults.MissingSlotValue(slot)
if value is None:
return
if type(value) is not self.pythonStorageType:
raise faults.BadSlotValue(slot, value)
def checkModelValueHolder(self, slot, valueHolder):
assert self.isPractical
if not self.accepts(valueHolder.kind):
raise faults.KindsIncompatibility(self, valueHolder.kind)
self.checkModelValue(slot, valueHolder.value)
def convertValueFromOtherType(self, value):
if value is None and self.pythonStorageType is types.StringType:
return ''
if type(value) is types.InstanceType:
raise NotImplementedError
try:
return self.pythonStorageType(value)
except:
raise 'convertValueFrom not implemented for %s' % \
repr((self, type(value)))
raise NotImplementedError
def convertValueToOtherType(self, value, otherType):
if value is None and otherType is types.StringType:
return ''
raise 'convertValueTo not implemented for %s' % \
repr((self, otherType))
raise NotImplementedError
2002-10-19 15:00:35 +02:00
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
assert self.isPractical
2002-10-19 15:00:35 +02:00
return value
def equals(self, kind):
"""Test whether two kinds are equal."""
return self.getThingName() == kind.getThingName()
def executeModel(self, slot, when, command = None):
pass
2002-10-19 15:00:35 +02:00
def exportValueToXmlRpc(self, slot, value):
assert self.isPractical
2002-10-19 15:00:35 +02:00
if type(value) in (types.StringType, types.UnicodeType):
value = utf8(value)
return value
def getBalloonHelp(self):
return self.balloonHelp
2002-10-19 15:00:35 +02:00
def getCmpFunction(self):
return cmp
def getDefaultValue(self, slot):
return self.defaultValue
def getModelFieldTag(self, slot):
layoutMode = context.getVar('layoutMode')
if layoutMode == 'edit':
isCreateEditMode = context.getVar('isCreateEditMode', default = 0)
if isCreateEditMode and self.tagInCreateMode is not None:
return self.tagInCreateMode
else:
return self.tagInEditMode
elif layoutMode == 'use':
aspect = context.getVar('aspect')
return aspect.htmlTag
else:
return self.tagInViewMode
def getModelLabel(self, slot):
if self.label:
return self.label
return slot.getLabel()
def getModelLabelPlural(self, slot):
if self.labelPlural:
return self.labelPlural
return self.getModelLabel(slot)
2002-10-19 15:00:35 +02:00
def getModelSlotByPath(self, slot, path):
if path.startswith('self'):
path = path[len('self'):]
if not path:
return slot
raise Exception('Path "%s" not found' % path)
def getModelWidget(self, slot, forceEmbedding = 0):
if self.widget is None:
widgetOptionHeader = 'widget_'
widgetOptionHeaderLen = len(widgetOptionHeader)
widgetOptionNames = [
name
for name in self.__dict__.keys()
if name.startswith(widgetOptionHeader) \
and not name.startswith(widgetOptionHeader + 'kind')]
baseClasses = self.getC3ClassLinearization()
for baseClass in baseClasses:
for name in baseClass.__dict__.keys():
if name.startswith(widgetOptionHeader) \
and not name.startswith(widgetOptionHeader + 'kind') \
and name not in widgetOptionNames:
widgetOptionNames.append(name)
widgetOptions = {}
for widgetOptionName in widgetOptionNames:
widgetOptions[widgetOptionName[widgetOptionHeaderLen:]
] = getattr(self, widgetOptionName)
widget = self.newModelWidget(slot)
widget.buildOptions(widgetOptions)
self.widget = widget
return self.widget
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = things.BaseThing.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += [
'label', 'labelPlural', 'widgetName', 'widget', 'textFormat',
'importExport',
'tagInCreateMode', 'stateInCreateMode',
'tagInEditMode', 'stateInEditMode',
'tagInViewMode', 'stateInViewMode',
'isRequired', 'defaultValue', 'balloonHelp', 'textMaxLength',
2003-08-11 17:05:58 +02:00
## 'helpAlias',
2004-05-16 19:54:28 +02:00
'useFileStorage', 'useCustomStorage']
return slotNames
def getPossibleWidgetNames(self):
assert self.isPractical
if self.possibleWidgetNames is not None:
return self.possibleWidgetNames
return [self.widgetName]
def getRealKindClass(self):
return self.__class__.__bases__[-1]
def getTextFormat(self, slot):
return self.textFormat
def getTextMaxLength(self):
return self.textMaxLength
2002-10-19 15:00:35 +02:00
def importValueFromXmlRpc(self, slot, value):
assert self.isPractical
2002-10-19 15:00:35 +02:00
if type(value) in (types.StringType, types.UnicodeType):
value = iso8859_15(value)
value = value.replace('\r\n', '\n') # MS-DOS return character
value = value.replace('\r', '\n') # MacOS return character
2002-10-19 15:00:35 +02:00
return value
def includes(self, kind):
"""Test whether the given kind is included in self.
For example:
- Integer includes Integer.
- Number includes Integer.
- Integer doesn't include Number.
"""
if self.equals(kind):
return 1
if kind.containerNames is None:
return 0
for kindContainerName in kind.containerNames:
if self.includes(commonTools.newThing(
'kind', kindContainerName)):
return 1
return 0
def intersects(self, kind):
"""Test whether the given kind has an intersection with self.
For example:
- Integer has an intersection with Integer.
- Number has an intersection with Integer.
- Integer has an intersection with Number.
"""
# To override, because the test below is incomplete.
return self.includes(kind) or kind.includes(self)
def isEmptyModelValue(self, slot, value):
return value is None
def isExportable(self):
raise NotImplementedError
def isHidden(self, slot):
layoutMode = context.getVar('layoutMode')
if layoutMode == 'edit':
isCreateEditMode = context.getVar('isCreateEditMode', default = 0)
if isCreateEditMode:
return self.stateInCreateMode == 'hidden' \
or (self.stateInCreateMode == 'read-only/hidden-if-empty'
and self.modelValueIsEmpty(slot)) \
or (self.stateInCreateMode is None
and (self.stateInEditMode == 'hidden'
or (self.stateInEditMode == 'read-only/hidden-if-empty'
and self.modelValueIsEmpty(slot))))
else:
return self.stateInEditMode == 'hidden' \
or self.stateInEditMode == 'read-only/hidden-if-empty' \
and self.modelValueIsEmpty(slot)
elif layoutMode == 'use':
aspect = context.getVar('aspect')
return aspect.state == 'hidden' \
or aspect.state == 'read-only/hidden-if-empty' \
and self.modelValueIsEmpty(slot)
else:
return self.stateInViewMode == 'hidden' \
or self.stateInViewMode == 'read-only/hidden-if-empty' \
and self.modelValueIsEmpty(slot)
def isImportable(self):
raise NotImplementedError
def isInCore(self, slot):
return not self.useCustomStorage and not self.useFileStorage
def isReadOnly(self, slot):
layoutMode = context.getVar('layoutMode')
if layoutMode == 'edit':
isCreateEditMode = context.getVar('isCreateEditMode', default = 0)
if isCreateEditMode:
return self.stateInCreateMode == 'read-only' \
or (self.stateInCreateMode == 'read-only/hidden-if-empty'
and not self.modelValueIsEmpty(slot)) \
or (self.stateInCreateMode is None
and (self.stateInEditMode == 'read-only'
or (self.stateInEditMode == 'read-only/hidden-if-empty'
and not self.modelValueIsEmpty(slot))))
else:
return self.stateInEditMode == 'read-only' \
or self.stateInEditMode == 'read-only/hidden-if-empty' \
and not self.modelValueIsEmpty(slot)
elif layoutMode == 'use':
aspect = context.getVar('aspect')
return aspect.state == 'read-only' \
or aspect.state == 'read-only/hidden-if-empty' \
and not self.modelValueIsEmpty(slot)
else:
return self.stateInViewMode == 'read-only' \
or self.stateInViewMode == 'read-only/hidden-if-empty' \
and not self.modelValueIsEmpty(slot)
def mayAccept(self, kind):
"""Test whether the given kind may be compatible with self.
For example:
- Integer always accepts Integer.
- Number always accepts Integer.
- Integer may accept Number, because sometimes a Number is an Integer.
"""
return self.intersects(kind)
def modelValueIsEmpty(self, slot):
return self.isEmptyModelValue(slot, slot.getValue())
def newJail(self, slot):
return jails.Jail(slot)
def releaseNonCoreValue(self, slot):
pass
def removeValueIds(self, slot, value, rolesToKeep):
return value
def repairValue(self, slot, value, toVersion):
assert self.isPractical
if toVersion == 5004:
if type(value) in (types.StringType, types.UnicodeType):
repairedValue = value.replace('\r\n', '\n')
repairedValue = repairedValue.replace('\r', '\n')
if repairedValue != value:
return repairedValue
2002-10-19 15:00:35 +02:00
return None
def saveNonCoreValue(self, slot, objectDirectoryPath):
pass
def setAutomaticalValue(self, slot, init = 0):
raise NotImplementedError
def setToDefaultValue(self, slot):
defaultValue = self.getDefaultValue(slot)
if defaultValue is not None:
slot.setValue(defaultValue)
def upgradeModel(self, slot, model, toVersion):
changed = 0
# Call upgradeModel_xxx methods.
classes = commonTools.getC3ClassLinearization(self.__class__)
upgradeMethodNames = []
for class_ in classes:
for attributeName in class_.__dict__.keys():
if attributeName.startswith('upgradeModel_'):
if not attributeName in upgradeMethodNames:
upgradeMethodNames.append(attributeName)
upgradeMethodNames.sort()
for upgradeMethodName in upgradeMethodNames:
if upgradeMethodName[len('upgradeModel_'):] < toVersion:
continue
modelChanged, model = getattr(self, upgradeMethodName)(slot, model)
changed = changed or modelChanged
return changed, model
2002-10-19 15:00:35 +02:00
register(BaseKind)
class AbstractSequence(BaseKind):
canInsertOrDelete = 1
minCount = None
minCount_kind_label = N_('Minimum Number of Items')
minCount_kindName = 'Integer'
maxCount = None
maxCount_kind_label = N_('Maximum Number of Items')
maxCount_kindName = 'Integer'
widgetName = 'Multi'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value is None:
return
if self.minCount and len(value) < self.minCount:
raise faults.BadSlotValue(slot, value)
if self.maxCount and len(value) > self.maxCount:
raise faults.BadSlotValue(slot, value)
def convertValueIds(self, slot, value, sourceDispatcherId,
destinationDispatcherId):
try:
len(value)
except TypeError:
raise Exception('Unsized value (= %s) for slot %s' % (value, slot))
2002-10-19 15:00:35 +02:00
for i in range(len(value)):
itemSlot = self.getItemSlot(slot, i)
newItem = itemSlot.getKind().convertValueIds(
itemSlot, value[i], sourceDispatcherId,
destinationDispatcherId)
2002-10-19 15:00:35 +02:00
if newItem != value[i]:
value[i] = newItem
return value
def executeModel(self, slot, when, command = None):
value = slot.getValue()
if value is None:
return
for i in range(len(value)):
itemSlot = self.getItemSlot(slot, i)
itemSlot.getKind().executeModel(itemSlot, when, command = command)
2002-10-19 15:00:35 +02:00
def exportValueToXmlRpc(self, slot, value):
if value is None:
return []
exportedValue = []
for i in range(len(value)):
itemSlot = self.getItemSlot(slot, i)
exportedValue.append(itemSlot.getKind().exportValueToXmlRpc(
itemSlot, value[i]))
return exportedValue
def getItemKind(self, index):
raise NotImplementedError
2002-10-19 15:00:35 +02:00
def getMinCount(self, slot):
return self.minCount
def getMaxCount(self, slot):
return self.maxCount
2002-10-19 15:00:35 +02:00
def getItemSlot(self, slot, index):
return slots.Item(index, parent = slot)
def getModelSlotByPath(self, slot, path):
if path.startswith('self'):
path = path[len('self'):]
if not path:
return slot
if path[0] != '[' or not ']' in path:
raise Exception('Path "%s" not found' % path)
index = int(path[1:path.index(']')])
return self.getItemKind(index).getModelSlotByPath(
self.getItemSlot(slot, index), path[path.index(']') + 1:])
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = BaseKind.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['maxCount']
return slotNames
2002-10-19 15:00:35 +02:00
def importValueFromXmlRpc(self, slot, importedValue):
if importedValue is None:
return []
value = []
slot.value = value
2002-10-19 15:00:35 +02:00
for i in range(len(importedValue)):
itemSlot = self.getItemSlot(slot, i)
value.append(itemSlot.getKind().importValueFromXmlRpc(
itemSlot, importedValue[i]))
del slot.value
2002-10-19 15:00:35 +02:00
return value
def newJail(self, slot):
return jails.MutableSequence(slot)
def removeValueIds(self, slot, value, rolesToKeep):
indexesToDelete = []
for i in range(len(value)):
itemSlot = self.getItemSlot(slot, i)
newItem = itemSlot.getKind().removeValueIds(
itemSlot, value[i], rolesToKeep)
if newItem != value[i]:
indexesToDelete.append(i)
indexesToDelete.reverse()
for i in indexesToDelete:
del value[i]
if not value:
return None
return value
def repairValue(self, slot, value, toVersion):
if toVersion == 4000:
changed = 0
for i in range(len(value)):
itemSlot = self.getItemSlot(slot, i)
newItem = itemSlot.getKind().repairValue(
itemSlot, value[i], toVersion)
if newItem:
changed = 1
value[i] = newItem
if changed:
return value
2002-10-19 15:00:35 +02:00
return None
def setToDefaultValue(self, slot):
BaseKind.setToDefaultValue(self, slot)
for i in range(len(slot.getValue() or [])):
itemSlot = self.getItemSlot(slot, i)
itemKind = itemSlot.getKind()
itemKind.setToDefaultValue(itemSlot)
def upgradeModel(self, slot, model, toVersion):
changed, model = BaseKind.upgradeModel(self, slot, model, toVersion)
# Upgrade each item.
if model is not None:
for i, item in zip(range(len(model)), model):
itemSlot = self.getItemSlot(slot, i)
itemChanged, item = itemSlot.getKind().upgradeModel(
itemSlot, item, toVersion)
if itemChanged:
changed = 1
model[i] = item
return changed, model
2002-10-19 15:00:35 +02:00
class Alias(BaseKind):
defaultValue_kindName = 'Alias'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Alias')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if self.isRequired and value == '':
raise faults.MissingSlotValue(slot)
if value:
if ' ' in value: # or '/' in value:
raise faults.BadSlotValue(slot, value)
register(Alias)
class Any(BaseKind):
defaultValue_kindName = 'Any'
isPractical = 0
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Any')
register(Any)
2002-10-19 15:00:35 +02:00
class Boolean(BaseKind):
containerNames = ['Any']
defaultValue = 0
defaultValue_kindName = 'Boolean'
labels = {
'0': N_('False'),
'1': N_('True'),
}
labels_kind_keyKind_value_stateInEditMode = 'read-only'
labels_kind_keyKind_valueName = 'String'
labels_kind_label = N_('Labels')
labels_kind_valueKind_valueName = 'String'
labels_kindName = 'Mapping'
possibleWidgetNames = ['InputCheckBox', 'Select']
pythonStorageType = types.IntType
# in Python 2.3 that could have been BooleanType
sortLabels = 0
sortLabels_kind_balloonHelp = N_(
'Check the box to sort labels alphabetically')
sortLabels_kind_importExport = 'private'
sortLabels_kind_label = N_('Sort Labels')
sortLabels_kind_stateInEditMode = 'hidden'
sortLabels_kind_stateInViewMode = 'hidden'
sortLabels_kindName = 'Boolean'
thingPublicCategory = N_('Numbers')
thingPublicName = N_('Boolean')
titles = None
titles_kind_importExport = 'private'
titles_kind_keyKind_value_stateInEditMode = 'read-only'
titles_kind_keyKind_valueName = 'String'
titles_kind_label = N_('Titles')
titles_kind_stateInEditMode = 'hidden'
titles_kind_stateInViewMode = 'hidden'
titles_kind_valueKind_valueName = 'String'
titles_kindName = 'Mapping'
2002-10-19 15:00:35 +02:00
values = [0, 1]
values_kind_importExport = 'private'
values_kind_itemKind_valueName = 'Boolean'
values_kind_stateInEditMode = 'hidden'
values_kind_stateInViewMode = 'hidden'
2002-10-19 15:00:35 +02:00
values_kindName = 'Sequence'
widgetName = 'InputCheckBox'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value not in (None, 0, 1):
raise faults.BadSlotValue(slot, value)
def convertValueFromOtherType(self, value):
if type(value) is types.StringType:
if value in ('0', '1'):
return int(value)
raise faults.BadValue()
return BaseKind.convertValueFromOtherType(self, value)
def convertValueToOtherType(self, value, otherType):
if otherType is types.StringType:
return str(value)
return BaseKind.convertValueToOtherType(self, value, otherType)
def getGroupedValues(self, slot):
return None
def getLabels(self, slot):
return self.labels
def getSortedValues(self, slot):
values = self.getValues(slot)
if values is not None:
values = values[:]
labels = self.getLabels(slot)
values.sort(lambda x, y:
locale.strcoll(_(labels[x]), _(labels[y])))
return values
def getValues(self, slot):
return self.values
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = BaseKind.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['values', 'labels', 'titles']
return slotNames
def newJail(self, slot):
return jails.Numeric(slot)
2002-10-19 15:00:35 +02:00
register(Boolean)
class Choice(BaseKind):
defaultValue_kindName = 'Choice'
groupedValues = None
groupedValues_kind_importExport = 'private'
groupedValues_kind_keyKind_valueName = 'String'
groupedValues_kind_stateInEditMode = 'hidden'
groupedValues_kind_stateInViewMode = 'hidden'
groupedValues_kind_valueKind_valueName = 'String'
groupedValues_kindName = 'Mapping'
# only use is in Metis; marked with a FIXME to remove it
groupedValuesGetterName = None
groupedValuesGetterName_kind_importExport = 'private'
groupedValuesGetterName_kind_stateInEditMode = 'hidden'
groupedValuesGetterName_kind_stateInViewMode = 'hidden'
groupedValuesGetterName_kindName = 'PythonIdentifier'
groupNames = None
groupNames_kind_importExport = 'private'
groupNames_kind_itemKind_valueName = 'String'
groupNames_kind_stateInEditMode = 'hidden'
groupNames_kind_stateInViewMode = 'hidden'
groupNames_kindName = 'Sequence'
# only use is in Metis; marked with a FIXME to remove it
groupNamesGetterName = None
groupNamesGetterName_kind_importExport = 'private'
groupNamesGetterName_kind_stateInEditMode = 'hidden'
groupNamesGetterName_kind_stateInViewMode = 'hidden'
groupNamesGetterName_kindName = 'PythonIdentifier'
labels = None
labels_kind_importExport = 'private'
labels_kind_keyKind_valueName = 'String'
labels_kind_label = N_('Labels')
labels_kind_stateInEditMode = 'hidden'
labels_kind_stateInViewMode = 'hidden'
labels_kind_valueKind_valueName = 'String'
labels_kindName = 'Mapping'
possibleWidgetNames = ['Select', 'RadioButtons']
pythonStorageType = types.StringType
sortLabels = 1
sortLabels_kind_importExport = 'private'
sortLabels_kind_balloonHelp = N_(
'Check the box to sort labels alphabetically')
sortLabels_kind_label = N_('Sort Labels')
sortLabels_kind_stateInEditMode = 'hidden'
sortLabels_kind_stateInViewMode = 'hidden'
sortLabels_kindName = 'Boolean'
thingPublicCategory = N_('Data')
thingPublicName = N_('Exclusive Choice')
titles = None
titles_kind_importExport = 'private'
titles_kind_keyKind_value_stateInEditMode = 'read-only'
titles_kind_keyKind_valueName = 'String'
titles_kind_label = N_('Titles')
titles_kind_stateInEditMode = 'hidden'
titles_kind_stateInViewMode = 'hidden'
titles_kind_valueKind_valueName = 'String'
titles_kindName = 'Mapping'
2002-10-19 15:00:35 +02:00
values = None
values_kind_itemKind_valueName = 'String'
values_kind_label = N_('Values')
2002-10-19 15:00:35 +02:00
values_kindName = 'Sequence'
widgetName = 'Select'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and self.values and value not in self.getValues(slot):
raise faults.BadSlotValue(slot, value)
def getGroupedValues(self, slot):
return None
def getGroupLabels(self, slot):
return None
def getLabels(self, slot):
if self.labels:
return self.labels
labels = {}
values = self.getValues(slot)
if values is not None:
for value in values:
labels[str(value)] = str(value)
return labels
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = BaseKind.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['values', 'labels', 'titles']
return slotNames
def getSortedValues(self, slot):
values = self.getValues(slot)
if values is None:
return None
values = values[:]
sortedValues = []
if None in values:
sortedValues.append(None)
values.remove(None)
if '__all__' in values:
sortedValues.append('__all__')
values.remove('__all__')
labels = self.getLabels(slot)
values.sort(lambda x, y: locale.strcoll(_(labels[x]), _(labels[y])))
sortedValues += values
return sortedValues
def getValues(self, slot):
groupedValuesGetterName = self.groupedValuesGetterName
if groupedValuesGetterName is not None:
currentSlot = slot
while currentSlot is not None:
container = currentSlot.getContainer()
try:
groupedValuesGetter = getattr(container,
groupedValuesGetterName)
except AttributeError:
currentSlot = currentSlot.parent
continue
groupedValues = groupedValuesGetter(slot)
assert type(groupedValues) is type({})
values = []
for group in groupedValues.keys():
assert type(groupedValues[group]) is type([])
values += groupedValues[group]
return values
return []
if self.groupedValues:
result = []
assert type(self.groupedValues) is type({})
for key in self.groupedValues.keys():
assert type(self.groupedValues[key]) is type([])
for value in self.groupedValues[key]:
result.append(value)
return result
if self.values:
return self.values
else:
return []
2002-10-19 15:00:35 +02:00
register(Choice)
class Data(BaseKind):
defaultValue_kindName = 'Data'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Data')
def convertValueFromOtherType(self, value):
if type(value) is types.InstanceType and \
value.getThingName() == 'Upload':
return value.data
2002-10-19 15:00:35 +02:00
def exportValueToXmlRpc(self, slot, value):
if value:
value = base64.encodestring(value)
return value
def importValueFromXmlRpc(self, slot, value):
if value:
value = base64.decodestring(value)
return value
register(Data)
class Time(BaseKind):
defaultValue_kindName = 'Time'
formatString = '%Y-%m-%d %H:%M:%S'
formatString_kind_label = N_('Date & Time Format')
formatString_kindName = 'String'
formatStringDay = '%Y-%m-%d'
formatStringDay_kind_label = N_('Date Format')
formatStringDay_kindName = 'String'
pythonStorageType = types.FloatType # seconds since epoch
textMaxLength = 19
thingPublicCategory = N_('Date & Time')
thingPublicName = N_('Date & Time')
widget_size = 19
widgetName = 'Time'
def convertValueFromOtherType(self, value):
if type(value) is types.IntType:
return float(value)
if type(value) is types.StringType:
if value == '':
return None
formatDate = ( self.formatStringDay, '%Y-%m-%d', '%y-%m-%d',
'%d/%m/%Y', '%d/%m/%y' )
formatTime = ( '%H:%M:%S', '%H:%M', '' )
for format in [x + ' ' + y
for x in formatDate for y in formatTime]:
try:
t = time.strptime(value, format)
except ValueError:
continue
break
else:
raise faults.BadValue()
# Set Daylight Saving Time to -1, so that it is handled
# correctly by mktime.
t = tuple(list(t[0:-1]) + [-1])
try:
value = time.mktime(t)
except OverflowError:
raise faults.BadValue()
return value
return BaseKind.convertValueFromOtherType(self, value)
def convertValueToOtherType(self, value, otherType):
if otherType is types.StringType:
if not value:
return ''
tupleTime = time.localtime(value)
if tuple(tupleTime[3:6]) == (0, 0, 0):
formatString = self.formatStringDay
else:
formatString = self.formatString
return time.strftime(formatString, time.localtime(value))
return BaseKind.convertValueToOtherType(self, value, otherType)
register(Time)
class DispatcherId(BaseKind):
containerNames = ['Any', 'String']
defaultValue_kindName = 'DispatcherId'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Glasnost Dispatcher ID')
widget_size = 40
widgetName = 'InputText'
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
return value.replace(sourceDispatcherId, destinationDispatcherId)
def newJail(self, slot):
return jails.String(slot)
register(DispatcherId)
class Duration(BaseKind):
defaultValue_kindName = 'Duration'
pythonStorageType = types.FloatType # number of seconds
requiredParts = ['day', 'hour', 'minute', 'second']
requiredParts_kind_itemKind_valueName = 'String'
requiredParts_kindName = 'Sequence'
thingPublicCategory = None # N_('Date & Time')
thingPublicName = N_('Duration')
widgetName = 'Duration'
register(Duration)
2002-10-19 15:00:35 +02:00
class Email(BaseKind):
containerNames = ['Any', 'String']
defaultValue_kindName = 'Email'
pythonStorageType = types.StringType
thingPublicCategory = N_('Text')
thingPublicName = N_('Email Address')
widgetName = 'Email'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value is None:
return
if value == '':
if self.isRequired:
raise faults.MissingSlotValue(slot)
return
if not re.match(r'^\S+@\S+$', value):
raise faults.BadSlotValue(slot, value)
def newJail(self, slot):
return jails.String(slot)
2002-10-19 15:00:35 +02:00
register(Email)
2003-05-29 17:46:46 +02:00
class Fields(BaseKind):
containerNames = ['Any']
defaultValue_kindName = 'Fields'
pythonStorageType = types.StringType # ~
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Fields')
2003-05-29 17:46:46 +02:00
def exportValueToXmlRpc(self, slot, value):
return base64.encodestring(marshal.dumps(value))
def importValueFromXmlRpc(self, slot, valueImport):
return marshal.loads(base64.decodestring(valueImport))
register(Fields)
class Path(BaseKind):
checkFilePath = 1
checkFilePath_kindName = 'Boolean'
containerNames = ['Any', 'String']
defaultValue_kindName = 'Path'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Text')
thingPublicName = N_('Path')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value is None:
return
if self.checkFilePath:
from glasnost.proxy.tools import getProxyForServerRole
systemFilesProxy = getProxyForServerRole('systemfiles')
systemFilesProxy.checkFilePath(value)
def newJail(self, slot):
return jails.String(slot)
register(Path)
class FilePath(Path):
containerNames = ['Any', 'String']
defaultValue_kindName = 'FilePath'
thingPublicCategory = None # N_('Text')
thingPublicName = N_('File Path')
def newJail(self, slot):
return jails.String(slot)
2002-10-19 15:00:35 +02:00
register(FilePath)
class Fingerprint(BaseKind):
containerNames = ['Any', 'String']
defaultValue_kindName = 'Fingerprint'
pythonStorageType = types.StringType
textMaxLength = 50
thingPublicCategory = N_('Text')
thingPublicName = N_('OpenPGP Fingerprint')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value is None or value == '':
return
value = value.replace(' ', '')
if len(value) != 40:
raise faults.BadSlotValue(slot, value)
for char in value:
if char not in string.hexdigits:
raise faults.BadSlotValue(slot, value)
def convertValueToOtherType(self, value, otherType):
if otherType is types.StringType:
if value is None:
return ''
value = value.replace(' ', '')
return '%s %s %s %s %s %s %s %s %s %s' % (
value[ 0: 4], value[ 4: 8], value[ 8:12], value[12:16],
value[16:20], value[20:24], value[24:28], value[28:32],
value[32:36], value[36:40])
return BaseKind.convertValueToOtherType(self, value, otherType)
def newJail(self, slot):
return jails.String(slot)
2002-10-19 15:00:35 +02:00
register(Fingerprint)
class Float(BaseKind):
defaultValue_kindName = 'Float'
pythonStorageType = types.FloatType
thingPublicCategory = N_('Numbers')
thingPublicName = N_('Float Number')
def convertValueFromOtherType(self, value):
if type(value) in (types.IntType, types.StringType):
try:
return float(value)
except ValueError:
pass
return BaseKind.convertValueFromOtherType(self, value)
def convertValueToOtherType(self, value, otherType):
if otherType is types.StringType:
if value is None:
return ''
return str(value)
return BaseKind.convertValueToOtherType(self, value, otherType)
def newJail(self, slot):
return jails.Numeric(slot)
2002-10-19 15:00:35 +02:00
register(Float)
class Id(BaseKind):
containerNames = ['Any']
defaultValue_kindName = 'Id'
permanentIds = None
pythonStorageType = types.StringType
rememberedIds = 0
rememberedIds_kindName = 'Boolean'
2002-10-19 15:00:35 +02:00
serverRoles = None
serverRoles_kindName = 'AcceptedRoles'
2002-10-19 15:00:35 +02:00
thingPublicCategory = N_('Links')
thingPublicName = N_('Object')
widgetName = 'SelectId'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value:
try:
commonTools.extractDispatcherId(value)
except:
raise faults.BadSlotValue(slot, value)
2002-10-19 15:00:35 +02:00
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
if value is None:
return None
return value.replace(sourceDispatcherId, destinationDispatcherId)
2002-10-19 15:00:35 +02:00
def equals(self, kind):
if not BaseKind.equals(self, kind):
return 0
if self.getServerRoles(None) is None:
serverRoles = None
else:
serverRoles = self.getServerRoles(None)[:]
serverRoles.sort()
if kind.serverRoles is None:
kindServerRoles = None
else:
kindServerRoles = kind.getServerRoles(None)[:]
kindServerRoles.sort()
return serverRoles == kindServerRoles
def getLabels(self, slot):
values = self.getValues(slot)
from glasnost.proxy.tools import getObjectLabelsTranslated
labels = getObjectLabelsTranslated(values,
context.getVar('readLanguages'))
return labels
def getServerRoles(self, slot):
return self.serverRoles
def getGroupedValues(self, slot):
values = self.getValues(slot)
groupedValues = {}
for v in values:
if v in (self.permanentIds or []):
role = None
else:
role = commonTools.extractRole(v)
if not groupedValues.has_key(role):
groupedValues[role] = []
groupedValues[role].append(v)
return groupedValues
def getGroupLabels(self, slot):
groupNames = self.getGroupedValues(slot).keys()
d = {}
for role in groupNames:
if not role:
d[''] = None
continue
common = getCommonForServerRole(role)
d[common.getTranslatedObjectsNameCapitalized()] = role
return d
def getValues(self, slot):
from glasnost.proxy.tools import getProxyForServerRole
result = []
result.extend(self.permanentIds or [])
currentValue = slot.getValue()
serverRoles = self.getServerRoles(slot) or context.getVar('knownRoles')
for role in serverRoles:
proxy = getProxyForServerRole(role)
if not hasattr(proxy, 'getObjectIds'):
continue
try:
objectIds = None
if self.rememberedIds:
user = context.getVar('user')
if user and user.objectsMemory and \
user.objectsMemory.has_key(role) and \
user.objectsMemory[role]:
objectIds = user.objectsMemory[role]
if currentValue and \
commonTools.extractRole(currentValue) == role:
objectIds.append(currentValue)
if not objectIds:
objectIds = proxy.getObjectIds()
except faults.UserAccessDenied:
continue
2004-04-19 11:58:53 +02:00
if role == 'groups' and serverRoles and serverRoles != ['groups']:
objectIds = proxy.getObjectIdsWithCriteria(
'not object.acceptedRoles or '\
' [x for x in object.acceptedRoles if x in %r]' % (
serverRoles))
result.extend(objectIds)
return result
def includes(self, kind):
if BaseKind.includes(self, kind):
return 1
if self.getThingName() != kind.getThingName():
return 0
if not self.getServerRoles(None):
return 1
if not kind.getServerRoles(None):
return 0
for kindServerRole in kind.serverRoles:
if not kindServerRole in self.getServerRoles(None):
return 0
return 1
def intersects(self, kind):
if BaseKind.intersects(self, kind):
return 1
if self.getThingName() != kind.getThingName():
return 0
if not self.getServerRoles(None) or not kind.getServerRoles(None):
return 1
for kindServerRole in kind.serverRoles:
if kindServerRole in self.getServerRoles(None):
return 1
return 0
def isEmptyModelValue(self, slot, value):
return not value
def removeValueIds(self, slot, value, rolesToKeep):
if not commonTools.extractRole(value) in rolesToKeep:
return None
return value
def repairValue(self, slot, value, toVersion):
if toVersion == 4000:
return repairId(value)
return None
def upgradeModel_0001_0028(self, slot, model):
"""Convert user ids from "people" to "identities"."""
changed = 0
if self.serverRoles is not None and 'identities' in self.serverRoles \
and not 'people' in self.serverRoles \
and commonTools.extractRole(model) == 'people':
changed = 1
model = '%s/%s' % (
commonTools.makeApplicationId(model, 'identities'),
commonTools.extractLocalId(model))
return changed, model
2002-10-19 15:00:35 +02:00
register(Id)
class Integer(BaseKind):
containerNames = ['Any']
defaultValue_kindName = 'Integer'
max = None
max_kind_label = N_('Maximum Value')
max_kindName = 'Integer'
min = None
min_kind_label = N_('Minimum Value')
min_kindName = 'Integer'
pythonStorageType = types.IntType
textMaxLength = 10
thingPublicCategory = N_('Numbers')
thingPublicName = N_('Integer Number')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value is None:
return
if self.min is not None and value < self.min:
raise faults.ValueTooSmall(slot, value)
if self.max is not None and value > self.max:
raise faults.ValueTooBig(slot, value)
def convertValueFromOtherType(self, value):
if type(value) is types.FloatType:
return int(value)
if type(value) is types.StringType:
try:
return int(value)
except ValueError:
raise faults.BadValue()
return BaseKind.convertValueFromOtherType(self, value)
def convertValueToOtherType(self, value, otherType):
if otherType is types.StringType:
if value is None:
return ''
return str(value)
if otherType is types.FloatType:
return float(value)
return BaseKind.convertValueToOtherType(self, value, otherType)
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = BaseKind.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames = slotNames[:]
i = slotNames.index('defaultValue')
slotNames[i:i] = ['min', 'max']
return slotNames
def getTextMaxLength(self):
if self.min is not None and self.max is not None:
textMaxLength = max(len(str(self.min)), len(str(self.max)))
else:
textMaxLength = BaseKind.getTextMaxLength(self)
return textMaxLength
def newJail(self, slot):
return jails.Numeric(slot)
2002-10-19 15:00:35 +02:00
register(Integer)
class IntegerChoice(Choice):
defaultValue_kindName = 'IntegerChoice'
pythonStorageType = types.IntType
thingPublicCategory = None # N_('Choice')
thingPublicName = N_('Integer Choice')
titles_kind_keyKind_valueName = 'Integer'
values_kind_itemKind_valueName = 'Integer'
register(IntegerChoice)
2002-10-19 15:00:35 +02:00
class LanguageChoice(Choice):
balloonHelp = N_('Select the [language->language] of '\
'this [object->objects].')
containerNames = ['Any']
defaultValue_kindName = 'LanguageChoice'
label = N_('Language')
labels = translation.languageLabels
isRequired = 1
thingPublicCategory = N_('Data')
thingPublicName = N_('Language')
2002-10-19 15:00:35 +02:00
values = translation.languageKeys
values_kind_importExport = 'private'
values_kind_stateInEditMode = 'hidden'
values_kind_stateInViewMode = 'hidden'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
return 1
def getDefaultValue(self, slot):
languages = context.getVar('readLanguages')
if languages and languages[0] in self.values:
return languages[0]
else:
return 'en'
def getValues(self, slot):
from glasnost.proxy.tools import getProxyForServerRole
translationsProxy = getProxyForServerRole('translations')
if translationsProxy:
try:
return translationsProxy.getPossibleLanguages()
except faults.UnknownServerId:
return self.values
return self.values
2002-10-19 15:00:35 +02:00
register(LanguageChoice)
class Link(BaseKind):
defaultValue_kindName = 'Link'
pythonStorageType = types.TupleType # (name, url)
thingPublicCategory = None # N_('Data')
thingPublicName = N_('Link')
2002-10-19 15:00:35 +02:00
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value is None:
return
if len(value) != 2:
raise faults.BadSlotValue(slot, value)
2002-10-19 15:00:35 +02:00
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
name, url = value
if url.startswith('id:'):
url = url.replace(sourceDispatcherId, destinationDispatcherId)
return (name, url)
def isEmptyModelValue(self, slot, value):
return value is None or not value[0] and not value[1]
def removeValueIds(self, slot, value, rolesToKeep):
name, url = value
if url.startswith('id:') \
and not commonTools.extractRole(url[3:]) in rolesToKeep:
return None
return value
def repairValue(self, slot, value, toVersion):
if toVersion == 4000:
name, url = value
if url.startswith('id:'):
newId = repairId(url[3:])
if newId:
return (name, 'id:' + newId)
2002-10-19 15:00:35 +02:00
return None
register(Link)
class Mapping(BaseKind):
containerNames = ['Any']
defaultValue_kindName = 'Mapping'
deleteNullValues = 0
deleteNullValues_kindName = 'Boolean'
keyKind = None
keyKind_kind_isRequired = 1
keyKind_kindName = 'Kind'
2002-10-19 15:00:35 +02:00
pythonStorageType = types.DictType
requiredCount = 0
requiredCount_kindName = 'Integer'
thingPublicCategory = None # N_('Data')
thingPublicName = N_('Mapping')
valueKind = None
valueKind_kind_isRequired = 1
valueKind_kindName = 'Kind'
2002-10-19 15:00:35 +02:00
widgetName = 'Mapping'
def buildKinds(self):
# Should be converted to a class method, when porting Glasnost to
# Python 2.2.
BaseKind.buildKinds(self)
# Build keyKind from keyKind_valueName attributes.
if hasattr(self, 'keyKind_valueName') \
and self.keyKind_valueName is not None:
baseClasses = self.getC3ClassLinearization()
keyKindOptionNames = [key
for key in self.__dict__.keys()
if key.startswith('keyKind_value_')]
for baseClass in baseClasses:
for key in baseClass.__dict__.keys():
if key.startswith('keyKind_value_') \
and not key in keyKindOptionNames:
keyKindOptionNames.append(key)
keyKindOptions = {}
for keyKindOptionName in keyKindOptionNames:
keyKindOptions[keyKindOptionName[len('keyKind_value_'):]
] = getattr(self, keyKindOptionName)
keyKind = commonTools.newThing('kind', self.keyKind_valueName)
keyKind.buildOptions(keyKindOptions)
self.__class__.keyKind = keyKind
# Build valueKind from valueKind_valueName attributes.
if hasattr(self, 'valueKind_valueName') \
and self.valueKind_valueName is not None:
baseClasses = self.getC3ClassLinearization()
valueKindOptionNames = [key
for key in self.__dict__.keys()
if key.startswith('valueKind_value_')]
for baseClass in baseClasses:
for key in baseClass.__dict__.keys():
if key.startswith('valueKind_value_') \
and not key in valueKindOptionNames:
valueKindOptionNames.append(key)
valueKindOptions = {}
for valueKindOptionName in valueKindOptionNames:
valueKindOptions[valueKindOptionName[len('valueKind_value_'):]
] = getattr(self, valueKindOptionName)
valueKind = commonTools.newThing('kind', self.valueKind_valueName)
valueKind.buildOptions(valueKindOptions)
self.__class__.valueKind = valueKind
# Build keyKind from keyKind_valueClass attributes.
if hasattr(self, 'keyKind_valueClass') \
and self.keyKind_valueClass is not None:
realKindClass = commonTools.getThingClass(
'kind', self.keyKind_valueClass._kindName)
class class_(self.keyKind_valueClass, realKindClass):
pass
kind = class_()
kind.buildOptions({})
self.__class__.keyKind = kind
# Build valueKind from valueKind_valueClass attributes.
if hasattr(self, 'valueKind_valueClass') \
and self.valueKind_valueClass is not None:
realKindClass = commonTools.getThingClass(
'kind', self.valueKind_valueClass._kindName)
class class_(self.valueKind_valueClass, realKindClass):
pass
kind = class_()
kind.buildOptions({})
self.__class__.valueKind = kind
2002-10-19 15:00:35 +02:00
def buildOptions(self, options):
baseClasses = self.getC3ClassLinearization()
keyKindOptionNames = [key
for key in self.__dict__.keys()
if key.startswith('keyKind_value_')]
for baseClass in baseClasses:
for key in baseClass.__dict__.keys():
if key.startswith('keyKind_value_') \
and not key in keyKindOptionNames:
keyKindOptionNames.append(key)
keyKindOptions = {}
for keyKindOptionName in keyKindOptionNames:
keyKindOptions[keyKindOptionName[len('keyKind_value_'):]
] = getattr(self, keyKindOptionName)
keyKindOptionNames = [key
for key in options.keys()
if key.startswith('keyKind_value_')]
for keyKindOptionName in keyKindOptionNames:
keyKindOptions[keyKindOptionName[len('keyKind_value_'):]
] = options[keyKindOptionName]
del options[keyKindOptionName]
if options.has_key('keyKind_valueName'):
keyKindName = options['keyKind_valueName']
del options['keyKind_valueName']
elif hasattr(self, 'keyKind_valueName'):
keyKindName = self.keyKind_valueName
else:
keyKindName = None
if options.has_key('keyKind_valueClass'):
keyKindClass = options['keyKind_valueClass']
del options['keyKind_valueClass']
elif hasattr(self, 'keyKind_valueClass'):
keyKindClass = self.keyKind_valueClass
else:
keyKindClass = None
valueKindOptionNames = [key
for key in self.__dict__.keys()
if key.startswith('valueKind_value_')]
for baseClass in baseClasses:
for key in baseClass.__dict__.keys():
if key.startswith('valueKind_value_') \
and not key in valueKindOptionNames:
valueKindOptionNames.append(key)
valueKindOptions = {}
for valueKindOptionName in valueKindOptionNames:
valueKindOptions[valueKindOptionName[len('valueKind_value_'):]
] = getattr(self, valueKindOptionName)
valueKindOptionNames = [key
for key in options.keys()
if key.startswith('valueKind_value_')]
for valueKindOptionName in valueKindOptionNames:
valueKindOptions[valueKindOptionName[len('valueKind_value_'):]
] = options[valueKindOptionName]
del options[valueKindOptionName]
if options.has_key('valueKind_valueName'):
valueKindName = options['valueKind_valueName']
del options['valueKind_valueName']
elif hasattr(self, 'valueKind_valueName'):
valueKindName = self.valueKind_valueName
else:
valueKindName = None
if options.has_key('valueKind_valueClass'):
valueKindClass = options['valueKind_valueClass']
del options['valueKind_valueClass']
elif hasattr(self, 'valueKind_valueClass'):
valueKindClass = self.valueKind_valueClass
else:
valueKindClass = None
2002-10-19 15:00:35 +02:00
BaseKind.buildOptions(self, options)
if keyKindClass is not None:
realKindClass = commonTools.getThingClass(
'kind', keyKindClass._kindName)
class class_(keyKindClass, realKindClass):
pass
keyKind = class_()
keyKind.buildOptions(keyKindOptions)
self.keyKind = keyKind
elif keyKindName is not None:
keyKind = commonTools.newThing('kind', keyKindName)
keyKind.buildOptions(keyKindOptions)
self.keyKind = keyKind
if valueKindClass is not None:
realKindClass = commonTools.getThingClass(
'kind', valueKindClass._kindName)
class class_(valueKindClass, realKindClass):
pass
valueKind = class_()
valueKind.buildOptions(valueKindOptions)
self.valueKind = valueKind
elif valueKindName is not None:
valueKind = commonTools.newThing('kind', valueKindName)
valueKind.buildOptions(valueKindOptions)
self.valueKind = valueKind
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if self.requiredCount > 0:
if value is None:
raise faults.MissingSlotValue(slot)
if len(value) < self.requiredCount:
raise faults.BadSlotValue(slot, value)
2002-10-19 15:00:35 +02:00
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
keyIndex = 0
2002-10-19 15:00:35 +02:00
for key, val in value.items():
keySlot = self.getItemKeySlot(slot, keyIndex)
newKey = keySlot.getKind().convertValueIds(
keySlot, key, sourceDispatcherId, destinationDispatcherId)
if newKey != key:
del value[key]
value[newKey] = val
keyIndex += 1
for key, val in value.items():
valueSlot = self.getItemValueSlot(slot, key)
2002-10-19 15:00:35 +02:00
newVal = valueSlot.getKind().convertValueIds(
valueSlot, val, sourceDispatcherId, destinationDispatcherId)
if newVal != val:
value[key] = newVal
return value
def executeModel(self, slot, when, command = None):
value = slot.getValue()
if value is None:
return
keyIndex = 0
for key, itemValue in value.items():
keySlot = self.getItemKeySlot(slot, keyIndex)
keySlot.getKind().executeModel(keySlot, when, command = command)
valueSlot = self.getItemValueSlot(slot, key)
valueSlot.getKind().executeModel(
valueSlot, when, command = command)
keyIndex += 1
2002-10-19 15:00:35 +02:00
def exportValueToXmlRpc(self, slot, value):
if value is None:
return {}
exportedValue = {}
keyIndex = 0
try:
value.items()
except:
raise str((self, slot, value))
2002-10-19 15:00:35 +02:00
for key, itemValue in value.items():
keySlot = self.getItemKeySlot(slot, keyIndex)
exportedKey = keySlot.getKind().exportValueToXmlRpc(keySlot, key)
valueSlot = self.getItemValueSlot(slot, key)
2002-10-19 15:00:35 +02:00
exportedItemValue = valueSlot.getKind().exportValueToXmlRpc(
valueSlot, itemValue)
exportedValue[exportedKey] = exportedItemValue
keyIndex += 1
return exportedValue
def getItemKeyKind(self, index):
return self.keyKind
2002-10-19 15:00:35 +02:00
def getItemKeySlot(self, slot, index):
return slots.ItemKey(index, parent = slot)
def getItemKeyValueKind(self, key):
return self.valueKind
def getItemKeyValueSlot(self, slot):
return slots.ItemKeyValue(parent = slot)
def getItemValueKind(self, key):
return self.valueKind
2002-10-19 15:00:35 +02:00
def getItemValueSlot(self, slot, key):
return slots.ItemValue(key, parent = slot)
2002-10-19 15:00:35 +02:00
def getModelSlotByPath(self, slot, path):
if path.startswith('self'):
path = path[len('self'):]
if not path:
return slot
if path.startswith('.keys()[') and ']' in path:
index = int(path[len('.keys()['):path.index(']')])
return self.getItemKeyKind(index).getModelSlotByPath(
self.getItemKeySlot(slot, index), path[path.index(']') + 1:])
if path[0] != '[' or not ']' in path:
raise Exception('Path "%s" not found' % path)
key = eval(path[1:path.index(']')], {})
return self.getItemValueKind(key).getModelSlotByPath(
self.getItemValueSlot(slot, key), path[path.index(']') + 1:])
2002-10-19 15:00:35 +02:00
def importValueFromXmlRpc(self, slot, importedValue):
if importedValue is None:
return {}
value = {}
slot.value = value
2002-10-19 15:00:35 +02:00
keyIndex = 0
for importedKey, importedItemValue in importedValue.items():
keySlot = self.getItemKeySlot(slot, keyIndex)
key = keySlot.getKind().importValueFromXmlRpc(keySlot, importedKey)
valueSlot = self.getItemValueSlot(slot, key)
2002-10-19 15:00:35 +02:00
itemValue = valueSlot.getKind().importValueFromXmlRpc(
valueSlot, importedItemValue)
value[key] = itemValue
keyIndex += 1
del slot.value
2002-10-19 15:00:35 +02:00
return value
def isEmptyModelValue(self, slot, value):
return not value
def newJail(self, slot):
return jails.Mapping(slot)
def removeValueIds(self, slot, value, rolesToKeep):
keyIndex = 0
for key, val in value.items():
keySlot = self.getItemKeySlot(slot, keyIndex)
newKey = keySlot.getKind().removeValueIds(
keySlot, key, rolesToKeep)
if newKey != key:
del value[key]
keyIndex += 1
for key, val in value.items():
valueSlot = self.getItemValueSlot(slot, key)
newVal = valueSlot.getKind().removeValueIds(
valueSlot, val, rolesToKeep)
if newVal != val:
del value[key]
if not value:
return None
return value
def repairValue(self, slot, value, toVersion):
if toVersion == 4000:
changed = 0
keyIndex = 0
for key, val in value.items():
keySlot = self.getItemKeySlot(slot, keyIndex)
newKey = keySlot.getKind().repairValue(keySlot, key, toVersion)
if newKey:
changed = 1
del value[key]
value[newKey] = val
keyIndex += 1
for key, val in value.items():
valueSlot = self.getItemValueSlot(slot, key)
newVal = valueSlot.getKind().repairValue(
valueSlot, val, toVersion)
if newVal:
changed = 1
value[key] = newVal
if changed:
return value
2002-10-19 15:00:35 +02:00
return None
def upgradeModel(self, slot, model, toVersion):
changed, model = BaseKind.upgradeModel(self, slot, model, toVersion)
# Upgrade each key and value.
if model is not None:
for keyIndex, key in zip(range(len(model.keys())), model.keys()):
keySlot = self.getItemKeySlot(slot, keyIndex)
keyChanged, upgradedKey = keySlot.getKind().upgradeModel(
keySlot, key, toVersion)
if keyChanged:
changed = 1
model[upgradedKey] = model.pop(key)
for key, value in model.items():
valueSlot = self.getItemValueSlot(slot, key)
valueChanged, value = valueSlot.getKind().upgradeModel(
valueSlot, value, toVersion)
if valueChanged:
changed = 1
model[key] = value
return changed, model
2002-10-19 15:00:35 +02:00
register(Mapping)
class Marks(BaseKind):
defaultValue_kindName = 'Marks'
pythonStorageType = types.DictType
## thingPublicCategory = N_('Other')
2002-10-19 15:00:35 +02:00
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
for id, mark in value.items():
newId = id.replace(sourceDispatcherId, destinationDispatcherId)
if newId != id:
del value[id]
value[newId] = mark
return value
def exportValueToXmlRpc(self, slot, value):
exportedValue = {}
if value is not None:
for objectId, mark in value.items():
if mark is None:
exportedMark = -1
else:
exportedMark = mark
exportedValue[objectId] = exportedMark
return exportedValue
def importValueFromXmlRpc(self, slot, importedValue):
value = {}
slot.value = value
2002-10-19 15:00:35 +02:00
for objectId, importedMark in importedValue.items():
if importedMark == -1:
mark = None
else:
mark = importedMark
value[objectId] = mark
if not value:
value = None
del slot.value
2002-10-19 15:00:35 +02:00
return value
def removeValueIds(self, slot, value, rolesToKeep):
for id in value.keys():
if not commonTools.extractRole(id) in rolesToKeep:
del value[id]
if not value:
return None
return value
def repairValue(self, slot, value, toVersion):
if toVersion == 4000:
changed = 0
for id, mark in value.items():
newId = repairId(id)
if newId:
changed = 1
del value[id]
value[newId] = mark
if changed:
return value
2002-10-19 15:00:35 +02:00
return None
register(Marks)
class Memory(BaseKind):
defaultValue_kindName = 'Memory'
pythonStorageType = types.DictType
## thingPublicCategory = N_('Other')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.DictType:
raise faults.BadSlotValue(slot, value)
2002-10-19 15:00:35 +02:00
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
for serverId, serverMemory in value.items():
newServerId = serverId.replace(
sourceDispatcherId, destinationDispatcherId)
if newServerId != serverId:
del value[serverId]
value[newServerId] = serverMemory
for i in range(len(serverMemory)):
itemId = serverMemory[i]
newItemId = itemId.replace(
sourceDispatcherId, destinationDispatcherId)
if newItemId != itemId:
serverMemory[i] = newItemId
return value
def removeValueIds(self, slot, value, rolesToKeep):
for serverId, serverMemory in value.items():
if not commonTools.extractRole(serverId) in rolesToKeep:
del value[serverId]
continue
indexesToDelete = []
for i in range(len(serverMemory)):
itemId = serverMemory[i]
if not commonTools.extractRole(itemId) in rolesToKeep:
indexesToDelete.append(i)
indexesToDelete.reverse()
for i in indexesToDelete:
del serverMemory[i]
if not serverMemory:
del value[serverId]
if not value:
return None
return value
2002-10-19 15:00:35 +02:00
register(Memory)
class PairwiseMatrix(BaseKind):
defaultValue_kindName = 'PairwiseMatrix'
pythonStorageType = types.DictType
## thingPublicCategory = N_('Other')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.DictType:
raise faults.BadSlotValue(slot, value)
2002-10-19 15:00:35 +02:00
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
for id1, row in value.items():
newId1 = id1.replace(sourceDispatcherId, destinationDispatcherId)
if newId1 != id1:
del value[id1]
value[newId1] = row
for id2, score in row.items():
newId2 = id2.replace(
sourceDispatcherId, destinationDispatcherId)
if newId2 != id2:
del row[id2]
row[newId2] = score
return value
def removeValueIds(self, slot, value, rolesToKeep):
for id1, row in value.items():
if not commonTools.extractRole(id1) in rolesToKeep:
del value[id1]
continue
for id2, score in row.items():
if not commonTools.extractRole(id2) in rolesToKeep:
del row[id2]
if not row:
del value[id1]
if not value:
return None
return value
def repairValue(self, slot, value, toVersion):
if toVersion == 4000:
changed = 0
for id1, row in value.items():
newId1 = repairId(id1)
if newId1:
2002-10-19 15:00:35 +02:00
changed = 1
del value[id1]
value[newId1] = row
for id2, score in row.items():
newId2 = repairId(id2)
if newId2:
changed = 1
del row[id2]
row[newId2] = score
if changed:
return value
2002-10-19 15:00:35 +02:00
return None
register(PairwiseMatrix)
class Password(BaseKind):
defaultValue_kindName = 'Password'
# enterTwice is not used anymore, but should be...
enterTwice = 0
enterTwice_kind_importExport = 'private'
enterTwice_kind_label = N_('Enter Twice')
enterTwice_kind_stateInEditMode = 'hidden'
enterTwice_kind_stateInViewMode = 'hidden'
enterTwice_kindName = 'Boolean'
pythonStorageType = types.StringType
thingPublicCategory = N_('Text')
thingPublicName = N_('Password')
widgetName = 'InputPassword'
register(Password)
class PythonIdentifier(BaseKind):
defaultValue_kindName = 'PythonIdentifier'
invalidValues = None
invalidValues_kind_itemKind_valueName = 'PythonIdentifier'
invalidValues_kind_label = N_('Invalid values')
invalidValues_kindName = 'Sequence'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Text')
thingPublicName = N_('Python Identifier')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value is None:
return
if self.invalidValues and value in self.invalidValues:
raise faults.BadSlotValue(slot, value)
if re.match('[a-zA-Z_][a-zA-Z0-9_]*$', value) is None:
raise faults.BadSlotValue(slot, value)
register(PythonIdentifier)
2002-10-19 15:00:35 +02:00
class Rating(BaseKind):
defaultValue_kindName = 'Rating'
pythonStorageType = types.DictType
## thingPublicCategory = N_('Other')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.DictType:
raise faults.BadSlotValue(slot, value)
2002-10-19 15:00:35 +02:00
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
for k in ['wins', 'losses', 'ties']:
v = value[k]
for i in range(len(v)):
id = v[i]
newId = id.replace(sourceDispatcherId, destinationDispatcherId)
if newId != id:
v[i] = newId
return value
def removeValueIds(self, slot, value, rolesToKeep):
for k in ['wins', 'losses', 'ties']:
v = value[k]
r = range(len(v))
r.reverse()
for i in r:
id = v[i]
if not commonTools.extractRole(id) in rolesToKeep:
del v[i]
return value
def repairValue(self, slot, value, toVersion):
if toVersion == 4000:
changed = 0
for k in ['wins', 'losses', 'ties']:
v = value[k]
for i in range(len(v)):
id = v[i]
newId = repairId(id)
if newId:
changed = 1
v[i] = newId
if changed:
return value
2002-10-19 15:00:35 +02:00
return None
register(Rating)
class Script(BaseKind):
builtins = {
'abs': abs,
'cmp': cmp,
'complex': complex,
'divmod': divmod,
'float': float,
'hash': hash,
'hex': hex,
'int': int,
'len': len,
'long': long,
'None': None,
'oct': oct,
'pow': pow,
'repr': repr,
'str': str,
'unicode': unicode,
}
containerNames = ['Any', 'String']
defaultValue_kindName = 'Script'
executeOnDisplay = 0
class executeOnDisplay_kindClass:
_kindName = 'Boolean'
label = N_('Execute On Display')
executeOnSubmit = 0
class executeOnSubmit_kindClass:
_kindName = 'Boolean'
label = N_('Execute On Submit')
sourceCode = None
class sourceCode_kindClass:
_kindName = 'ScriptSourceCode'
label = N_('Source Code')
#tagInEditMode = 'div'
#tagInViewMode = 'div'
stateInEditMode = 'read-only'
stateInViewMode = 'read-only'
textFormat = 'text'
thingPublicCategory = N_('Data')
thingPublicName = N_('Script')
widgetName = 'TextArea'
def executeModel(self, slot, when, command = None):
if not (when == 'onDisplay' and self.executeOnDisplay) \
and not (when == 'onSubmit' and self.executeOnSubmit):
return
if not self.sourceCode:
return
objectSlot = slots.Root(slot.getObject())
objectJail = objectSlot.newJail()
globals_ = {
'__builtins__': self.builtins,
'command': command,
'self': objectJail,
}
locals_ = {}
# stdin = sys.stdin
stdout = sys.stdout
stderr = sys.stderr
sys.stdout = sys.stderr = executionOutputIO = cStringIO.StringIO()
try:
exec '%s\n' % self.sourceCode in globals_, locals_
except:
## traceback.print_exception(sys.exc_type, sys.exc_value, None)
traceback.print_exc()
# sys.stdin = stdin
sys.stdout = stdout
sys.stderr = stderr
slot.setValue(executionOutputIO.getvalue())
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = BaseKind.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['sourceCode', 'executeOnDisplay', 'executeOnSubmit']
return slotNames
def newJail(self, slot):
return jails.String(slot)
register(Script)
class ScriptSourceCode(BaseKind):
containerNames = ['Any', 'String']
defaultValue_kindName = 'ScriptSourceCode'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Data')
thingPublicName = N_('Script Source Code')
widget_rows = 10
widget_viewInTextArea = 1
widgetName = 'TextArea'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.StringType:
raise faults.BadSlotValue(slot, value)
if value and (
value.find ('__') >= 0
or value.find ('_model') >= 0):
raise faults.BadSlotValue(slot, value)
def newJail(self, slot):
return jails.String(slot)
register(ScriptSourceCode)
2002-10-19 15:00:35 +02:00
class Sequence(AbstractSequence):
containerNames = ['Any']
defaultValue_kindName = 'Sequence'
class isRequired_kindClass(AbstractSequence.isRequired_kindClass):
importExport = 'private'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
itemKind = None
itemKind_kind_isRequired = 1
itemKind_kind_label = N_('Item Type')
itemKind_kindName = 'Kind'
itemKind_valueName = 'String'
pythonStorageType = types.ListType
thingPublicCategory = N_('Data')
thingPublicName = N_('Sequence')
def buildKinds(self):
# Should be converted to a class method, when porting Glasnost to
# Python 2.2.
AbstractSequence.buildKinds(self)
# Build itemKind from itemKind_valueName attributes.
if hasattr(self, 'itemKind_valueName') \
and self.itemKind_valueName is not None:
baseClasses = self.getC3ClassLinearization()
itemKindOptionNames = [key
for key in self.__dict__.keys()
if key.startswith('itemKind_value_')]
for baseClass in baseClasses:
for key in baseClass.__dict__.keys():
if key.startswith('itemKind_value_') \
and not key in itemKindOptionNames:
itemKindOptionNames.append(key)
itemKindOptions = {}
for itemKindOptionName in itemKindOptionNames:
itemKindOptions[itemKindOptionName[len('itemKind_value_'):]
] = getattr(self, itemKindOptionName)
itemKind = commonTools.newThing('kind', self.itemKind_valueName)
itemKind.buildOptions(itemKindOptions)
self.__class__.itemKind = itemKind
# Build itemKind from itemKind_valueClass attributes.
if hasattr(self, 'itemKind_valueClass') \
and self.itemKind_valueClass is not None:
realKindClass = commonTools.getThingClass(
'kind', self.itemKind_valueClass._kindName)
class class_(self.itemKind_valueClass, realKindClass):
pass
kind = class_()
kind.buildOptions({})
self.__class__.itemKind = kind
2002-10-19 15:00:35 +02:00
def buildOptions(self, options):
baseClasses = self.getC3ClassLinearization()
itemKindOptionNames = [key
for key in self.__dict__.keys()
if key.startswith('itemKind_value_')]
for baseClass in baseClasses:
for key in baseClass.__dict__.keys():
if key.startswith('itemKind_value_') \
and not key in itemKindOptionNames:
itemKindOptionNames.append(key)
itemKindOptions = {}
for itemKindOptionName in itemKindOptionNames:
itemKindOptions[itemKindOptionName[len('itemKind_value_'):]
] = getattr(self, itemKindOptionName)
itemKindOptionNames = [key
for key in options.keys()
if key.startswith('itemKind_value_')]
for itemKindOptionName in itemKindOptionNames:
itemKindOptions[itemKindOptionName[len('itemKind_value_'):]
] = options[itemKindOptionName]
del options[itemKindOptionName]
if options.has_key('itemKind_valueName'):
itemKindName = options['itemKind_valueName']
del options['itemKind_valueName']
else:
itemKindName = self.itemKind_valueName
2002-10-19 15:00:35 +02:00
if options.has_key('itemKind_valueClass'):
itemKindClass = options['itemKind_valueClass']
del options['itemKind_valueClass']
elif hasattr(self, 'itemKind_valueClass'):
itemKindClass = self.itemKind_valueClass
else:
itemKindClass = None
2002-10-19 15:00:35 +02:00
AbstractSequence.buildOptions(self, options)
if itemKindClass is not None:
realKindClass = commonTools.getThingClass(
'kind', itemKindClass._kindName)
class class_(itemKindClass, realKindClass):
pass
itemKind = class_()
itemKind.buildOptions(itemKindOptions)
self.itemKind = itemKind
elif itemKindName is not None:
itemKind = commonTools.newThing('kind', itemKindName)
itemKind.buildOptions(itemKindOptions)
self.itemKind = itemKind
#def checkModelValue(self, slot, value):
# AbstractSequence.checkModelValue(self, slot, value)
# if len(value or []) < self.requiredCount:
# raise faults.MissingSlotValue(slot)
#def getDefaultValue(self, slot):
# if self.defaultValue:
# return self.defaultValue
# return [self.itemKind.getDefaultValue(slot) \
# for i in range(self.minCount or 1)]
2002-10-19 15:00:35 +02:00
def getItemKind(self, index):
return self.itemKind
2002-10-19 15:00:35 +02:00
## def getModelLabel(self, slot):
## if self.label:
## return self.label
## return self.itemKind.getModelLabelPlural(self.getItemSlot(slot, 0))
## def getModelLabelPlural(self, slot):
## if self.labelPlural:
## return self.labelPlural
## return self.itemKind.getModelLabelPlural(self.getItemSlot(slot, 0))
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = AbstractSequence.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames = slotNames[:]
i = slotNames.index('maxCount')
slotNames[i:i] = ['itemKind']
return slotNames
def includes(self, kind):
if AbstractSequence.includes(self, kind):
return 1
if not isinstance(kind, Sequence):
return 0
2003-08-27 22:32:57 +02:00
if self.itemKind is None:
return 1
if kind.itemKind is None:
return 0
return self.itemKind.includes(kind.itemKind)
def intersects(self, kind):
if AbstractSequence.intersects(self, kind):
return 1
if not isinstance(kind, Sequence):
return 0
if self.itemKind is None or kind.itemKind is None:
return 1
return self.itemKind.intersects(kind.itemKind)
def isEmptyModelValue(self, slot, value):
return not value
2002-10-19 15:00:35 +02:00
register(Sequence)
class AcceptedRoles(Sequence):
balloonHelp = N_('Select accepted Glasnost objects types. '\
'Click on "Apply" to update the list proposed below.')
containerNames = ['Any', 'Sequence']
defaultValue = [ '__all__' ]
defaultValue_kindName = 'AcceptedRoles'
itemKind_kind_importExport = 'private'
itemKind_kind_stateInEditMode = 'hidden'
itemKind_kind_stateInViewMode = 'hidden'
itemKind_value_allowAll = 1
itemKind_value_allowNone = 1
itemKind_valueName = 'ServerRole'
label = N_('Accepted Types')
minCount = 1
thingPublicCategory = None # N_('Data')
thingPublicName = N_('Accepted Roles')
register(AcceptedRoles)
class UsersSet(Sequence):
containerNames = ['Any', 'Sequence']
defaultValue_kindName = 'UsersSet'
itemKind_kind_importExport = 'private'
itemKind_kind_stateInEditMode = 'hidden'
itemKind_kind_stateInViewMode = 'hidden'
itemKind_value_permanentIds = [system.generalPublicId,
system.loggedUsersGroupId]
itemKind_value_serverRoles = ['groups', 'identities']
itemKind_valueName = 'Id'
label = N_('Users')
minCount = 0
thingPublicCategory = N_('People Set')
thingPublicName = N_('Users')
def getDefaultValue(self, slot):
userId = context.getVar('userId')
if userId:
return [userId]
else:
return None
register(UsersSet)
class AuthorsSet(UsersSet):
balloonHelp = N_('Choose the author(s) for this object.')
containerNames = ['Any', 'Sequence']
defaultValue_kindName = 'AuthorsSet'
# Remove generelPublic from the menu, because the authorsSet must be
# countable.
# FIXME: that's useless since the user may "visit" the group and it will
# be shown nevertheless
itemKind_value_permanentIds = None
itemKind_value_serverRoles = ['groups', 'people']
label = N_('Authors')
thingPublicName = N_('Authors')
def getDefaultValue(self, slot):
user = context.getVar('user')
if user is not None and user.personId is not None:
return [user.personId]
else:
return None
register(AuthorsSet)
class Properties(Sequence):
itemKind_kind_importExport = 'private'
itemKind_kind_stateInEditMode = 'hidden'
itemKind_kind_stateInViewMode = 'hidden'
itemKind_value_valueThingCategory = 'other'
itemKind_value_valueThingName = 'Property'
itemKind_valueName = 'Thing'
label = N_('Properties')
stateInViewMode = 'read-only/hidden-if-empty'
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Properties')
widget_reorderingButtons = 0
widgetName = 'Multi'
def exportValueToXmlRpc(self, slot, value):
if value is None:
return []
exportedValue = []
for i in range(len(value)):
property = value[i]
propertySlot = self.getPropertySlot(slot, property.name)
exportedProperty = propertySlot.getKind().exportValueToXmlRpc(
propertySlot, property)
exportedValue.append(exportedProperty)
return exportedValue
def getItemSlot(self, slot, index):
return slots.PropertiesItem(index, parent = slot)
def getModelSlotByPath(self, slot, path):
if path.startswith('self'):
path = path[len('self'):]
if not path:
return slot
if path[0] != '[' or not ']' in path:
raise Exception('Path "%s" not found' % path)
key = eval(path[1:path.index(']')], {})
if type(key) in (types.StringType, types.UnicodeType):
# Key is a property name.
# FIXME: We should raise Exception('Path "%s" not found' % path),
# when there is no property named key.
kind = slot.getContainer().getDirectPropertyValueKind(key)
if kind is None:
kind = slot.getContainer().getPropertyValueKind(key)
kind = copy.deepcopy(kind)
property = commonTools.newThing('other', 'Property')
property.kind = kind
property.name = key
return property.getSlotByPath(
path[path.index(']') + 1:],
parentSlot = slot.getContainer().getPropertySlot(
key, parentSlot = slot.parent))
else:
# Key is an integer index.
return self.getItemKind(key).getModelSlotByPath(
self.getItemSlot(slot, key), path[path.index(']') + 1:])
def getPropertySlot(self, slot, name):
return slots.Property(name, parent = slot)
def importValueFromXmlRpc(self, slot, importedValue):
if importedValue is None:
return []
value = []
slot.value = value
for i in range(len(importedValue)):
importedProperty = importedValue[i]
propertyName = importedProperty['name']
propertySlot = self.getPropertySlot(slot, propertyName)
value.append(propertySlot.getKind().importValueFromXmlRpc(
propertySlot, importedProperty))
del slot.value
return value
register(Properties)
class ReadersSet(UsersSet):
balloonHelp = N_(
'Select one or more [readers->readers-and-editors] or groups of readers for '\
'this [object->objects] (Readers are allowed to view objects, they have '\
'read access to them). '\
'Click on "[Others->buttons-others]" if your choice is not proposed in the '\
'list. Click on "Add" to add another one. '\
'Select "None" to remove one.')
containerNames = ['Any', 'Sequence', 'UsersSet']
defaultValue_kindName = 'ReadersSet'
label = N_('Readers')
thingPublicName = N_('Readers')
2002-12-02 01:44:03 +01:00
register(ReadersSet)
2002-10-19 15:00:35 +02:00
class ServerId(Id):
containerNames = ['Any', 'String']
defaultValue_kindName = 'ServerId'
2003-05-20 19:24:43 +02:00
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Glasnost Server ID')
## widgetName = 'SelectServerId'
widget_size = 40
widgetName = 'InputText'
def newJail(self, slot):
return jails.String(slot)
def removeValueIds(self, slot, value, rolesToKeep):
return value
2002-10-19 15:00:35 +02:00
register(ServerId)
class ServerRole(Choice):
allowAll = 0
allowAll_kindName = 'Boolean'
allowNone = 0
allowNone_kindName = 'Boolean'
containerNames = ['Any', 'String']
defaultValue_kindName = 'ServerRole'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Server Role')
def getLabels(self, slot):
roles = self.getValues(slot)
labels = {}
for role in roles:
if role in [None, '__all__']:
continue
common = getCommonForServerRole(role)
if common is None:
label = role
else:
label = common.objectsNameCapitalized
labels[role] = label
return labels
2002-10-19 15:00:35 +02:00
def getValues(self, slot):
from glasnost.proxy.DispatcherProxy import getRegisteredRoles
values = []
if self.allowNone:
values.append(None)
if self.allowAll:
values.append('__all__')
registeredRoles = getRegisteredRoles(context.getVar('dispatcherId'))
for role in registeredRoles:
common = getCommonForServerRole(role)
if common is None:
continue
if not hasattr(common, 'useObjectIds') or not common.useObjectIds:
continue
values.append(role)
return values
def newJail(self, slot):
return jails.String(slot)
2002-10-19 15:00:35 +02:00
register(ServerRole)
class SlotName(Choice):
defaultValue_kindName = 'SlotName'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Slot Name')
register(SlotName)
2002-10-19 15:00:35 +02:00
class Source(BaseKind):
defaultValue_kindName = 'Source'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Glasnost')
2002-10-19 15:00:35 +02:00
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
return value.replace(sourceDispatcherId, destinationDispatcherId)
def removeValueIds(self, slot, value, rolesToKeep):
if not commonTools.extractRole(value) in rolesToKeep:
return None
return value
2002-10-19 15:00:35 +02:00
register(Source)
class String(BaseKind):
containerNames = ['Any']
defaultValue_kindName = 'String'
2002-10-19 15:00:35 +02:00
isTranslatable = 1
class isTranslatable_kindClass(BaseKind.isTranslatable_kindClass):
importExport = 'public'
stateInEditMode = 'read-write'
stateInViewMode = 'read-only'
possibleWidgetNames = ['InputText', 'TextArea']
pythonStorageType = types.StringType
class textFormat_kindClass(BaseKind.textFormat_kindClass):
importExport = 'public'
stateInEditMode = 'read-write'
stateInViewMode = 'read-only/hidden-if-empty'
class textMaxLength_kindClass(BaseKind.textMaxLength_kindClass):
importExport = 'public'
stateInEditMode = 'read-write'
stateInViewMode = 'read-only/hidden-if-empty'
thingPublicCategory = N_('Text')
thingPublicName = N_('Text')
class useFileStorage_kindClass(BaseKind.useFileStorage_kindClass):
importExport = 'public'
stateInEditMode = 'read-write'
stateInViewMode = 'read-only'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if self.isRequired and value == '':
raise faults.MissingSlotValue(slot)
if self.getTextFormat(slot) == 'html':
from xml.dom.minidom import parseString
import xml
try:
2007-12-18 21:04:56 +01:00
value = unicode(value,'iso-8859-15')
import codecs
value = codecs.utf_8_encode(value)[0]
parseString(value)
except xml.parsers.expat.ExpatError:
raise faults.BadSlotValue(slot, value)
def convertValueToOtherType(self, value, otherType):
if otherType is types.StringType:
return value
return BaseKind.convertValueToOtherType(self, value, otherType)
2002-10-19 15:00:35 +02:00
def getCmpFunction(self):
return locale.strcoll
def isEmptyModelValue(self, slot, value):
return not value
def newJail(self, slot):
return jails.String(slot)
2002-10-19 15:00:35 +02:00
register(String)
class Structure(AbstractSequence):
canInsertOrDelete = 0
containerNames = ['Any']
defaultValue_kindName = 'Structure'
2002-10-19 15:00:35 +02:00
parameters = None
parameters_kind_itemKind_value_valueThingCategory = 'other'
parameters_kind_itemKind_value_valueThingName = 'Parameter'
parameters_kind_itemKind_valueName = 'Thing'
2002-10-19 15:00:35 +02:00
parameters_kindName = 'Sequence'
thingPublicCategory = None # N_('Data')
thingPublicName = N_('Structure')
2002-10-19 15:00:35 +02:00
def getItemKind(self, index):
if self.parameters is None or index >= len(self.parameters):
return None
return self.parameters[index].kind
def isEmptyModelValue(self, slot, value):
if value is None:
return 1
for i in range(len(self.parameters)):
itemSlot = self.getItemSlot(slot, i)
if not itemSlot.getKind().isEmptyModelValue(itemSlot, value[i]):
return 0
return 1
2002-10-19 15:00:35 +02:00
register(Structure)
class Thing(Choice):
accessInCreateMode = None
class accessInCreateMode_kindClass:
_kindName = 'Choice'
importExport = 'private'
label = N_('Access in Creation Mode')
labels = {
'': N_('Same As Edition Mode'),
'embedded': N_('Embedded'),
'pointed': N_('Link'),
}
sortLabels = 0
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
values = [
None,
'embedded',
'pointed',
]
accessInEditMode = 'embedded'
class accessInEditMode_kindClass:
_kindName = 'Choice'
importExport = 'private'
isRequired = 1
label = N_('Access in Edition Mode')
labels = {
'embedded': N_('Embedded'),
'pointed': N_('Link'),
}
sortLabels = 0
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
values = [
'embedded',
'pointed',
]
accessInViewMode = 'embedded'
class accessInViewMode_kindClass:
_kindName = 'Choice'
importExport = 'private'
isRequired = 1
label = N_('Access in View Mode')
labels = {
'embedded': N_('Embedded'),
'pointed': N_('Link'),
}
sortLabels = 0
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
values = [
'embedded',
'pointed',
]
containerNames = ['Any']
defaultValue_kindName = 'Thing'
possibleWidgetNames = ['Thing']
pythonStorageType = types.InstanceType
thingPublicCategory = None # N_('Data')
thingPublicName = N_('Thing')
2002-10-19 15:00:35 +02:00
valueThingCategory = None
valueThingCategory_kind_stateInEditMode = 'hidden'
valueThingCategory_kind_stateInViewMode = 'hidden'
2002-10-19 15:00:35 +02:00
valueThingCategory_kindName = 'String'
valueThingName = None
valueThingName_kind_stateInEditMode = 'hidden'
valueThingName_kind_stateInViewMode = 'hidden'
2002-10-19 15:00:35 +02:00
valueThingName_kindName = 'String'
values_kind_importExport = 'private'
values_kind_stateInEditMode = 'hidden'
values_kind_stateInViewMode = 'hidden'
widgetName = 'Thing'
class widgetName_kindClass(Choice.widgetName_kindClass):
importExport = 'private'
def checkModelValue(self, slot, value):
# Pay attention: Use BaseKind instead of Choice.
BaseKind.checkModelValue(self, slot, value)
# TODO: check value is an instance of the appropriate class
def convertValueIds(self, slot, value, sourceDispatcherId,
destinationDispatcherId):
if value is None:
return None
value.convertIds(
sourceDispatcherId, destinationDispatcherId, parentSlot = slot)
return value
2002-10-19 15:00:35 +02:00
def convertValueToOtherType(self, value, otherType):
if otherType is types.StringType:
return value.getThingName()
return BaseKind.convertValueToOtherType(self, value, otherType)
def equals(self, kind):
if not Choice.equals(self, kind):
return 0
return self.valueThingCategory == kind.valueThingCategory \
and self.valueThingName == kind.valueThingName
def executeModel(self, slot, when, command = None):
value = slot.getValue()
if value is None:
return
value.execute(when, parentSlot = slot, command = command)
2002-10-19 15:00:35 +02:00
def exportValueToXmlRpc(self, slot, value):
if value is None:
return None
return value.exportToXmlRpc(parentSlot = slot)
2002-10-19 15:00:35 +02:00
def getGroupedValues(self, slot):
categories = []
groupedValues = {}
for thingClass in commonTools.getAllThingClasses().values():
if thingClass.thingCategory != self.valueThingCategory:
continue
if thingClass.thingPublicCategory is None:
continue
if not thingClass.thingPublicCategory in categories:
categories.append(thingClass.thingPublicCategory)
groupedValues[thingClass.thingPublicCategory] = []
groupedValues[thingClass.thingPublicCategory].append(
thingClass.getThingName.im_func(thingClass))
return groupedValues
#categories.sort(lambda x, y: locale.strcoll(_(x), _(y)))
#labels = self.getLabels(slot)
#for values in groupedValues.values():
# values.sort(lambda x, y:
# locale.strcoll(_(labels[x]), _(labels[y])))
def getGroupLabels(self, slot):
groupNames = self.getGroupedValues(slot).keys()
groupLabels = {}
for g in groupNames:
groupLabels[_(g)] = g
return groupLabels
def getDefaultValue(self, slot):
value = commonTools.newThing(
self.valueThingCategory, self.valueThingName)
return value.getDefaultValue(slot)
def getLabels(self, slot):
if self.labels is not None:
return self.labels
self.labels = {}
for thingClass in commonTools.getAllThingClasses().values():
if thingClass.thingCategory != self.valueThingCategory:
continue
value = thingClass.getThingName.im_func(thingClass)
self.labels[value] = _(
thingClass.getThingPublicName.im_func(thingClass) )
return self.labels
def getModelSlotByPath(self, slot, path):
value = slot.getValue()
if value is None:
value = commonTools.newThing(
self.valueThingCategory, self.valueThingName)
slot = slot.detach(value)
return value.getSlotByPath(path, parentSlot = slot)
def getModelWidget(self, slot, forceEmbedding = 0):
if forceEmbedding or self.isModelEmbedded(slot):
return Choice.getModelWidget(
self, slot, forceEmbedding = forceEmbedding)
else:
widget = commonTools.newThing('widget', 'Select')
widgetOptionHeader = 'widget_'
widgetOptionHeaderLen = len(widgetOptionHeader)
widgetOptionNames = [
name
for name in self.__dict__.keys()
if name.startswith(widgetOptionHeader) \
and not name.startswith(widgetOptionHeader + 'kind')]
baseClasses = self.getC3ClassLinearization()
for baseClass in baseClasses:
for name in baseClass.__dict__.keys():
if name.startswith(widgetOptionHeader) \
and not name.startswith(widgetOptionHeader + 'kind') \
and name not in widgetOptionNames:
widgetOptionNames.append(name)
widgetOptions = {}
for widgetOptionName in widgetOptionNames:
widgetOptions[widgetOptionName[widgetOptionHeaderLen:]
] = getattr(self, widgetOptionName)
widget.buildOptions(widgetOptions)
return widget
def getValues(self, slot):
if self.values is not None:
return self.values
self.values = [
thingClass.getThingName.im_func(thingClass)
for thingClass in commonTools.getAllThingClasses().values()
if thingClass.thingCategory == self.valueThingCategory \
and thingClass.thingPublicCategory is not None]
return self.values
2002-10-19 15:00:35 +02:00
def importValueFromXmlRpc(self, slot, importedValue):
if importedValue is None:
return None
value = commonTools.newThing(
importedValue['__thingCategory__'],
importedValue['__thingName__'])
slot.value = value
value.importFromXmlRpc(importedValue, parentSlot = slot)
del slot.value
2002-10-19 15:00:35 +02:00
return value
def includes(self, kind):
if Choice.includes(self, kind):
return 1
if self.getThingName() != kind.getThingName():
return 0
if self.valueThingCategory is None:
return 1
if self.valueThingCategory != kind.valueThingCategory:
return 0
if self.valueThingName is None:
return 1
return self.valueThingName == kind.valueThingName
def intersects(self, kind):
if Choice.intersects(self, kind):
return 1
if self.getThingName() != kind.getThingName():
return 0
if self.valueThingCategory is None or kind.valueThingCategory is None:
return 1
if self.valueThingCategory != kind.valueThingCategory:
return 0
if self.valueThingName is None or kind.valueThingName is None:
return 1
return self.valueThingName == kind.valueThingName
def isEmptyModelValue(self, slot, value):
if value is None:
return 1
if self.isModelEmbedded(slot):
return value.isEmpty(parentSlot = slot)
else:
return 0
def isModelEmbedded(self, slot):
layoutMode = context.getVar('layoutMode')
if layoutMode == 'edit':
isCreateEditMode = context.getVar('isCreateEditMode', default = 0)
if isCreateEditMode:
return self.accessInCreateMode == 'embedded' \
or self.accessInCreateMode is None \
and self.accessInEditMode == 'embedded'
else:
return self.accessInEditMode == 'embedded'
elif layoutMode == 'use':
return 1
else:
return self.accessInViewMode == 'embedded'
def newJail(self, slot):
if self.valueThingCategory == 'object':
return jails.Object(slot)
else:
return jails.Thing(slot)
def removeValueIds(self, slot, value, rolesToKeep):
if value is None:
return None
value.removeIds(rolesToKeep, parentSlot = slot)
return value
def repairValue(self, slot, value, toVersion):
if toVersion == 4000:
changed = value.repair(toVersion, parentSlot = slot)
if changed:
return value
return None
def setToDefaultValue(self, slot):
if self.isModelEmbedded(slot):
slot, value = self.getCreatedModelSlotAndValue(slot)
if self.getDefaultValue(slot):
slot.getKind().setToDefaultValue(slot)
else:
BaseKind.setToDefaultValue(self, slot)
def upgradeModel(self, slot, model, toVersion):
changed, model = BaseKind.upgradeModel(self, slot, model, toVersion)
if model is not None:
if model.upgrade(toVersion, parentSlot = slot):
changed = 1
return changed, model
2002-10-19 15:00:35 +02:00
register(Thing)
class Union(BaseKind):
containerNames = ['Any']
defaultValue_kindName = 'Union'
isPractical = 0
items = None
items_kind_itemKind_valueName = 'Kind'
items_kind_label = N_('Items')
items_kindName = 'Sequence'
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Union')
def equals(self, kind):
if not BaseKind.equals(self, kind):
return 0
if not self.items or not kind.items:
return 0
if len(self.items) != len(kind.items):
return 0
for item in self.items:
for kindItem in kind.items:
if item.equals(kindItem):
break
else:
return 0
return 1
def includes(self, kind):
if BaseKind.includes(self, kind):
return 1
if self.items is not None:
for item in self.items:
if item.includes(kind):
return 1
return 0
def intersects(self, kind):
if BaseKind.intersects(self, kind):
return 1
if self.getThingName() != kind.getThingName():
if not self.items or not kind.items:
return 0
for item in self.items:
for kindItem in kind.items:
if item.intersects(kindItem):
return 1
return 0
if self.items is not None:
for item in self.items:
if item.intersects(kind):
return 1
return 0
register(Union)
class CreationTime(Time):
defaultValue_kindName = 'CreationTime'
importExport = 'from-server-only'
isAutomaticallyModified = 1
class isRequired_kindClass(Time.isRequired_kindClass):
importExport = 'private'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
label = N_('Creation Time')
stateInEditMode = 'read-only'
thingPublicName = N_('Creation Time')
def accepts(self, kind):
if isinstance(kind, Time):
return 1
return Time.accepts(self, kind)
def setAutomaticalValue(self, slot, init = 0):
if init:
slot.setValue(time.time())
register(CreationTime)
class ModificationTime(Time):
defaultValue_kindName = 'ModificationTime'
importExport = 'from-server-only'
isAutomaticallyModified = 1
class isRequired_kindClass(Time.isRequired_kindClass):
importExport = 'private'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
label = N_('Modification Time')
stateInEditMode = 'read-only'
thingPublicName = N_('Modification Time')
def setAutomaticalValue(self, slot, init = 0):
slot.setValue(time.time())
register(ModificationTime)
2002-10-19 15:00:35 +02:00
class Token(BaseKind):
containerNames = ['Any', 'String']
defaultValue_kindName = 'Token'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Text')
thingPublicName = N_('Token')
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
if value is None:
return None
return value.replace(sourceDispatcherId, destinationDispatcherId)
def newJail(self, slot):
return jails.String(slot)
2002-10-19 15:00:35 +02:00
register(Token)
class ApplicationToken(Token):
containerNames = ['Any', 'String', 'Token']
defaultValue_kindName = 'ApplicationToken'
thingPublicName = N_('Application Token')
2002-10-19 15:00:35 +02:00
register(ApplicationToken)
class UserToken(Token):
containerNames = ['Any', 'String', 'Token']
defaultValue_kindName = 'UserToken'
thingPublicName = N_('User Token')
2002-10-19 15:00:35 +02:00
register(UserToken)
class TranslationToAdd(BaseKind):
defaultValue_kindName = 'TranslationToAdd'
thingPublicCategory = None
2002-10-19 15:00:35 +02:00
register(TranslationToAdd)
class TranslatorsSets(BaseKind):
defaultValue_kindName = 'TranslatorsSets'
pythonStorageType = types.DictType
thingPublicCategory = None # N_('Glasnost')
2002-10-19 15:00:35 +02:00
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
for translationName, translatorsSet in value.items():
if translatorsSet:
for i in range(len(translatorsSet)):
id = translatorsSet[i]
newId = id.replace(
sourceDispatcherId, destinationDispatcherId)
if newId != id:
translatorsSet[i] = newId
return value
def removeValueIds(self, slot, value, rolesToKeep):
for translationName, translatorsSet in value.items():
if translatorsSet:
r = range(len(translatorsSet))
r.reverse()
for i in r:
id = translatorsSet[i]
if not commonTools.extractRole(id) in rolesToKeep:
del translatorsSet[i]
if not translatorsSet:
del value[translationName]
if not value:
return None
return value
def repairValue(self, slot, value, toVersion):
if toVersion == 4000:
changed = 0
for translationName, translatorsSet in value.items():
if translatorsSet:
for i in range(len(translatorsSet)):
id = translatorsSet[i]
newId = repairId(id)
if newId:
changed = 1
translatorsSet[i] = newId
if changed:
return value
2002-10-19 15:00:35 +02:00
return None
def upgradeModel_0001_0028(self, slot, model):
"""Convert user ids from "people" to "identities"."""
changed = 0
model = slot.getValue()
if model:
changed = 1
for key in model.keys():
model[key] = [x.replace('/people', '/identities') \
for x in model[key]]
return changed, model
2002-10-19 15:00:35 +02:00
register(TranslatorsSets)
class WritersSet(UsersSet):
balloonHelp = N_(
'Select one or more [editors->readers-and-editors] or groups of editors '\
'for this [object->objects] (Editors can modify or delete objects). '\
'Click on "[Others->buttons-others]" if your choice is not proposed in the '\
'list. Click on "Add" to add another one. '\
'Select "None" to remove one.')
containerNames = ['Any', 'Sequence', 'UsersSet']
defaultValue_kindName = 'WritersSet'
label = N_('Editors')
thingPublicName = N_('Editors')
2002-12-02 10:43:46 +01:00
register(WritersSet)
2003-01-07 22:34:31 +01:00
class XChoice(Choice):
defaultValue_kindName = 'XChoice'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Choice')
thingPublicName = N_('Extended Choice')
2003-01-07 22:34:31 +01:00
widgetName = 'XSelect'
register(XChoice)
class Command(BaseKind):
action = None
class action_kindClass:
_kindName = 'PythonIdentifier'
label = N_('Action')
defaultValue_kindName = 'Command'
nextModeName = None
class nextModeName_kindClass:
_kindName = 'PythonIdentifier'
label = N_('Next Mode')
nextObjectId = None
class nextObjectId_kindClass:
_kindName = 'Id'
label = N_('Next Object')
possibleWidgetNames = ['PushButton']
thingPublicCategory = N_('Links')
thingPublicName = N_('Push Button')
widgetName = 'PushButton'
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = BaseKind.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['action', 'nextObjectId', 'nextModeName']
return slotNames
register(Command)
class Fault(Thing):
defaultValue_kindName = 'Fault'
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Fault')
valueThingCategory = 'other'
valueThingName = 'Fault'
register(Fault)
## class InputConnector(Thing):
## defaultInput_kindName = 'InputConnector'
## thingPublicCategory = None # N_('Glasnost')
## thingPublicName = N_('Input Connector')
## valueThingCategory = 'other'
## valueThingName = 'InputConnector'
## register(InputConnector)
2002-10-19 15:00:35 +02:00
class Kind(Thing):
accessInEditMode = 'pointed'
accessInViewMode = 'pointed'
defaultValue_kindName = 'Kind'
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Kind')
2002-10-19 15:00:35 +02:00
valueThingCategory = 'kind'
valueThingName = 'BaseKind'
def convertValueFromOtherType(self, value):
if type(value) is types.StringType and value:
return commonTools.newThing('kind', value)
return BaseKind.convertValueFromOtherType(self, value)
2002-10-19 15:00:35 +02:00
register(Kind)
class KindName(Choice):
defaultValue_kindName = 'KindName'
pythonStorageType = types.StringType
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Kind Name')
## def __init__(self, **attributes):
## Choice.__init__(self, **attributes)
## self.values = [
## kindClass.getThingName.im_func(kindClass)
## for kindClass in commonTools.getAllThingClasses().values()
## if kindClass.thingCategory == 'kind']
def getGroupedValues(self, slot):
categories = []
groupedValues = {}
for kindClass in commonTools.getAllThingClasses().values():
if kindClass.thingCategory != 'kind':
continue
if kindClass.thingPublicCategory is None:
continue
if not kindClass.thingPublicCategory in categories:
categories.append(kindClass.thingPublicCategory)
groupedValues[kindClass.thingPublicCategory] = []
groupedValues[kindClass.thingPublicCategory].append(
kindClass.getThingName.im_func(kindClass))
for values in groupedValues.values():
values.sort(lambda x, y:
locale.strcoll(_(labels[x]), _(labels[y])))
return groupedValues
def getGroupLabels(self, slot):
categories = self.getGroupedValues(slot).keys()
groupLabels = {}
for cat in categories:
groupLabels[_(cat)] = cat
return categories
def getValues(self, slot):
return [
kindClass.getThingName.im_func(kindClass)
for kindClass in commonTools.getAllThingClasses().values()
if kindClass.thingCategory == 'kind' \
and kindClass.thingPublicCategory is not None]
register(KindName)
class Mode(Thing):
accessInEditMode = 'pointed'
accessInViewMode = 'pointed'
defaultValue_kindName = 'Mode'
isRequired = 1 # Important for submitField2.
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Mode')
valueThingCategory = 'mode'
valueThingName = 'ModeAbstract'
def convertValueFromOtherType(self, value):
if not value:
return None
if type(value) is types.StringType:
return commonTools.newThing('mode', value)
return BaseKind.convertValueFromOtherType(self, value)
def convertValueToOtherType(self, value, otherType):
if otherType is types.StringType and value:
return value.getThingName()
return BaseKind.convertValueToOtherType(self, value, otherType)
def getGroupedValues(self, slot):
return None
register(Mode)
## class OutputConnector(Thing):
## defaultOutput_kindName = 'OutputConnector'
## thingPublicCategory = None # N_('Glasnost')
## thingPublicName = N_('Output Connector')
## valueThingCategory = 'other'
## valueThingName = 'OutputConnector'
## register(OutputConnector)
class Upload(Thing):
defaultValue_kindName = 'Upload'
thingPublicCategory = N_('Data')
thingPublicName = N_('File')
valueThingCategory = 'other'
valueThingName = 'Upload'
widgetName = 'UploadFile'
register(Upload)
class ValueHolder(Thing):
defaultValue_kindName = 'ValueHolder'
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Value Holder')
valueThingCategory = 'other'
valueThingName = 'ValueHolder'
register(ValueHolder)
2002-10-19 15:00:35 +02:00
class Widget(Thing):
accessInEditMode = 'pointed'
accessInViewMode = 'pointed'
defaultValue_kindName = 'Widget'
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Widget')
2002-10-19 15:00:35 +02:00
valueThingCategory = 'widget'
valueThingName = 'BaseWidget'
def convertValueFromOtherType(self, value):
if type(value) is types.StringType and value:
return commonTools.newThing('widget', value)
return BaseKind.convertValueFromOtherType(self, value)
2002-10-19 15:00:35 +02:00
register(Widget)
class WidgetName(Choice):
defaultValue_kindName = 'WidgetName'
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Widget Name')
def getValues(self, slot):
values = Choice.getValues(self, slot)
if values:
return values
else:
return ['InputText']
register(WidgetName)