232 lines
8.0 KiB
Python
232 lines
8.0 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.
|
|
|
|
|
|
__doc__ = """Glasnost Groups Web"""
|
|
|
|
__version__ = '$Revision$'[11:-2]
|
|
|
|
|
|
import copy
|
|
|
|
import glasnost.common.context as context
|
|
import glasnost.common.faults as faults
|
|
import glasnost.common.tools_new as commonTools
|
|
|
|
import glasnost.proxy.GroupsProxy as proxyGroups
|
|
|
|
import ObjectsWeb as objects
|
|
from tools import *
|
|
|
|
|
|
class AdminGroups(objects.AdminMixin, proxyGroups.AdminGroups):
|
|
pass
|
|
objects.register(AdminGroups)
|
|
|
|
|
|
class GroupMixin(objects.ObjectWebMixin):
|
|
# FIXME: Replace by kind ServerRoles.
|
|
acceptedRoles_kind_itemKind_value_widget_allLabel = N_('Every Type')
|
|
acceptedRoles_kind_itemKind_value_widget_noneLabel = N_('No Type')
|
|
acceptedRoles_kind_widget_apply = 1
|
|
acceptedRoles_kind_widget_fieldLabel = N_('Members Types')
|
|
|
|
className = None
|
|
className_kind_defaultValue = 'GroupUnion'
|
|
className_kind_importExport = 'private'
|
|
className_kind_isRequired = 1
|
|
className_kind_values = [
|
|
'GroupAll',
|
|
'GroupDelta',
|
|
'GroupIntersection',
|
|
'GroupUnion',
|
|
]
|
|
className_kind_widget_apply = 1
|
|
className_kind_widget_fieldLabel = N_('Type')
|
|
className_kind_widget_labels = {
|
|
'GroupAll': N_('All'),
|
|
'GroupDelta': N_('Difference'),
|
|
'GroupIntersection': N_('Intersection'),
|
|
'GroupUnion': N_('Union'),
|
|
}
|
|
className_kindName = 'Choice'
|
|
|
|
name_kind_widget_fieldLabel = N_('Name')
|
|
name_kind_widget_size = 40
|
|
name_kind_widgetName = 'InputText'
|
|
|
|
def getViewLayoutSlotNames(self, fields, parentSlot = None):
|
|
slotNames = objects.ObjectWebMixin.getViewLayoutSlotNames(
|
|
self, fields, parentSlot = parentSlot)
|
|
slotNames = slotNames[:]
|
|
userToken = context.getVar('userToken', default = '')
|
|
if not userToken or context.getVar('useCompactLayout', default = 0):
|
|
for slotName in ['className', 'acceptedRoles', 'writersSet']:
|
|
if slotName in slotNames:
|
|
slotNames.remove(slotName)
|
|
return slotNames
|
|
|
|
|
|
class GroupCountableMixin(GroupMixin):
|
|
itemIds = None
|
|
itemIds_kind_importExport = 'private'
|
|
itemIds_kind_stateInEditMode = 'read-only'
|
|
itemIds_kind_itemKind_value_widgetName = 'SelectId'
|
|
itemIds_kind_itemKind_valueName = 'Id'
|
|
itemIds_kind_widget_fieldLabel = N_('Items')
|
|
itemIds_kind_widgetName = 'Multi'
|
|
itemIds_kindName = 'Sequence'
|
|
|
|
def getEditLayoutSlotNames(self, fields, parentSlot = None):
|
|
slotNames = GroupMixin.getEditLayoutSlotNames(
|
|
self, fields, parentSlot = parentSlot)
|
|
slotNames = slotNames[:]
|
|
for slotName in ['itemIds']:
|
|
if slotName in slotNames:
|
|
slotNames.remove(slotName)
|
|
return slotNames
|
|
|
|
def getViewLayoutSlotNames(self, fields, parentSlot = None):
|
|
slotNames = GroupMixin.getViewLayoutSlotNames(
|
|
self, fields, parentSlot = parentSlot)
|
|
slotNames = slotNames[:]
|
|
userToken = context.getVar('userToken', default = '')
|
|
if not userToken or context.getVar('useCompactLayout', default = 0):
|
|
for slotName in ['membersSet']:
|
|
if slotName in slotNames:
|
|
slotNames.remove(slotName)
|
|
return slotNames
|
|
|
|
|
|
class GroupAll(GroupMixin, proxyGroups.GroupAll):
|
|
pass
|
|
objects.register(GroupAll)
|
|
|
|
|
|
class GroupDelta(GroupCountableMixin, proxyGroups.GroupDelta):
|
|
pass
|
|
objects.register(GroupDelta)
|
|
|
|
|
|
class GroupIntersection(GroupCountableMixin, proxyGroups.GroupIntersection):
|
|
pass
|
|
objects.register(GroupIntersection)
|
|
|
|
|
|
class GroupRole(GroupMixin, proxyGroups.GroupRole):
|
|
pass
|
|
objects.register(GroupRole)
|
|
|
|
|
|
class GroupUnion(GroupCountableMixin, proxyGroups.GroupUnion):
|
|
pass
|
|
objects.register(GroupUnion)
|
|
|
|
|
|
class GroupsWeb(objects.ObjectsWebMixin, proxyGroups.GroupsProxy):
|
|
def getObject_handleResult(self, lazyObject):
|
|
object = proxyGroups.GroupsProxy.getObject_handleResult(self,
|
|
lazyObject)
|
|
object.className = object.__class__.__name__
|
|
if hasattr(object, 'itemIds'): # group is countable
|
|
try:
|
|
object.itemIds = object.getContainedIds()
|
|
object.itemIds = sortIds(object.itemIds)
|
|
except faults.IllegalRecursiveGroup:
|
|
object.itemIds_kind = commonTools.newThing(
|
|
'kind', 'String', isTranslatable = 0)
|
|
object.itemIds = _('Illegal recursive group')
|
|
return object
|
|
|
|
def newObject(self, keywords = None):
|
|
group = GroupUnion() # fake group to get className
|
|
if not keywords:
|
|
group.className = 'GroupUnion'
|
|
return group
|
|
classNameSlot = group.getSlot('className')
|
|
className = classNameSlot.getWidget().submit(classNameSlot, keywords)
|
|
if not className:
|
|
className = 'GroupUnion'
|
|
group = commonTools.newThing('object', 'groups.%s' % className)
|
|
group.className = className
|
|
return group
|
|
|
|
def slides(self, id, index = '0'):
|
|
try:
|
|
index = int(index)
|
|
except ValueError:
|
|
index = 0
|
|
object = self.getObject(id)
|
|
try:
|
|
itemId = object.membersSet[index]
|
|
except IndexError:
|
|
return pageNotFound()
|
|
|
|
item = getObject(itemId)
|
|
|
|
if index > 0:
|
|
o = getObject(object.membersSet[index-1])
|
|
webTools.addContextualHeader(
|
|
'<link rel="prev" href="%s" title="%s" />' % (
|
|
X.idUrl(id, 'slides/%s' % (index-1)),
|
|
o.getLabelTranslated()))
|
|
|
|
if index+1 < len(object.membersSet):
|
|
o = getObject(object.membersSet[index+1])
|
|
webTools.addContextualHeader(
|
|
'<link rel="next" href="%s" title="%s" />' % (
|
|
X.idUrl(id, 'slides/%s' % (index+1)),
|
|
o.getLabelTranslated()))
|
|
|
|
return item.getWeb().view(itemId)
|
|
slides.isPublicForWeb = 1
|
|
|
|
def view(self, id):
|
|
webTools.addContextualHeader('noindex')
|
|
return objects.ObjectsWebMixin.view(self, id)
|
|
view.isPublicForWeb = 1
|
|
|
|
def viewAll(self):
|
|
webTools.addContextualHeader('noindex')
|
|
return objects.ObjectsWebMixin.viewAll(self)
|
|
viewAll.isPublicForWeb = 1
|
|
|