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

2798 lines
87 KiB
Python

# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# 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.
from __future__ import nested_scopes
__doc__ = """Glasnost Common Kinds"""
__version__ = '$Revision$'[11:-2]
import base64
import copy
import locale
import marshal
import time
import types
import slots
import translation
import things
import system
from tools import *
import tools_new as commonTools
import connectors # Do not remove!
import functions # Do not remove!
import properties # Do not remove!
import uploads # Do not remove!
import values # Do not remove!
import views # Do not remove!
import widgets # Do not remove!
register = things.register
class BaseKind(things.BaseThing):
balloonHelp = None
balloonHelp_kind_label = N_('Balloon Help')
balloonHelp_kind_widgetName = 'TextArea'
balloonHelp_kindName = 'String'
category = None
category_kind_importExport = 'private'
category_kind_label = N_('Category')
category_kindName = 'String'
containerNames = None
containerNames_kind_importExport = 'private'
containerNames_kind_itemKind_valueName = 'KindName'
containerNames_kind_label = N_('Containers')
containerNames_kindName = 'Sequence'
defaultValue = None
defaultValue_kind_importExport = 'private'
defaultValue_kind_label = N_('Default Value')
defaultValue_kindName = None # To override
## helpAlias = None
## helpAlias_kind_label = N_('Help Alias')
## helpAlias_kindName = 'Alias'
hideLabel = 0
hideLabel_kind_importExport = 'private'
hideLabel_kind_label = N_('Hidden Label')
hideLabel_kindName = 'Boolean'
importExport = 'public'
importExport_kind_label = N_('Import/Export')
importExport_kind_labels = {
'from-server-only': N_('From Server Only'),
'private': N_('Private'),
'public': N_('Public'),
'to-server-only': N_('To Server Only'),
}
importExport_kind_values = [
'private',
'to-server-only',
'from-server-only',
'public',
]
importExport_kindName = 'Choice'
isAutomaticalyModified = 0
isAutomaticalyModified_kind_importExport = 'private'
isAutomaticalyModified_kindName = 'Boolean'
# 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
isPractical_kind_importExport = 'private'
isPractical_kindName = 'Boolean'
isRequired = 0
isRequired_kind_label = N_('Mandatory')
## isRequired_kind_labels = {
## '0': N_('Optional'),
## '1': N_('Required'),
## }
isRequired_kindName = 'Boolean'
isTranslatable = 0
isTranslatable_kind_importExport = 'private'
isTranslatable_kind_label = N_('Translatable')
## isTranslatable_kind_labels = {
## '0': N_('Invariant'),
## '1': N_('Translatable'),
## }
isTranslatable_kindName = 'Boolean'
label = None
label_kind_label = N_('Label')
label_kindName = 'String'
labelPlural = None
labelPlural_kind_importExport = 'private'
labelPlural_kind_label = N_('Label (plural form)')
labelPlural_kindName = 'String'
name = None
name_kind_importExport = 'private'
name_kind_label = N_('Name')
name_kindName = 'String'
possibleWidgetNames = None
possibleWidgetNames_kind_importExport = 'private'
possibleWidgetNames_kind_itemKind_valueName = 'WidgetName'
possibleWidgetNames_kindName = 'Sequence'
stateInEditMode = 'read-write'
stateInEditMode_kind_label = N_('State In "Edit" Mode')
stateInEditMode_kind_labels = {
'hidden': N_('Hidden'),
'read-only': N_('Read Only'),
'read-write': N_('Read/Write'),
}
stateInEditMode_kind_values = [
'hidden',
'read-only',
'read-write',
]
stateInEditMode_kindName = 'Choice'
stateInUseMode = 'read-only'
stateInUseMode_kind_label = N_('State In "Use" Mode')
stateInUseMode_kind_labels = {
'hidden': N_('Hidden'),
'read-only': N_('Read Only'),
'read-write': N_('Read/Write'),
}
stateInUseMode_kind_values = [
'hidden',
'read-only',
'read-write',
]
stateInUseMode_kindName = 'Choice'
stateInViewMode = 'read-only'
stateInViewMode_kind_label = N_('State In "View" Mode')
stateInViewMode_kind_labels = {
'hidden': N_('Hidden'),
'read-only': N_('Read Only'),
}
stateInViewMode_kind_values = [
'hidden',
'read-only',
]
stateInViewMode_kindName = 'Choice'
thingCategory = 'kind'
useCustomStorage = 0
useCustomStorage_kind_importExport = 'private'
useCustomStorage_kindName = 'Boolean'
useFileStorage = 0
useFileStorage_kind_importExport = 'from-server-only'
useFileStorage_kind_label = N_('Storage')
useFileStorage_kind_labels = {
'0': N_('Internal'),
'1': N_('In External File'),
}
useFileStorage_kindName = 'Boolean'
widget = None
widget_kind_importExport = 'private'
widget_kind_valueThingNameSlotName = 'widgetName'
widget_kindName = 'Widget'
widgetName = 'InputText'
widgetName_kind_label = N_('Graphical Component')
widgetName_kind_valuesGetterName = 'getWidgetNameValues'
widgetName_kindName = 'WidgetName'
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 __str__(self):
return self.getName()
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)
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 convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
assert self.isPractical
return value
def equals(self, kind):
"""Test whether two kinds are equal."""
return self.getName() == kind.getName()
def exportValueToXmlRpc(self, slot, value):
assert self.isPractical
if type(value) in (types.StringType, types.UnicodeType):
value = utf8(value)
return value
def getBalloonHelp(self):
return self.balloonHelp
def getCmpFunction(self):
return cmp
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)
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 getName(cls):
if type(cls) == types.InstanceType:
cls = cls.__class__
if cls.name:
name = cls.name
else:
name = cls.getThingName.im_func(cls)
return name
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = things.BaseThing.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += [
'category', 'name', 'label', 'labelPlural', 'hideLabel',
'widgetName', 'widget', 'stateInEditMode', 'stateInViewMode',
'stateInUseMode', 'isRequired', 'defaultValue', 'balloonHelp',
## 'helpAlias',
'importExport', 'useFileStorage', 'useCommonStorage']
return slotNames
def getPossibleWidgetNames(self):
assert self.isPractical
if self.possibleWidgetNames is not None:
return self.possibleWidgetNames
return [self.widgetName]
def getWidgetNameValues(self, widgetNameSlot, fields):
kindSlot = widgetNameSlot.parent
return kindSlot.getValue().getPossibleWidgetNames()
def importValueFromXmlRpc(self, slot, value):
assert self.isPractical
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
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 isExportable(self):
raise NotImplementedError
def isImportable(self):
raise NotImplementedError
def isInCore(self, slot):
return not self.useCustomStorage and not self.useFileStorage
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 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
return None
def saveNonCoreValue(self, slot, objectDirectoryPath):
pass
def setAutomaticalValue(self, slot, init = 0):
raise NotImplementedError
register(BaseKind)
class AbstractSequence(BaseKind):
maxCount = None
maxCount_kindName = 'Integer'
maxCountGetterName = None
maxCountGetterName_kindName = 'PythonIdentifier'
widgetName = 'Multi'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value:
if type(value) is not types.ListType:
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))
for i in range(len(value)):
itemSlot = self.getItemSlot(slot, i)
newItem = itemSlot.getKind().convertValueIds(
itemSlot, value[i], sourceDispatcherId,
destinationDispatcherId)
if newItem != value[i]:
value[i] = newItem
return value
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
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 importValueFromXmlRpc(self, slot, importedValue):
if importedValue is None:
return []
value = []
slot.value = value
for i in range(len(importedValue)):
itemSlot = self.getItemSlot(slot, i)
value.append(itemSlot.getKind().importValueFromXmlRpc(
itemSlot, importedValue[i]))
del slot.value
return value
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
return None
class Alias(BaseKind):
category = N_('Glasnost')
defaultValue_kindName = 'Alias'
name = N_('Alias')
register(Alias)
class Amount(BaseKind):
## category = N_('Numbers')
defaultValue_kindName = 'Amount'
name = N_('Amount')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.IntType:
raise faults.BadSlotValue(slot, value)
register(Amount)
class Any(BaseKind):
category = N_('Glasnost')
defaultValue_kindName = 'Any'
isPractical = 0
name = N_('Any')
register(Any)
class Boolean(BaseKind):
category = N_('Numbers')
containerNames = ['Any']
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'
name = N_('Boolean')
possibleWidgetNames = ['InputCheckBox', 'PushButton', 'Select']
sortLabels = 0
sortLabels_kindName = '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_valueKind_valueName = 'String'
titles_kindName = 'Mapping'
values = [0, 1]
values_kind_importExport = 'private'
values_kind_itemKind_valueName = 'Boolean'
values_kindName = 'Sequence'
widgetName = 'InputCheckBox'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and value not in self.values:
raise faults.BadSlotValue(slot, value)
def getGroupedValues(self, slot, fields):
return (None, None) # groupNames, groupedValues
def getLabels(self, slot, fields):
return self.labels
def getSortedValues(self, slot, fields):
values = self.getValues(slot, fields)
if values is not None:
values = values[:]
labels = self.getLabels(slot, fields)
values.sort(lambda x, y:
locale.strcoll(_(labels[x]), _(labels[y])))
return values
def getValues(self, slot, fields):
return self.values
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = BaseKind.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['values', 'labels', 'titles']
return slotNames
register(Boolean)
class Choice(BaseKind):
category = N_('Choice')
defaultValue_kindName = 'Choice'
groupedValues = None
groupedValues_kind_importExport = 'private'
groupedValues_kind_keyKind_valueName = 'String'
groupedValues_kind_valueKind_valueName = 'String'
groupedValues_kindName = 'Mapping'
groupedValuesGetterName = None
groupedValuesGetterName_kindName = 'PythonIdentifier'
groupNames = None
groupNames_kind_importExport = 'private'
groupNames_kind_itemKind_valueName = 'String'
groupNames_kindName = 'Sequence'
groupNamesGetterName = None
groupNamesGetterName_kindName = 'PythonIdentifier'
labels = None
labels_kind_keyKind_valueName = 'String'
labels_kind_label = N_('Labels')
labels_kind_valueKind_valueName = 'String'
labels_kindName = 'Mapping'
name = N_('Choice')
possibleWidgetNames = ['InputCheckBox', 'Select']
sortLabels = 1
sortLabels_kindName = '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_valueKind_valueName = 'String'
titles_kindName = 'Mapping'
values = None
values_kind_importExport = 'private'
values_kind_itemKind_valueName = 'String'
values_kindName = 'Sequence'
valuesGetterName = None
valuesGetterName_kindName = 'PythonIdentifier'
widgetName = 'Select'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and self.values and value not in self.values:
raise faults.BadSlotValue(slot, value)
def getGroupedValues(self, slot, fields):
if self.groupedValuesGetterName:
currentSlot = slot
while currentSlot is not None:
container = currentSlot.getContainer()
try:
groupedValuesGetter = getattr(container,
self.groupedValuesGetterName)
self.groupedValues = groupedValuesGetter(slot, fields)
if self.groupNamesGetterName:
groupNamesGetter = getattr(container,
self.groupNamesGetterName)
self.groupNames = groupNamesGetter(slot, fields)
break
except AttributeError:
currentSlot = currentSlot.parent
continue
return (self.groupNames, self.groupedValues)
def getLabels(self, slot, fields):
if self.labels:
return self.labels
labels = {}
values = self.getValues(slot, fields)
if values is not None:
for value in values:
labels[str(value)] = str(value)
return labels
def getSortedValues(self, slot, fields):
values = self.getValues(slot, fields)
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, fields)
values.sort(lambda x, y: locale.strcoll(_(labels[x]), _(labels[y])))
sortedValues += values
return sortedValues
def getValues(self, slot, fields):
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, fields)
assert type(groupedValues) is type({})
values = []
for group in groupedValues.keys():
assert type(groupedValues[group]) is type([])
values += groupedValues[group]
return values
return []
valuesGetterName = self.valuesGetterName
if valuesGetterName is not None:
currentSlot = slot
while currentSlot is not None:
container = currentSlot.getContainer()
try:
valuesGetter = getattr(container, valuesGetterName)
except AttributeError:
currentSlot = currentSlot.parent
continue
return valuesGetter(slot, fields)
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 []
register(Choice)
class Data(BaseKind):
category = N_('Compound')
defaultValue_kindName = 'Data'
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):
category = N_('Date & Time')
defaultValue_kindName = 'Time'
formatString = '%Y-%m-%d %H:%M:%S'
formatString_kindName = 'String'
name = N_('Time')
widgetName = 'Time'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) not in [types.IntType, types.FloatType]:
raise faults.BadSlotValue(slot, value)
register(Time)
class Date(Time):
requiredParts = ['year', 'month', 'day']
requiredParts_kind_itemKind_valueName = 'String'
requiredParts_kindName = 'Sequence'
name = N_('Date')
def repairValue(self, slot, value, toVersion):
if type(value) is types.StringType:
if value[-2:] == '00':
repairedValue = time.mktime(time.strptime(value[:-2], '%Y%m'))
else:
repairedValue = time.mktime(time.strptime(value, '%Y%m%d'))
if repairedValue != value:
return repairedValue
return None
register(Date)
class DispatcherId(BaseKind):
category = N_('Glasnost')
containerNames = ['Any', 'String']
defaultValue_kindName = 'DispatcherId'
name = N_('Dispatcher ID')
widget_size = 40
widgetName = 'InputText'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.StringType:
raise faults.BadSlotValue(slot, value)
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
return value.replace(sourceDispatcherId, destinationDispatcherId)
register(DispatcherId)
class Duration(BaseKind):
category = N_('Date & Time')
defaultValue_kindName = 'Duration'
requiredParts = ['day', 'hour', 'minute', 'second']
requiredParts_kind_itemKind_valueName = 'String'
requiredParts_kindName = 'Sequence'
name = N_('Duration')
widgetName = 'Duration'
register(Duration)
class Email(BaseKind):
category = N_('Text')
containerNames = ['Any', 'String']
defaultValue_kindName = 'Email'
name = N_('Email Address')
widgetName = 'Email'
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 len(value) > 100:
raise faults.BadSlotValue(slot, value)
register(Email)
class Fields(BaseKind):
category = N_('Glasnost')
containerNames = ['Any']
defaultValue_kindName = 'Fields'
name = N_('Fields')
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):
category = N_('Text')
checkFilePath = 1
checkFilePath_kindName = 'Boolean'
containerNames = ['Any', 'String']
defaultValue_kindName = 'Path'
name = N_('Path')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.StringType:
raise faults.BadSlotValue(slot, value)
register(Path)
class FilePath(Path):
category = N_('Text')
containerNames = ['Any', 'String']
defaultValue_kindName = 'FilePath'
name = N_('File Path')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.StringType:
raise faults.BadSlotValue(slot, value)
register(FilePath)
class Fingerprint(BaseKind):
category = N_('Text')
containerNames = ['Any', 'String']
defaultValue_kindName = 'Fingerprint'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.StringType:
raise faults.BadSlotValue(slot, value)
register(Fingerprint)
class Float(BaseKind):
category = N_('Numbers')
defaultValue_kindName = 'Float'
name = N_('Float Number')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) not in [types.IntType, types.FloatType]:
raise faults.BadSlotValue(slot, value)
register(Float)
class FunctionName(Choice):
category = N_('Glasnost')
defaultValue_kindName = 'FunctionName'
name = N_('Function Name')
serverIdSlotName = None
serverIdSlotName_kindName = 'String'
def checkModelValue(self, slot, value):
Choice.checkModelValue(self, slot, value)
if value and type(value) is not types.StringType:
raise faults.BadSlotValue(slot, value)
def getValues(self, slot, fields):
if not self.serverIdSlotName:
return []
serverId = slot.getContainer().getSlot(
self.serverIdSlotName, parentSlot = slot.parent).getField(fields)
if not serverId:
return []
try:
serverRole = commonTools.extractRole(serverId)
except: # TODO: tighter check
return []
from glasnost.proxy.tools import getProxyForServerRole
try:
proxy = getProxyForServerRole(serverRole)
except: # TODO: tighter check
return []
if proxy is None:
return []
try:
functionDeclarations = proxy.getFunctionDeclarations()
except: # TODO: tighter check
return []
return functionDeclarations.keys()
register(FunctionName)
class Id(BaseKind):
category = N_('Glasnost')
containerNames = ['Any']
defaultValue_kindName = 'Id'
permanentIds = None
name = N_('Object ID')
serverRoles = None
serverRoles_kind_itemKind_valueName = 'ServerRole'
serverRoles_kindName = 'Sequence'
valuesGetterName = None
valuesGetterName_kindName = 'PythonIdentifier'
widgetName = 'SelectId'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value:
try:
commonTools.extractDispatcherId(value)
except:
raise faults.BadSlotValue(slot, value)
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
return value.replace(sourceDispatcherId, destinationDispatcherId)
def equals(self, kind):
if not BaseKind.equals(self, kind):
return 0
return self.serverRoles == kind.serverRoles
def getServerRoles(self):
return self.serverRoles
def getValues(self, slot, fields):
valuesGetterName = self.valuesGetterName
if valuesGetterName is None:
raise 'FIXME: getValues called while valuesGetterName was not set'
currentSlot = slot
while currentSlot is not None:
container = currentSlot.getContainer()
try:
valuesGetter = getattr(container, valuesGetterName)
except AttributeError:
currentSlot = currentSlot.parent
continue
return valuesGetter(slot, fields)
return []
def includes(self, kind):
if BaseKind.includes(self, kind):
return 1
if self.getName() != kind.getName():
return 0
if not self.serverRoles:
return 1
if not kind.serverRoles:
return 0
for kindServerRole in kind.serverRoles:
if not kindServerRole in self.serverRoles:
return 0
return 1
def intersects(self, kind):
if BaseKind.intersects(self, kind):
return 1
if self.getName() != kind.getName():
return 0
if not self.serverRoles or not kind.serverRoles:
return 1
for kindServerRole in kind.serverRoles:
if kindServerRole in self.serverRoles:
return 1
return 0
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
register(Id)
class Integer(BaseKind):
category = N_('Numbers')
containerNames = ['Any']
defaultValue_kindName = 'Integer'
max = None
max_kind_label = N_('Maximum')
max_kindName = 'Integer'
min = None
min_kind_label = N_('Minimum')
min_kindName = 'Integer'
name = N_('Integer Number')
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 checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) not in [types.IntType, types.LongType]:
raise faults.BadSlotValue(slot, value)
register(Integer)
class IntegerChoice(Choice):
defaultValue_kindName = 'IntegerChoice'
name = N_('Integer Choice')
titles_kind_keyKind_valueName = 'Integer'
values_kind_itemKind_valueName = 'Integer'
def checkModelValue(self, slot, value):
Choice.checkModelValue(self, slot, value)
if value and type(value) is not types.IntType:
raise faults.BadSlotValue(slot, value)
register(IntegerChoice)
class LanguageChoice(Choice):
category = N_('Choice')
containerNames = ['Any']
defaultValue_kindName = 'LanguageChoice'
name = N_('Language')
values = translation.languageKeys
register(LanguageChoice)
class Link(BaseKind):
## category = N_('Compound')
defaultValue_kindName = 'Link'
name = N_('Link')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and (type(value) not in [types.ListType, types.TupleType]
or len(value) != 2):
raise faults.BadSlotValue(slot, value)
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
name, url = value
if url.startswith('id:'):
url = url.replace(sourceDispatcherId, destinationDispatcherId)
return (name, url)
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)
return None
register(Link)
class Mapping(BaseKind):
category = N_('Compound')
containerNames = ['Any']
defaultValue_kindName = 'Mapping'
deleteNullValues = 0
deleteNullValues_kindName = 'Boolean'
keyKind = None
keyKind_kind_isRequired = 1
keyKind_kindName = 'Kind'
name = N_('Mapping')
requiredCount = 0
requiredCount_kindName = 'Integer'
valueKind = None
valueKind_kind_isRequired = 1
valueKind_kindName = 'Kind'
widgetName = 'Mapping'
def buildKinds(self):
# Should be converted to a class method, when porting Glasnost to
# Python 2.2.
BaseKind.buildKinds(self)
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
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
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
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
BaseKind.buildOptions(self, options)
if keyKindName is not None:
keyKind = commonTools.newThing('kind', keyKindName)
keyKind.buildOptions(keyKindOptions)
self.keyKind = keyKind
if 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)
if value and type(value) is not types.DictType:
raise faults.BadSlotValue(slot, value)
def convertValueIds(
self, slot, value, sourceDispatcherId, destinationDispatcherId):
keyIndex = 0
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)
newVal = valueSlot.getKind().convertValueIds(
valueSlot, val, sourceDispatcherId, destinationDispatcherId)
if newVal != val:
value[key] = newVal
return value
def exportValueToXmlRpc(self, slot, value):
if value is None:
return {}
exportedValue = {}
keyIndex = 0
try:
value.items()
except:
raise str((self, slot, value))
for key, itemValue in value.items():
keySlot = self.getItemKeySlot(slot, keyIndex)
exportedKey = keySlot.getKind().exportValueToXmlRpc(keySlot, key)
valueSlot = self.getItemValueSlot(slot, key)
exportedItemValue = valueSlot.getKind().exportValueToXmlRpc(
valueSlot, itemValue)
exportedValue[exportedKey] = exportedItemValue
keyIndex += 1
return exportedValue
def getItemKeyKind(self, index):
return self.keyKind
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
def getItemValueSlot(self, slot, key):
return slots.ItemValue(key, parent = slot)
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:])
def importValueFromXmlRpc(self, slot, importedValue):
if importedValue is None:
return {}
value = {}
slot.value = value
keyIndex = 0
for importedKey, importedItemValue in importedValue.items():
keySlot = self.getItemKeySlot(slot, keyIndex)
key = keySlot.getKind().importValueFromXmlRpc(keySlot, importedKey)
valueSlot = self.getItemValueSlot(slot, key)
itemValue = valueSlot.getKind().importValueFromXmlRpc(
valueSlot, importedItemValue)
value[key] = itemValue
keyIndex += 1
del slot.value
return value
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
return None
register(Mapping)
class Marks(BaseKind):
## category = N_('Other')
defaultValue_kindName = 'Marks'
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
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
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
return None
register(Marks)
class Memory(BaseKind):
## category = N_('Other')
defaultValue_kindName = 'Memory'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.DictType:
raise faults.BadSlotValue(slot, value)
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
register(Memory)
class PairwiseMatrix(BaseKind):
## category = N_('Other')
defaultValue_kindName = 'PairwiseMatrix'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.DictType:
raise faults.BadSlotValue(slot, value)
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:
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
return None
register(PairwiseMatrix)
class Password(BaseKind):
category = N_('Text')
defaultValue_kindName = 'Password'
name = N_('Password')
widgetName = 'InputPassword'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.StringType:
raise faults.BadSlotValue(slot, value)
register(Password)
class PythonIdentifier(BaseKind):
category = N_('Text')
defaultValue_kindName = 'PythonIdentifier'
name = N_('Python Identifier')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.StringType:
raise faults.BadSlotValue(slot, value)
register(PythonIdentifier)
class Rating(BaseKind):
## category = N_('Other')
defaultValue_kindName = 'Rating'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.DictType:
raise faults.BadSlotValue(slot, value)
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
return None
register(Rating)
class Sequence(AbstractSequence):
category = N_('Compound')
containerNames = ['Any']
defaultValue_kindName = 'Sequence'
itemKind = None
itemKind_kind_isRequired = 1
itemKind_kindName = 'Kind'
itemKind_valueName = None
name = N_('Sequence')
requiredCount = 0
requiredCount_kindName = 'Integer'
def buildKinds(self):
# Should be converted to a class method, when porting Glasnost to
# Python 2.2.
AbstractSequence.buildKinds(self)
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
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
AbstractSequence.buildOptions(self, options)
if itemKindName is not None:
itemKind = commonTools.newThing('kind', itemKindName)
itemKind.buildOptions(itemKindOptions)
self.itemKind = itemKind
def getItemKind(self, index):
return self.itemKind
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 includes(self, kind):
if AbstractSequence.includes(self, kind):
return 1
if not isinstance(kind, Sequence):
return 0
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)
register(Sequence)
class AcceptedRoles(Sequence):
balloonHelp = N_('Select accepted types of items.')
containerNames = ['Any', 'Sequence']
defaultValue_kindName = 'AcceptedRoles'
itemKind_value_allowAll = 1
itemKind_value_allowNone = 1
itemKind_valueName = 'ServerRole'
label = N_('Accepted Types')
name = N_('Accepted Roles')
requiredCount = 1
register(AcceptedRoles)
class ArgumentPins(Sequence):
defaultValue_kindName = 'ArgumentPins'
itemKind_valueName = 'OutputConnector'
label = N_('Argument Pins')
name = N_('Argument Pins')
def exportValueToXmlRpc(self, slot, value):
if value is None:
return []
exportedValue = []
for argumentNumber in range(len(value)):
if value[argumentNumber] is None:
itemExport = 0
else:
itemSlot = self.getItemSlot(slot, argumentNumber)
itemExport = itemSlot.getKind().exportValueToXmlRpc(
itemSlot, value[argumentNumber])
exportedValue.append(itemExport)
return exportedValue
def importValueFromXmlRpc(self, slot, importedValue):
if not importedValue:
return None
value = []
slot.value = value
for argumentNumber in range(len(importedValue)):
if importedValue[argumentNumber] == 0:
item = None
else:
itemSlot = self.getItemSlot(slot, argumentNumber)
item = itemSlot.getKind().importValueFromXmlRpc(
itemSlot, importedValue[argumentNumber])
value.append(item)
del slot.value
return value
register(ArgumentPins)
class UsersSet(Sequence):
balloonHelp = N_('Choose the user(s) of this object.')
containerNames = ['Any', 'Sequence']
defaultValue_kindName = 'UsersSet'
itemKind_value_permanentIds = [system.generalPublicId]
itemKind_value_serverRoles = ['groups', 'people']
itemKind_valueName = 'Id'
label = N_('Users')
name = N_('Users')
requiredCount = 1
register(UsersSet)
class AuthorsSet(UsersSet):
balloonHelp = N_('Choose the author(s) for this object.')
containerNames = ['Any', 'Sequence', 'UsersSet']
defaultValue_kindName = 'AuthorsSet'
label = N_('Authors')
name = N_('Authors')
register(AuthorsSet)
class Properties(Sequence):
importExport = 'private'
itemKind_value_valueThingCategory = 'other'
itemKind_value_valueThingName = 'Property'
itemKind_valueName = 'Thing'
label = N_('Properties')
name = N_('Properties')
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.kindName = kind.getThingName()
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 the people and groups who are allowed to read the item.')
containerNames = ['Any', 'Sequence', 'UsersSet']
defaultValue_kindName = 'ReadersSet'
label = N_('Readers')
name = N_('Readers')
register(ReadersSet)
class ResultPins(Sequence):
defaultValue_kindName = 'ResultPins'
itemKind_value_itemKind_value_itemKind_valueName = 'InputConnector'
itemKind_value_itemKind_valueName = 'Sequence'
itemKind_valueName = 'Sequence'
label = N_('Result Pins')
name = N_('Result Pins')
def convertValueIds(self, slot, value, sourceDispatcherId,
destinationDispatcherId):
for resultNumber in range(len(value)):
resultPin = value[resultNumber]
if resultPin is None:
continue
resultPinSlot = self.getItemSlot(slot, resultNumber)
for depth in range(len(resultPin)):
resultConnectors = resultPin[depth]
if resultConnectors is None:
continue
resultConnectorsSlot = self.getItemSlot(resultPinSlot, depth)
for index in range(len(resultConnectors)):
resultConnector = resultConnectors[index]
if resultConnector is None:
continue
resultConnectorSlot = self.getItemSlot(
resultConnectorsSlot, index)
resultConnectorSlot.getKind().convertValueIds(
resultConnectorSlot, resultConnector,
sourceDispatcherId, destinationDispatcherId)
return value
def exportValueToXmlRpc(self, slot, value):
if value is None:
return []
resultPinsExport = []
for resultNumber in range(len(value)):
resultPin = value[resultNumber]
if resultPin is None:
resultPinExport = 0
else:
resultPinSlot = self.getItemSlot(slot, resultNumber)
resultPinExport = []
for depth in range(len(resultPin)):
resultConnectors = resultPin[depth]
if resultConnectors is None:
resultConnectorsExport = 0
else:
resultConnectorsSlot = self.getItemSlot(
resultPinSlot, depth)
resultConnectorsExport = []
for index in range(len(resultConnectors)):
resultConnector = resultConnectors[index]
if resultConnector is None:
resultConnectorExport = 0
else:
resultConnectorSlot = self.getItemSlot(
resultConnectorsSlot, index)
resultConnectorExport = \
commonTools.newThing(
'kind', 'InputConnector'
).exportValueToXmlRpc(
resultConnectorSlot, resultConnector)
resultConnectorsExport.append(
resultConnectorExport)
resultPinExport.append(resultConnectorsExport)
resultPinsExport.append(resultPinExport)
return resultPinsExport
def importValueFromXmlRpc(self, slot, resultPinsImport):
if not resultPinsImport:
return None
resultPins = []
for resultNumber in range(len(resultPinsImport)):
resultPinImport = resultPinsImport[resultNumber]
if resultPinImport == 0:
resultPin = None
else:
resultPinSlot = self.getItemSlot(slot, resultNumber)
resultPin = []
for depth in range(len(resultPinImport)):
resultConnectorsImport = resultPinImport[depth]
if resultConnectorsImport == 0:
resultConnectors = None
else:
resultConnectorsSlot = self.getItemSlot(
resultPinSlot, depth)
resultConnectors = []
for index in range(len(resultConnectorsImport)):
resultConnectorImport = resultConnectorsImport[
index]
if resultConnectorImport == 0:
resultConnector = None
else:
resultConnectorSlot = self.getItemSlot(
resultConnectorsSlot, index)
resultConnector = \
commonTools.newThing(
'kind', 'InputConnector'
).importValueFromXmlRpc(
resultConnectorSlot,
resultConnectorImport)
resultConnectors.append(resultConnector)
resultPin.append(resultConnectors)
resultPins.append(resultPin)
return resultPins
def removeValueIds(self, slot, value, rolesToKeep):
for resultNumber in range(len(value)):
resultPin = value[resultNumber]
if resultPin is None:
continue
resultPinSlot = self.getItemSlot(slot, resultNumber)
for depth in range(len(resultPin)):
resultConnectors = resultPin[depth]
if resultConnectors is None:
continue
resultConnectorsSlot = self.getItemSlot(resultPinSlot, depth)
indexesToDelete = []
for index in range(len(resultConnectors)):
resultConnector = resultConnectors[index]
if resultConnector is None:
continue
resultConnectorSlot = self.getItemSlot(
resultConnectorsSlot, index)
newConnector = resultConnectorSlot.getKind(
).removeValueIds(resultConnectorSlot,
resultConnector, rolesToKeep)
if newConnector != resultConnector:
indexesToDelete.append(index)
indexesToDelete.reverse()
for index in indexesToDelete:
del resultConnectors[index]
if not resultConnectors:
resultPin[depth] = None
# FIXME: To do : Simplify the result.
return value
register(ResultPins)
class ServerId(Id):
category = N_('Glasnost')
containerNames = ['Any', 'String']
defaultValue_kindName = 'ServerId'
name = N_('Server ID')
## widgetName = 'SelectServerId'
widget_size = 40
widgetName = 'InputText'
def removeValueIds(self, slot, value, rolesToKeep):
return value
register(ServerId)
class ServerRole(Choice):
allowAll = 0
allowAll_kindName = 'Boolean'
allowNone = 0
allowNone_kindName = 'Boolean'
category = N_('Glasnost')
containerNames = ['Any', 'String']
defaultValue_kindName = 'ServerRole'
name = N_('Server Role')
def getLabels(self, slot, fields):
roles = self.getValues(slot, fields)
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
def getValues(self, slot, fields):
from glasnost.proxy.DispatcherProxy import getRegisteredRoles
values = []
if self.allowNone:
values.append(None)
if self.allowAll:
values.append('__all__')
values += getRegisteredRoles(context.getVar('dispatcherId'))
return values
register(ServerRole)
class SlotName(Choice):
category = N_('Glasnost')
defaultValue_kindName = 'SlotName'
name = N_('Slot Name')
register(SlotName)
class Source(BaseKind):
category = N_('Glasnost')
defaultValue_kindName = 'Source'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.StringType:
raise faults.BadSlotValue(slot, value)
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
register(Source)
class String(BaseKind):
category = N_('Text')
containerNames = ['Any']
defaultValue_kindName = 'String'
isTranslatable = 1
isTranslatable_kind_importExport = 'public'
name = N_('String')
possibleWidgetNames = ['InputText', 'TextArea']
useFileStorage_kind_importExport = 'public'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.StringType:
raise faults.BadSlotValue(slot, value)
def getCmpFunction(self):
return locale.strcoll
register(String)
class Structure(AbstractSequence):
category = N_('Compound')
containerNames = ['Any']
defaultValue_kindName = 'Structure'
name = N_('Structure')
parameters = None
parameters_kind_itemKind_value_valueThingCategory = 'other'
parameters_kind_itemKind_value_valueThingName = 'Parameter'
parameters_kind_itemKind_valueName = 'Thing'
parameters_kindName = 'Sequence'
def getItemKind(self, index):
if self.parameters is None or index >= len(self.parameters):
return None
return self.parameters[index].kind
register(Structure)
class Thing(BaseKind):
category = N_('Compound')
containerNames = ['Any']
defaultValue_kindName = 'Thing'
name = N_('Thing')
valueThingCategory = None
valueThingCategory_kindName = 'String'
valueThingName = None
valueThingName_kindName = 'String'
valueThingNameSlotName = None
valueThingNameSlotName_kindName = 'PythonIdentifier'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.InstanceType:
raise faults.BadSlotValue(slot, value)
def convertValueIds(self, slot, value, sourceDispatcherId,
destinationDispatcherId):
if value is None:
return None
value.convertIds(
sourceDispatcherId, destinationDispatcherId, parentSlot = slot)
return value
def equals(self, kind):
if not BaseKind.equals(self, kind):
return 0
return self.valueThingCategory == kind.valueThingCategory \
and self.valueThingName == kind.valueThingName
def exportValueToXmlRpc(self, slot, value):
if value is None:
return None
return value.exportToXmlRpc(parentSlot = slot)
def getModelSlotByPath(self, slot, path):
value = slot.getValue()
if value is None:
value = commonTools.newThing(
self.valueThingCategory, self.getValueThingName(slot))
slot = slot.detach(value)
return value.getSlotByPath(path, parentSlot = slot)
def getValueThingName(self, slot):
if self.valueThingNameSlotName is not None:
container = slot.getContainer()
valueThingName = container.getSlot(
self.valueThingNameSlotName, parentSlot = slot.parent
).getValue()
if valueThingName is not None:
return valueThingName
return self.valueThingName
def getValueThingNameFromFields(self, slot, fields):
if self.valueThingNameSlotName is not None:
container = slot.getContainer()
valueThingName = container.getSlot(
self.valueThingNameSlotName, parentSlot = slot.parent
).getField(fields)
if valueThingName is not None:
return valueThingName
return self.valueThingName
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
return value
def includes(self, kind):
if BaseKind.includes(self, kind):
return 1
if self.getName() != kind.getName():
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 BaseKind.intersects(self, kind):
return 1
if self.getName() != kind.getName():
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 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
register(Thing)
class Union(BaseKind):
category = N_('Glasnost')
containerNames = ['Any']
defaultValue_kindName = 'Union'
isPractical = 0
items = None
items_kind_itemKind_valueName = 'Kind'
items_kind_label = N_('Items')
items_kindName = 'Sequence'
name = 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.getName() != kind.getName():
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 = 'now'
defaultValue_kindName = 'CreationTime'
importExport = 'from-server-only'
isAutomaticalyModified = 1
stateInEditMode = 'read-only'
label = N_('Creation Time')
name = N_('Creation Time')
def setAutomaticalValue(self, slot, init = 0):
if init:
slot.setValue(time.time())
register(CreationTime)
class ModificationTime(Time):
## defaultValue = 'now'
defaultValue_kindName = 'ModificationTime'
importExport = 'from-server-only'
isAutomaticalyModified = 1
stateInEditMode = 'read-only'
label = N_('Modification Time')
name = N_('Modification Time')
def setAutomaticalValue(self, slot, init = 0):
slot.setValue(time.time())
register(ModificationTime)
class Token(BaseKind):
category = N_('Text')
containerNames = ['Any', 'String']
defaultValue_kindName = 'Token'
name = N_('Token')
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.StringType:
raise faults.BadSlotValue(slot, value)
register(Token)
class ApplicationToken(Token):
containerNames = ['Any', 'String', 'Token']
defaultValue_kindName = 'ApplicationToken'
name = N_('Application Token')
register(ApplicationToken)
class UserToken(Token):
containerNames = ['Any', 'String', 'Token']
defaultValue_kindName = 'UserToken'
name = N_('User Token')
register(UserToken)
class TranslationToAdd(BaseKind):
category = None
defaultValue_kindName = 'TranslationToAdd'
register(TranslationToAdd)
class TranslatorsSets(BaseKind):
defaultValue_kindName = 'TranslatorsSets'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and type(value) is not types.DictType:
raise faults.BadSlotValue(slot, value)
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
return None
register(TranslatorsSets)
class WritersSet(UsersSet):
balloonHelp = N_(
'Select the people and groups who are allowed to modify the item.')
containerNames = ['Any', 'Sequence', 'UsersSet']
defaultValue_kindName = 'WritersSet'
label = N_('Writers')
name = N_('Writers')
register(WritersSet)
class XChoice(Choice):
category = N_('Choice')
defaultValue_kindName = 'XChoice'
name = N_('Extended Choice')
widgetName = 'XSelect'
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
def getGroupedValues(self, slot, fields):
return (self.groupNames, self.groupedValues)
register(XChoice)
class Fault(Thing):
category = N_('Glasnost')
defaultValue_kindName = 'Fault'
name = N_('Fault')
valueThingCategory = 'other'
valueThingName = 'Fault'
register(Fault)
class InputConnector(Thing):
category = N_('Glasnost')
defaultInput_kindName = 'InputConnector'
name = N_('Input Connector')
valueThingCategory = 'other'
valueThingName = 'InputConnector'
register(InputConnector)
class Kind(Thing):
defaultValue_kindName = 'Kind'
name = N_('Kind')
valueThingCategory = 'kind'
valueThingName = 'BaseKind'
register(Kind)
class KindName(Choice):
defaultValue_kindName = 'KindName'
name = 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, fields):
categories = []
groupedValues = {}
for kindClass in commonTools.getAllThingClasses().values():
if kindClass.thingCategory != 'kind':
continue
if kindClass.category is None:
continue
if not kindClass.category in categories:
categories.append(kindClass.category)
groupedValues[kindClass.category] = []
groupedValues[kindClass.category].append(
kindClass.getThingName.im_func(kindClass))
return (categories, groupedValues) # groupNames, groupedValues
def getValues(self, slot, fields):
return [
kindClass.getThingName.im_func(kindClass)
for kindClass in commonTools.getAllThingClasses().values()
if kindClass.thingCategory == 'kind' \
and kindClass.category is not None]
register(KindName)
class OutputConnector(Thing):
category = N_('Glasnost')
defaultOutput_kindName = 'OutputConnector'
name = N_('Output Connector')
valueThingCategory = 'other'
valueThingName = 'OutputConnector'
register(OutputConnector)
class Upload(Thing):
category = N_('Compound')
defaultValue_kindName = 'Upload'
name = N_('Upload')
valueThingCategory = 'other'
valueThingName = 'Upload'
register(Upload)
class ValueHolder(Thing):
category = N_('Glasnost')
defaultValue_kindName = 'ValueHolder'
name = N_('Value Holder')
valueThingCategory = 'other'
valueThingName = 'ValueHolder'
register(ValueHolder)
class Widget(Thing):
defaultValue_kindName = 'Widget'
name = N_('Widget')
valueThingCategory = 'widget'
valueThingName = 'BaseWidget'
register(Widget)
class WidgetName(Choice):
defaultValue_kindName = 'WidgetName'
name = N_('Widget Name')
def getValues(self, slot, fields):
values = Choice.getValues(self, slot, fields)
if values:
return values
else:
return ['InputText']
register(WidgetName)