- définition de "profils d'utilisation" (granularité à négocier par la suite).

- très bonne idée (c'est moi qui le dit) pour les commentaires: "commentaires
  éditoriaux" dont les lecteurs == les éditeurs de l'objet commenté
- moi aussi j'avais corrigé le generalPublic dans les virtualhost
- les tests ont l'air de tourner (pas réessayé aujourd'hui)
- modifs diverses
This commit is contained in:
fpeters 2003-11-20 12:59:16 +00:00
parent 38cb449f59
commit ac17ad0fe7
71 changed files with 2327 additions and 1838 deletions

View File

@ -96,7 +96,7 @@ TEMPLATES=default april bxlug codelutin.org cuisine easter-eggs entrouvert.com e
RPM_PACKAGE_NAME=python$(PYTHON_VERSION)-tal python$(PYTHON_VERSION)-imaging python$(PYTHON_VERSION)-docutils
.PHONY: help archive clean data-archive dist dist-clean install-create-dir install-glasnost install-data install-extensions install-gtk install-locale install-log install-python-libs install-scripts install-servers install-templates install-web install mo po glasnost.spec rpm rpm-depend uninstall config
.PHONY: help archive clean data-archive dist dist-clean install-create-dir install-glasnost install-data install-extensions install-gtk install-locale install-log install-python-libs install-scripts install-servers install-templates install-web install mo po profiles-xml glasnost.spec rpm rpm-depend uninstall
help:
@echo
@ -196,13 +196,12 @@ infos-xml:
do \
intltool-merge -x po/glasnost-web/ $$F `dirname $$F`/`basename $$F .in`; \
done
install-create-dir:
-mkdir -p "$(DESTDIR)/$(BIN_DIR)"
-mkdir -p "$(DESTDIR)/$(DATA_DIR)"
-mkdir -p "$(DESTDIR)/$(GLASNOST_DIR)"
-mkdir -p "$(DESTDIR)/$(ETC_DIR)"
-mkdir -p "$(DESTDIR)/etc/init.d"
-mkdir -p "$(DESTDIR)/$(EXTENSIONS_DIR)"
-mkdir -p "$(DESTDIR)/$(LIBS_DIR)"
-mkdir -p "$(DESTDIR)/$(LOCALE_DIR)"
@ -214,9 +213,9 @@ install-create-dir:
-mkdir -p "$(DESTDIR)/$(TEMPLATES_DIR)"
-mkdir -p "$(DESTDIR)/$(WEB_DIR)"
install-glasnost: config
install-glasnost: config profiles-xml
@mkdir -p "$(DESTDIR)/$(GLASNOST_DIR)"
-cp $^ "$(DESTDIR)/$(GLASNOST_DIR)"/
-cp config "$(DESTDIR)/$(GLASNOST_DIR)"/
@if test -e "$(DESTDIR)/$(SBIN_DIR)/$(GLASNOST)"; then \
rm -f "$(DESTDIR)/$(SBIN_DIR)/$(GLASNOST)"; \
else :; fi
@ -234,6 +233,8 @@ install-glasnost: config
test ! -e "$(DESTDIR)/$(ETC_DIR)/config" || \
cp "$(DESTDIR)/$(ETC_DIR)/config" "$(DESTDIR)/$(ETC_DIR)/config.save"
test -e "$(DESTDIR)/$(ETC_DIR)/config" || cp config "$(DESTDIR)/$(ETC_DIR)/config"
test -d "$(DESTDIR)/$(ETC_DIR)/profiles" || mkdir "$(DESTDIR)/$(ETC_DIR)/profiles"
cp profiles/*.xml "$(DESTDIR)/$(ETC_DIR)/profiles"
install-data:
@if ! test -e "$(DESTDIR)/$(DATA_DIR)"; then \
@ -309,7 +310,7 @@ install-templates: infos-xml
-mkdir -p "$(DESTDIR)/$(TEMPLATES_DIR)"
for F in $(TEMPLATES); \
do \
(cd templates && tar c --exclude CVS --exclude '*.in' --exclude '*.in.h' $$F) | (cd "$(DESTDIR)/$(TEMPLATES_DIR)" && tar x); \
(cd templates && $(TAR) c --exclude CVS --exclude '*.in' --exclude '*.in.h' $$F) | (cd "$(DESTDIR)/$(TEMPLATES_DIR)" && $(TAR) x); \
done
install-web:
@ -356,6 +357,13 @@ mo: po/glasnost-web/de.po \
msgfmt --statistics -c -v -o locale/fr/LC_MESSAGES/glasnost-web.mo po/glasnost-web/fr.po
msgfmt --statistics -c -v -o locale/sv/LC_MESSAGES/glasnost-web.mo po/glasnost-web/sv.po
profiles-xml:
for F in `$(FIND) profiles/ -type f -name '*.xml.in'`; \
do \
intltool-merge -x po/glasnost-web/ $$F `dirname $$F`/`basename $$F .in`; \
done
talTranslations.py: templates/
./talGettext.py templates/ > talTranslations.py
@ -372,12 +380,12 @@ po: glasnost-web/ \
cp po/glasnost-web/fi.po po/glasnost-web/fi.pox
cp po/glasnost-web/fr.po po/glasnost-web/fr.pox
cp po/glasnost-web/sv.po po/glasnost-web/sv.pox
for F in `$(FIND) templates/ -type f -name '*.xml.in'`; \
for F in `$(FIND) profiles/ templates/ -type f -name '*.xml.in'`; \
do \
intltool-extract --type=gettext/xml $$F; \
done
$(GETTEXT) -d po/glasnost-web/messages -k N_ `$(FIND) $^ -type f -name "*.py"` \
`$(FIND) templates/ -type f -name '*.xml.in.h'`
`$(FIND) profiles/ templates/ -type f -name '*.xml.in.h'`
msgmerge -o po/glasnost-web/de.po -D po/glasnost-web de.pox messages.pot
msgmerge -o po/glasnost-web/es.po -D po/glasnost-web es.pox messages.pot
msgmerge -o po/glasnost-web/fi.po -D po/glasnost-web fi.pox messages.pot

View File

@ -37,9 +37,6 @@ UseBalloonHelp = true
# Cache files? (boolean, default: false)
CacheFiles = false
# Domains to use for translations going through gettext (don't change)
GettextDomains = glasnost-web
Per dispatcher options
----------------------
@ -80,9 +77,6 @@ Debug:
DisableSpellchecking:
Disable spellchecking (used in <textarea> previews). (default: false)
GettextDomains:
Allows to add more gettext domains to look in for translations.
Profiling:
Dumps profiling informations into /tmp/
(default: false)
@ -108,18 +102,10 @@ WebDirectoryPath:
Define an additional path where to look for .py files after site
DocumentRoot and before Glasnost-wide WebDirectoryPath.
It is also possible to define custom modules to use for different server roles
with:
%(serverRole)s-web = ...
Exemple: articles-web = lyonarticles
Per server options
------------------
OnlyForDispatchers
ServerHostName
ServerPort

4
debian/changelog vendored
View File

@ -1,8 +1,8 @@
glasnost (0.7.0.cvs-latestCVS.20031017.1) unstable; urgency=low
glasnost (0.7.0.cvs-latestCVS.20031109.1) unstable; urgency=low
* Built locally from CVS.
-- Frederic Peters <fpeters@debian.org> Fri, 17 Oct 2003 13:37:05 +0200
-- Frederic Peters <fpeters@debian.org> Sun, 9 Nov 2003 13:48:30 +0100
glasnost (0.6.5-1) unstable; urgency=low

View File

@ -1106,13 +1106,8 @@ class Application(applications.Application):
except locale.Error:
locale.setlocale(locale.LC_COLLATE, 'C')
domains = [
commonTools.getConfig(
virtualHost.hostName, 'GettextDomains', default = ''),
commonTools.getConfig('Misc', 'GettextDomains', default = ''),
'%s-web' % glasnost.applicationName ]
domains = ','.join([x for x in domains if x])
domains = [x.strip() for x in domains.split(',')]
domains = [ '%s-web' % glasnost.applicationName ] + (
virtualHost.locales or [])
translation = commonTools.translation(domains, languages)
__builtin__.__dict__['_'] = translation.gettext

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2
profiles/.cvsignore Normal file
View File

@ -0,0 +1,2 @@
*.xml
*.xml.in.h

15
profiles/basic.xml.in Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<glasnost>
<_description>Basic Functionalities</_description>
<roles>
<role>authentication</role>
<role>authentication-login-password</role>
<role>groups</role>
<role>pagenames</role>
<role>people</role>
<role>preferences</role>
<role>sessions</role>
<role>virtualhosts</role>
</roles>
</glasnost>

8
profiles/cards.xml.in Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<glasnost>
<_description>Cards Support</_description>
<roles>
<role>cards</role>
</roles>
</glasnost>

10
profiles/cms.xml.in Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<glasnost>
<_description>Content Management System</_description>
<roles>
<role>articles</role>
<role>rubrics</role>
<role>uploadfiles</role>
</roles>
</glasnost>

8
profiles/comments.xml.in Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<glasnost>
<_description>Comments Support</_description>
<roles>
<role>comments</role>
</roles>
</glasnost>

9
profiles/ldap.xml.in Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<glasnost>
<_description>LDAP Support</_description>
<roles>
<role>authentication-ldap</role>
<role>ldappeople</role>
</roles>
</glasnost>

View File

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<glasnost>
<_description>Translations Support</_description>
<roles>
<role>translations</role>
</roles>
</glasnost>

12
profiles/vote.xml.in Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<glasnost>
<_description>Electronic Voting</_description>
<roles>
<role>atoms</role>
<role>ballots</role>
<role>elections</role>
<role>grades</role>
<role>votes</role>
</roles>
</glasnost>

View File

@ -5,7 +5,7 @@ from scriptingTools import *
from glasnost.proxy.tools import getProxyForServerRole
articleId = sys.argv[1]
dispatcherId = 'glasnost://' + splitObjectId(articleId)[0]
dispatcherId = commonTools.extractDispatcherId(articleId)
init(dispatcherId)

View File

@ -7,7 +7,7 @@ from glasnost.proxy.tools import getProxyForServerRole
adminId = sys.argv[1]
editorsId = sys.argv[2]
dispatcherId = 'glasnost://' + splitObjectId(adminId)[0]
dispatcherId = commonTools.extractDispatcherId(adminId)
init(dispatcherId)

View File

@ -55,7 +55,7 @@ import glasnost
from glasnost.common.AppointmentsCommon import *
import glasnost.common.faults as faults
from glasnost.common.tools import sendMail, splitObjectId
from glasnost.common.tools import sendMail
import glasnost.common.tools_new as commonTools
from glasnost.server.ObjectsServer import ObjectServerMixin, \
@ -174,63 +174,12 @@ class AppointmentsServer(AppointmentsCommonMixin, ObjectsServer):
def addObjectXmlRpc(self, objectImport):
objectId = ObjectsServer.addObjectXmlRpc(self, objectImport)
return objectId
# TODO: proper notification email
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
object = virtualServer.loadObjectCore(objectId)
## send notification mail.
subject = _('New appointment')
body = _("""
A new appointement has been set for you on:
%(hostName)s/%(id)s
Subject: %(title)s
Message: %(body)s
Beginning: %(start)s
""") % {
'hostName': getProxyForServerRole('virtualhosts').getHostName(
virtualServerId),
'id' : '/'.join(splitObjectId(objectId)[1:]),
'title': object.title,
'body': object.body,
'start': time.strftime('%Y-%m-%d %H:%M:%S',
time.localtime(object.start))
}
self.sendNotification(virtualServerId, object, subject, body)
# TODO: send notification mail
return objectId
def modifyObjectXmlRpc(self, objectImport):
version = ObjectsServer.modifyObjectXmlRpc(self, objectImport)
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
object = virtualServer.loadObjectCore(objectImport['id'])
## send notification mail.
subject = _('Appointment modified')
body = _("""
An appointment has been modified for you on:
%(hostName)s/%(id)s
Subject: %(title)s
Message: %(body)s
Beginning: %(start)s
""") % {
'hostName': getProxyForServerRole('virtualhosts').getHostName(
virtualServerId),
'id' : '/'.join(splitObjectId(object.id)[1:]),
'title': object.title,
'body': object.body,
'start': time.strftime('%Y-%m-%d %H:%M:%S',
time.localtime(object.start))
}
self.sendNotification(virtualServerId, object, subject, body)
# TODO: send notification mail
return version
def updateFromVCalendar(self, vCalendar):

View File

@ -96,7 +96,8 @@ class Article(ObjectServerMixin, ArticleCommon):
virtualServer = self.getServer().getVirtualServer(virtualServerId)
articlesDirectoryPath = os.path.join(
virtualServer.dataDirectoryPath, self.getServer().applicationRole)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
bodyFilePath = os.path.join(articlesDirectoryPath, localId)
if not os.access(bodyFilePath, os.F_OK):
return None
@ -142,7 +143,8 @@ class Article(ObjectServerMixin, ArticleCommon):
virtualServer = self.getServer().getVirtualServer(virtualServerId)
articlesDirectoryPath = os.path.join(
virtualServer.dataDirectoryPath, self.getServer().applicationRole)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
bodyHistoryDirectoryPath = os.path.join(
articlesDirectoryPath, localId + '-history')
history = []
@ -174,7 +176,8 @@ class Article(ObjectServerMixin, ArticleCommon):
virtualServer = self.getServer().getVirtualServer(virtualServerId)
articlesDirectoryPath = os.path.join(
virtualServer.dataDirectoryPath, self.getServer().applicationRole)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
bodyHistoryDirectoryPath = os.path.join(
articlesDirectoryPath, localId + '-history')
if not os.access(bodyHistoryDirectoryPath, os.F_OK):
@ -227,7 +230,8 @@ class Article(ObjectServerMixin, ArticleCommon):
virtualServer = self.getServer().getVirtualServer(virtualServerId)
articlesDirectoryPath = os.path.join(
virtualServer.dataDirectoryPath, self.getServer().applicationRole)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
bodyFilePath = os.path.join(articlesDirectoryPath, localId)
try:
bodyFile = open(bodyFilePath, 'rb')
@ -266,7 +270,8 @@ class Article(ObjectServerMixin, ArticleCommon):
virtualServer = self.getServer().getVirtualServer(virtualServerId)
articlesDirectoryPath = os.path.join(
virtualServer.dataDirectoryPath, self.getServer().applicationRole)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
bodyFilePath = os.path.join(articlesDirectoryPath, localId)
try:
os.remove(bodyFilePath)
@ -280,7 +285,8 @@ class Article(ObjectServerMixin, ArticleCommon):
virtualServer = self.getServer().getVirtualServer(virtualServerId)
articlesDirectoryPath = os.path.join(
virtualServer.dataDirectoryPath, self.getServer().applicationRole)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
bodyHistoryDirectoryPath = os.path.join(
articlesDirectoryPath, localId + '-history')
if not os.access(bodyHistoryDirectoryPath, os.F_OK):
@ -314,7 +320,8 @@ class Article(ObjectServerMixin, ArticleCommon):
if not os.access(articlesDirectoryPath, os.F_OK):
os.mkdir(articlesDirectoryPath)
os.chmod(articlesDirectoryPath, 0750)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
bodyFilePath = os.path.join(articlesDirectoryPath, localId)
bodyFile = open(bodyFilePath, 'wb')
os.chmod(bodyFilePath, 0640)
@ -328,7 +335,8 @@ class Article(ObjectServerMixin, ArticleCommon):
virtualServer = self.getServer().getVirtualServer(virtualServerId)
articlesDirectoryPath = os.path.join(
virtualServer.dataDirectoryPath, self.getServer().applicationRole)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
bodyHistoryDirectoryPath = os.path.join(
articlesDirectoryPath, localId + '-history')
if not os.access(bodyHistoryDirectoryPath, os.F_OK):
@ -432,7 +440,7 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
destinationVirtualServerDataDirectoryPath, self.applicationRole)
for id in virtualServer.objects.keys():
serverHostNameAndPortNotUsed, serverRoleNotUsed, localId = \
splitObjectId(id)
commonTools.splitId(id)
sourceBodyFilePath = os.path.join(
sourceObjectsDirectoryPath, localId)
destinationBodyFilePath = os.path.join(
@ -505,7 +513,7 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
exportDirectoryPath, self.applicationRole)
for id in virtualServer.objects.keys():
serverHostNameAndPortNotUsed, serverRoleNotUsed, localId = \
splitObjectId(id)
commonTools.splitId(id)
sourceBodyFilePath = os.path.join(
objectsDirectoryPath, localId)
exportBodyFilePath = os.path.join(
@ -665,7 +673,7 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
virtualServerDataDirectoryPath, self.applicationRole)
for id in virtualServer.objects.keys():
serverHostNameAndPortNotUsed, serverRoleNotUsed, localId = \
splitObjectId(id)
commonTools.splitId(id)
importBodyFilePath = os.path.join(
importObjectsDirectoryPath, localId)
destinationBodyFilePath = os.path.join(
@ -771,7 +779,7 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
virtualServerDataDirectoryPath, self.applicationRole)
for id in virtualServer.objects.keys():
serverHostNameAndPortNotUsed, serverRoleNotUsed, localId = \
splitObjectId(id)
commonTools.splitId(id)
bodyHistoryDirectoryPath = os.path.join(
objectsDirectoryPath, localId + '-history')
if not os.access(bodyHistoryDirectoryPath, os.F_OK):
@ -827,7 +835,8 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
objectsDirectoryPath = os.path.join(
virtualServerDataDirectoryPath, self.applicationRole)
for id in virtualServer.objects.keys():
serverHostNameAndPort, serverRole, localId = splitObjectId(id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(id)
bodyFilePath = os.path.join(objectsDirectoryPath, localId)
if not os.access(bodyFilePath, os.F_OK):
continue
@ -866,7 +875,8 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
virtualServerDataDirectoryPath, self.applicationRole)
for id, object in virtualServer.objects.items():
changed = object.repair(5004) or changed
serverHostNameAndPort, serverRole, localId = splitObjectId(id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(id)
bodyFilePath = os.path.join(objectsDirectoryPath, localId)
if not os.access(bodyFilePath, os.F_OK):
continue

View File

@ -56,6 +56,7 @@ import glasnost
from glasnost.common.AtomsCommon import *
import glasnost.common.faults as faults
import glasnost.common.context as context
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
from glasnost.server.ObjectsServer import register, ObjectServerMixin, \
@ -77,7 +78,7 @@ class Atom(ObjectServerMixin, AtomCommon):
def canBeCreatedByClient(self):
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId)
return ObjectServerMixin.canBeCreatedByClient(self) \
or clientRole == 'elections'

View File

@ -110,12 +110,20 @@ class CommentsServer(CommentsCommonMixin, ObjectsServer):
def canGetObjects(self):
return 0
def getObjectIdsWithParent(self, parentId):
def canPostEditorialComment(self, parentId):
roleProxy = getProxyForServerRole(
commonTools.extractRole(parentId))
return roleProxy.canModifyObject(parentId)
def getObjectIdsWithParent(self, parentId, isEditorial):
if isEditorial and not self.canPostEditorialComment(parentId):
raise faults.UserAccessDenied()
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
tempResult = []
for objectId, objectCore in virtualServer.objects.items():
if self.getParentId(objectCore) == parentId:
if self.getParentId(objectCore) == parentId and \
objectCore.isEditorial == isEditorial:
tempResult.append(objectId)
result = []
for objectId in tempResult:
@ -133,6 +141,7 @@ class CommentsServer(CommentsCommonMixin, ObjectsServer):
def registerPublicMethods(self):
ObjectsServer.registerPublicMethods(self)
self.registerPublicMethod('canPostEditorialComment')
self.registerPublicMethod('getObjectIdsWithParent')
commentsServer = CommentsServer()

View File

@ -46,6 +46,8 @@ __doc__ = """Glasnost Dispatcher"""
__version__ = '$Revision$'[11:-2]
import os
import sgmllib
import sys
import whrandom
@ -67,6 +69,29 @@ applicationName = 'Dispatcher'
applicationRole = None
class ProfileRolesParser(sgmllib.SGMLParser):
inRole = 0
roleName = None
roles = None
def __init__(self, body):
sgmllib.SGMLParser.__init__(self)
self.roles = []
self.feed(body)
def start_role(self, attrs):
self.inRole = 1
self.roleName = ''
def end_role(self):
self.inRole = 0
self.roles.append(self.roleName)
self.roleName = None
def handle_data(self, data):
if self.inRole:
self.roleName += data
class DispatcherVirtualServer(VirtualServer):
"""Partial class designed for aggregation.
@ -79,7 +104,7 @@ class DispatcherVirtualServer(VirtualServer):
*applicationTokens*:
The dictionnary containing all the Glasnost application token. The
key is the client token.
*serverAccessors*:
The servers access informations dictionnary, sorted by applicationId.
It consists of:
@ -110,6 +135,7 @@ class DispatcherVirtualServer(VirtualServer):
defaultAccessors = None
serverInfos = None
virtualServerIds = None
virtualServerIdProfiles = None
def init(self):
VirtualServer.init(self)
@ -119,6 +145,9 @@ class DispatcherVirtualServer(VirtualServer):
self.serverAccessors = {}
self.serverInfos = {}
self.virtualServerIds = {}
self.virtualServerIdProfiles = {
'glasnost://system': ['basic', 'cms', 'translations'],
}
class Dispatcher(Server):
@ -126,6 +155,7 @@ class Dispatcher(Server):
hasMultipleVirtualServers = 0
randomGenerator = None
useDataFile = 0
rolesByProfile = None
def getApplicationId(self, applicationToken):
"""Get the application ID from the application token.
@ -225,6 +255,17 @@ class Dispatcher(Server):
def init(self):
self.randomGenerator = whrandom.whrandom()
self.rolesByProfile = {}
profilesPath = os.path.join(commonTools.configDir, 'profiles')
profiles = os.listdir(profilesPath)
values = [x[:-4] for x in profiles if x.endswith('.xml')]
for p in values:
pFileName = os.path.join(profilesPath, p + '.xml')
self.rolesByProfile[p] = ProfileRolesParser(
open(pFileName).read()).roles
print 'self.rolesByProfile:', self.rolesByProfile
Server.init(self)
def loadConfigOptions(self):
@ -238,7 +279,7 @@ class Dispatcher(Server):
autorizedHostNames = autorizedHostNames.strip().split()
configContext.setVar('autorizedHostNames', autorizedHostNames)
def registerDispatcherId(self, dispatcherId):
def registerDispatcherId(self, dispatcherId, profiles):
"""Register a new dispatcherId to the dispatcher."""
virtualServer = self.getVirtualServer(None)
@ -255,6 +296,7 @@ class Dispatcher(Server):
clientId = virtualServer.virtualServerIds[clientToken]
virtualServer.dispatcherIds.append(dispatcherId)
virtualServer.virtualServerIdProfiles[dispatcherId] = profiles
print 'Registered dispatcher id "%s"' % dispatcherId
if virtualServer.serverAccessors.has_key(clientId):
@ -273,16 +315,26 @@ class Dispatcher(Server):
serverId = commonTools.makeApplicationId(
'glasnost://%s' % serverAccessor['serverHostName'],
serverInfo['role'])
print 'Calling addDispatcher(%s) for %s' % (dispatcherId, serverId)
context.push(_level = 'registerDispatcherId',
directServerAccessor = serverAccessor)
try:
callServer(serverId, 'addDispatcher', [
serverId, getApplicationToken(),
context.getVar('userToken'), dispatcherId])
finally:
context.pull(_level = 'registerDispatcherId')
print 'Called addDispatcher(%s) for %s' % (dispatcherId, serverId)
rolesForVirtualServer = [''] # '' is for dispatcher
for p in virtualServer.virtualServerIdProfiles[dispatcherId]:
rolesForVirtualServer += self.rolesByProfile[p]
if serverInfo['role'] in rolesForVirtualServer:
print 'Calling addDispatcher(%s) for %s' % (
dispatcherId, serverId)
context.push(_level = 'registerDispatcherId',
directServerAccessor = serverAccessor)
try:
callServer(serverId, 'addDispatcher', [
serverId, getApplicationToken(),
context.getVar('userToken'), dispatcherId])
finally:
context.pull(_level = 'registerDispatcherId')
print 'Called addDispatcher(%s) for %s' % (dispatcherId, serverId)
else:
print 'Not calling addDispatcher(%s) for %s' % (
dispatcherId, serverId)
def registerToDispatcher(self):
applicationId = context.getVar('applicationId')
@ -357,6 +409,15 @@ class Dispatcher(Server):
if not virtualServer.serverInfos.has_key(serverNameAndPort):
raise faults.UnregisteredServer(serverHostName, serverPort)
rolesForVirtualServer = [''] # '' is for dispatcher
for p in virtualServer.virtualServerIdProfiles[serverDispatcherId]:
rolesForVirtualServer += self.rolesByProfile[p]
print 'rolesForVirtualServer:', rolesForVirtualServer
serverRole = commonTools.extractRole(serverId)
if not serverRole in rolesForVirtualServer:
print serverRole, 'not in roles defined by profiles for', serverDispatcherId
raise faults.RoleNotInProfiles(serverRole)
virtualServer.serverAccessors[serverId] = virtualServer.serverInfos[
serverNameAndPort]['accessor']
print 'Registered virtual server %s (for %s:%s)' % (

View File

@ -55,6 +55,7 @@ import glasnost
from glasnost.common.GradesCommon import *
import glasnost.common.faults as faults
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
from glasnost.server.ObjectsServer import register, ObjectServerMixin, \
@ -76,7 +77,7 @@ class Grade(ObjectServerMixin, GradeCommon):
def canBeModifiedByClient(self):
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId)
return ObjectServerMixin.canBeModifiedByClient(self) \
or clientRole == 'elections'
register(Grade)

View File

@ -122,7 +122,7 @@ class GroupsServer(commonGroups.GroupsCommonMixin, objects.ObjectsServer):
if not self.isAdmin():
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId)
if clientRole != 'people':
raise faults.UserAccessDenied()
object = virtualServer.loadObjectCore(objectId)
@ -156,7 +156,7 @@ class GroupsServer(commonGroups.GroupsCommonMixin, objects.ObjectsServer):
if not self.isAdmin():
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId)
if clientRole != 'people':
raise faults.UserAccessDenied()
object = virtualServer.loadObjectCore(objectId)

View File

@ -55,6 +55,7 @@ import glasnost
import glasnost.common.faults as faults
from glasnost.common.PreferencesCommon import PreferenceCommon
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
from glasnost.server.ObjectsServer import Server, VirtualServer
@ -153,7 +154,8 @@ class PreferencesServer(Server):
'__thingName__': 'preferences.Preference',
'version': 0,
}
serverHostNameAndPort, serverRole, localId = splitObjectId(id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(id)
if preference.has_key('objectsMemory'):
objectsMemory = preference['objectsMemory']
else:

View File

@ -58,6 +58,7 @@ import glasnost
import glasnost.common.faults as faults
from glasnost.common.TranslationsCommon import *
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
from glasnost.server.ObjectsServer import register, AdministrableServerMixin, \
@ -540,7 +541,7 @@ class TranslationsServer(TranslationsCommonMixin, AdministrableServerMixin,
destinationLanguages, ignoreNew = 0):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
if splitObjectId(sourceId)[1] == 'virtualhosts':
if commonTools.extractRole(sourceId) == 'virtualhosts':
try:
virtualHost = getProxy(sourceId).getObject(sourceId)
except (faults.MissingItem, faults.UserAccessDenied,

View File

@ -66,6 +66,7 @@ import glasnost
from glasnost.common.UploadFilesCommon import *
import glasnost.common.faults as faults
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
from glasnost.server.ObjectsServer import register, ObjectServerMixin, \
@ -99,7 +100,8 @@ class UploadFile(ObjectServerMixin, UploadFileCommon):
virtualServer = self.getServer().getVirtualServer(virtualServerId)
uploadFilesDirectoryPath = os.path.join(
virtualServer.dataDirectoryPath, self.getServer().applicationRole)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
dataFilePath = os.path.join(uploadFilesDirectoryPath, localId)
try:
dataFile = open(dataFilePath, 'rb')
@ -138,7 +140,8 @@ class UploadFile(ObjectServerMixin, UploadFileCommon):
virtualServer = self.getServer().getVirtualServer(virtualServerId)
uploadFilesDirectoryPath = os.path.join(
virtualServer.dataDirectoryPath, self.getServer().applicationRole)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
dataFilePath = os.path.join(uploadFilesDirectoryPath, localId)
try:
os.remove(dataFilePath)
@ -168,7 +171,8 @@ class UploadFile(ObjectServerMixin, UploadFileCommon):
if not os.access(uploadFilesDirectoryPath, os.F_OK):
os.mkdir(uploadFilesDirectoryPath)
os.chmod(uploadFilesDirectoryPath, 0750)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
dataFilePath = os.path.join(uploadFilesDirectoryPath, localId)
dataFile = open(dataFilePath, 'wb')
os.chmod(dataFilePath, 0640)
@ -247,7 +251,7 @@ class UploadFilesServer(UploadFilesCommonMixin, ObjectsServer):
destinationVirtualServerDataDirectoryPath, self.applicationRole)
for id in virtualServer.objects.keys():
serverHostNameAndPortNotUsed, serverRoleNotUsed, localId = \
splitObjectId(id)
commonTools.splitId(id)
sourceDataFilePath = os.path.join(
sourceObjectsDirectoryPath, localId)
destinationDataFilePath = os.path.join(
@ -284,7 +288,7 @@ class UploadFilesServer(UploadFilesCommonMixin, ObjectsServer):
exportDirectoryPath, self.applicationRole)
for id in virtualServer.objects.keys():
serverHostNameAndPortNotUsed, serverRoleNotUsed, localId = \
splitObjectId(id)
commonTools.splitId(id)
sourceBodyFilePath = os.path.join(
objectsDirectoryPath, localId)
exportBodyFilePath = os.path.join(
@ -342,7 +346,7 @@ class UploadFilesServer(UploadFilesCommonMixin, ObjectsServer):
virtualServerDataDirectoryPath, self.applicationRole)
for id in virtualServer.objects.keys():
serverHostNameAndPortNotUsed, serverRoleNotUsed, localId = \
splitObjectId(id)
commonTools.splitId(id)
importBodyFilePath = os.path.join(
importObjectsDirectoryPath, localId)
destinationBodyFilePath = os.path.join(

View File

@ -47,8 +47,11 @@ __version__ = '$Revision$'[11:-2]
from fnmatch import fnmatch
import os
import sgmllib
import sys
glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install
sys.path.insert(0, glasnostPythonDir)
@ -78,11 +81,62 @@ class AdminVirtualHosts(AdminServerMixin, AdminVirtualHostsCommon):
register(AdminVirtualHosts)
class VirtualHostXmlParser(sgmllib.SGMLParser):
inCustomWeb = 0
customWeb = None
customWebs = None
currentRole = None
inLocale = 0
locale = None
def __init__(self, body):
sgmllib.SGMLParser.__init__(self)
self.customWebs = {}
self.feed(body)
def start_customweb(self, attrs):
if attrs[0][0] == 'role':
self.currentRole = str(attrs[0][1])
self.inCustomWeb = 1
self.customWeb = ''
def end_customweb(self):
if self.inCustomWeb:
self.inCustomWeb = 0
self.customWebs[self.currentRole] = self.customWeb
def start_locale(self, attrs):
self.inLocale = 1
self.locale = ''
def end_locale(self):
self.locale = self.locale.strip()
self.inLocale = 0
def handle_data(self, data):
if self.inCustomWeb:
self.customWeb += data
if self.inLocale:
self.locale += data
class VirtualHost(ObjectServerMixin, VirtualHostCommon):
strings = None
strings_keyType = 'string'
strings_type = 'mapping'
strings_valueType = 'string'
def acquireNonCore(self, objectDirectoryPath = None,
dataDirectoryPath = None, parentSlot = None):
ObjectServerMixin.acquireNonCore(
self, objectDirectoryPath = objectDirectoryPath,
dataDirectoryPath = dataDirectoryPath, parentSlot = parentSlot)
print 'acquireNonCore'
self.customWebs = {}
self.locales = []
profilesPath = os.path.join(commonTools.configDir, 'profiles')
for p in self.profiles:
pFileName = os.path.join(profilesPath, p + '.xml')
vhP = VirtualHostXmlParser(open(pFileName).read())
self.customWebs.update(vhP.customWebs)
if vhP.locale:
self.locales.append(vhP.locale)
def checkModifyIsPossible(self, changes, givenSlotNames = None):
ObjectServerMixin.checkModifyIsPossible(
@ -110,6 +164,14 @@ class VirtualHost(ObjectServerMixin, VirtualHostCommon):
del objectsByHostName[hostName]
if self.hostName is not None:
objectsByHostName[self.hostName] = self
def releaseNonCore(self, parentSlot = None):
if self.__dict__.has_key('customWebs'):
del self.customWebs
if self.__dict__.has_key('locales'):
del self.locales
ObjectServerMixin.releaseNonCore(self, parentSlot = parentSlot)
register(VirtualHost)
@ -204,7 +266,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
virtualServer.markObjectAsDirty(object)
newDispatcherId = object.defaultDispatcherId
registerDispatcherId(newDispatcherId)
registerDispatcherId(newDispatcherId, object.profiles)
newVirtualServerId = commonTools.makeApplicationId(
newDispatcherId, self.applicationRole)
context.push(
@ -237,19 +299,29 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
"""Return the url of the virtual server."""
virtualServerId = context.getVar('applicationId')
print 'getHostName for', virtualServerId
virtualServer = self.getVirtualServer(virtualServerId)
dispatcherId = commonTools.extractDispatcherId(
virtualServerId).lower()
for object in virtualServer.objects.values():
if dispatcherId == commonTools.extractDispatcherId(
object.defaultDispatcherId).lower():
return utf8('http://' + object.hostName)
return utf8(object.hostName)
raise faults.MissingItem(dispatcherId)
def getObjectByHostName(self, hostName):
"""Return the virtual host with the given host name."""
def getObjectByHostNameXmlRpc(self, hostName):
hostName = iso8859_15(hostName)
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
objectId = self.getObjectIdByHostName(hostName)
object = virtualServer.objectsByHostName[hostName]
object.acquireNonCore()
try:
result = object.exportToXmlRpc()
finally:
object.releaseNonCore()
return result
def getObjectIdByHostName(self, hostName):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
askedHostName = hostName
@ -261,6 +333,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
object.hostName = hostName
object.defaultDispatcherId = 'glasnost://%s' % hostName
object.language = 'en'
object.profiles = ['basic', 'cms', 'vote']
object.writersSet = [system.generalPublicId]
object.readersSet = [system.generalPublicId]
context.push(noVirtualHost = 1)
@ -284,17 +357,13 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
virtualServer.admin.defaultVirtualHostId]
except KeyError:
raise faults.MissingItem(hostName)
return object
return object.id
object = virtualServer.objectsByHostName[hostName]
return object
def getObjectByHostNameXmlRpc(self, hostName):
hostName = iso8859_15(hostName)
return self.getObjectByHostName(hostName).exportToXmlRpc()
return object.id
def getObjectIdByHostNameXmlRpc(self, hostName):
hostName = iso8859_15(hostName)
return self.getObjectByHostName(hostName).id
return self.getObjectIdByHostName(hostName)
def hasDispatcherIdXmlRpc(self, dispatcherId):
virtualServerId = context.getVar('applicationId')
@ -329,11 +398,18 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
return ObjectsServer.isAdmin(self)
def modifyObjectXmlRpc(self, objectImport):
version = ObjectsServer.modifyObjectXmlRpc(self, objectImport)
id = objectImport['id']
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
oldObject = virtualServer.loadObjectCore(id)
version = ObjectsServer.modifyObjectXmlRpc(self, objectImport)
object = virtualServer.loadObjectCore(id)
oldObject.profiles.sort()
object.profiles.sort()
if oldObject.profiles != object.profiles:
# FIXME: update profiles (for now it is needed to restart Glasnost)
pass
self.updateApacheVHost(object)
return version
@ -352,7 +428,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
ObjectsServer.registerToDispatcher(self)
for virtualHost in self.virtualServer.objects.values():
newDispatcherId = virtualHost.defaultDispatcherId
registerDispatcherId(newDispatcherId)
registerDispatcherId(newDispatcherId, virtualHost.profiles)
newVirtualServerId = commonTools.makeApplicationId(
newDispatcherId, self.applicationRole)
context.push(
@ -390,6 +466,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
object.defaultDispatcherId = object.defaultDispatcherId[
:-1]
changed = 1
if changed:
virtualServer.markAllAsDirtyFIXME()
@ -450,6 +527,11 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
virtualServer.objectsByHostName[object.hostName] = object
virtualServer.markCoreAsDirty()
def upgrade_0001_0027(self, virtualServer):
for object in virtualServer.objects.values():
object.profiles = ['basic', 'cms', 'vote', 'translations']
virtualServer.markCoreAsDirty()
virtualHostsServer = VirtualHostsServer()

View File

@ -55,6 +55,7 @@ import glasnost
from glasnost.common.VotesCommon import *
import glasnost.common.faults as faults
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
from glasnost.server.ObjectsServer import register, ObjectServerMixin, \
@ -82,25 +83,25 @@ class VoteMixin(ObjectServerMixin):
def canBeCreatedByClient(self):
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId)
return clientRole == 'ballots'
def canBeDeletedByClient(self):
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId)
return clientRole == 'ballots'
def canBeGottenByClient(self):
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId)
return clientRole == 'ballots'
def canBeModifiedByClient(self):
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId)
return clientRole == 'ballots'

View File

@ -72,7 +72,7 @@ class CardCommon(ObjectCommon):
label = N_('Create Mode')
widget_noneLabel = N_('Inherited')
def getValues(self, slot, fields):
def getValues(self, slot):
card = slot.getContainer()
return card.getModeNames()
@ -84,7 +84,7 @@ class CardCommon(ObjectCommon):
stateInViewMode = 'hidden'
widget_noneLabel = N_('Inherited')
def getValues(self, slot, fields):
def getValues(self, slot):
return ['viewAll']
defaultModeName = None
@ -93,7 +93,7 @@ class CardCommon(ObjectCommon):
label = N_('Default Mode')
widget_noneLabel = N_('Inherited')
def getValues(self, slot, fields):
def getValues(self, slot):
card = slot.getContainer()
return card.getModeNames()
@ -106,7 +106,7 @@ class CardCommon(ObjectCommon):
stateInViewMode = 'hidden'
valueThingName = 'Edit'
def getLabels(self, slot, fields):
def getLabels(self, slot):
return {'Edit': slot.getValue().getMenuLabel()}
def getter(self, slot):
@ -129,7 +129,7 @@ class CardCommon(ObjectCommon):
_kindName = 'Mode'
values = [None, 'Custom']
def getLabels(self, slot, fields):
def getLabels(self, slot):
card = slot.parent.getContainer()
if card.modes is not None and len(card.modes) > slot.index \
and card.modes[slot.index] is not None:
@ -163,7 +163,7 @@ class CardCommon(ObjectCommon):
stateInViewMode = 'hidden'
valueThingName = 'View'
def getLabels(self, slot, fields):
def getLabels(self, slot):
return {'View': slot.getValue().getMenuLabel()}
def getter(self, slot):

View File

@ -69,28 +69,30 @@ class CommentCommon(ObjectCommon):
creationTime_kind_importExport = 'from-server-only'
creationTime_kindName = 'CreationTime'
serverRole = 'comments'
isEditorial = 0
class isEditorial_kindClass:
_kindName = 'Boolean'
label = N_('Editorial Comment ?')
parentId = None
parentId_kindName = 'Id'
title = None
title_kind_balloonHelp = N_('Enter the title of your comment.')
title_kind_isRequired = 1
title_kindName = 'String'
serverRole = 'comments'
def canCache(self):
return 1
def getLabel(self):
if self.title:
return self.title
return 'some comment'
return _('some comment')
def getLabelLanguage(self):
'''Return an empty string so that label is not translated'''
return ''
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = ObjectCommon.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['title', 'authorId', 'body' ]
slotNames += ['authorId', 'body' ]
return slotNames

View File

@ -193,11 +193,11 @@ class ObjectsCommonMixin:
The capitalized 'gettextized' handled object class name string.
*objectsName*:
The 'gettextized' functionnal class name string (Usualy the class name
The 'gettextized' functionnal class name string (Usually the class name
without the type (proxy or server, etc...)).
*objectsNameCapitalized*:
The capitalized 'gettextized' class name string (Usualy the class name
The capitalized 'gettextized' class name string (Usually the class name
without the type (proxy or server, etc...)).
*serverRole*:

View File

@ -257,11 +257,11 @@ class PeopleCommonMixin(ObjectsCommonMixin):
The capitalized 'gettextized' handled object class name string.
*objectsName*:
The 'gettextized' functionnal class name string (Usualy the class name
The 'gettextized' functionnal class name string (Usually the class name
without the type (proxy or server, etc...)).
*objectsNameCapitalized*:
The capitalized 'gettextized' class name string (Usualy the class name
The capitalized 'gettextized' class name string (Usually the class name
without the type (proxy or server, etc...)).
*serverRole*:

View File

@ -51,6 +51,7 @@ from ObjectsCommon import AdminCommon, ObjectCommon, ObjectsCommonMixin
import system
import glasnost.common.context as context
import glasnost.common.tools_new as commonTools
class AdminVirtualHostsCommon(AdminCommon):
defaultVirtualHostId = None
@ -91,6 +92,28 @@ class VirtualHostInfoParser(sgmllib.SGMLParser):
self.label += data
class ProfileParser(sgmllib.SGMLParser):
inDescription = 0
description = None
def __init__(self, body):
sgmllib.SGMLParser.__init__(self)
self.feed(body)
def start_description(self, attrs):
if len(attrs) == 0:
self.inDescription = 1
self.description = ''
def end_description(self):
self.inDescription = 0
if self.description:
self.description = self.description.strip()
def handle_data(self, data):
if self.inDescription:
self.description += data
class VirtualHostCommon(ObjectCommon):
"""Virtual host super class used to be inherited with a Mixin Class.
@ -102,6 +125,21 @@ class VirtualHostCommon(ObjectCommon):
creationTime = None
creationTime_kindName = 'CreationTime'
customWebs = None
customWebs_kind_importExport = 'from-server-only'
customWebs_kind_keyKind_valueName = 'String'
customWebs_kind_valueKind_valueName = 'String'
customWebs_kind_stateInViewMode = 'hidden'
customWebs_kind_stateInEditMode = 'hidden'
customWebs_kindName = 'Mapping'
locales = None
locales_kind_itemKind_valueName = 'String'
locales_kind_importExport = 'from-server-only'
locales_kind_stateInViewMode = 'hidden'
locales_kind_stateInEditMode = 'hidden'
locales_kindName = 'Sequence'
defaultDispatcherId = None
defaultDispatcherId_kind_balloonHelp = N_(
'Enter the Glasnost dispatcher id for this virtual host '\
@ -128,8 +166,42 @@ class VirtualHostCommon(ObjectCommon):
modificationTime = None
modificationTime_kindName = 'ModificationTime'
profiles = None
class profiles_kindClass:
_kindName = 'Sequence'
defaultValue = ['basic', 'cms', 'vote']
requiredCount = 1
label = N_('Usage Profiles')
class itemKind_valueClass:
_kindName = 'Choice'
def getLabels(self, slot):
profilesPath = os.path.join(commonTools.configDir, 'profiles')
profiles = self.getValues(slot)
labels = {}
for p in profiles:
pFileName = os.path.join(profilesPath, p + '.xml')
label = ProfileParser(open(pFileName).read()).description
labels[p] = label
return labels
def getSortedValues(self, slot):
# puts 'basic' first
values = self.getValues(slot)
values.sort()
values.remove('basic')
values.insert(0, 'basic')
return values
def getValues(self, slot):
profilesPath = os.path.join(commonTools.configDir, 'profiles')
profiles = os.listdir(profilesPath)
values = [x[:-4] for x in profiles if x.endswith('.xml')]
return values
widgetName = 'MultiCheck'
readersSet = None
readersSet_kind_itemKind_value_defaultValue = system.generalPublicId
readersSet_defaultValue = [system.generalPublicId]
readersSet_kindName = 'ReadersSet'
serverRole = 'virtualhosts'
@ -144,7 +216,7 @@ class VirtualHostCommon(ObjectCommon):
isRequired = 1
defaultValue = 'glasnost2'
label = N_('Template')
def getValues(self, slot, fields):
def getValues(self, slot):
templatesDirectoryPath = context.getVar('templatesDirectoryPath')
dirs = os.listdir(templatesDirectoryPath)
values = []
@ -155,9 +227,9 @@ class VirtualHostCommon(ObjectCommon):
values.sort()
return values
def getLabels(self, slot, fields):
def getLabels(self, slot):
templatesDirectoryPath = context.getVar('templatesDirectoryPath')
dirs = self.getValues(slot, fields)
dirs = self.getValues(slot)
labels = {}
for d in dirs:
infosName = os.path.join(templatesDirectoryPath, d, 'infos.xml')
@ -249,11 +321,11 @@ class VirtualHostsCommonMixin(ObjectsCommonMixin):
The capitalized 'gettextized' handled object class name string.
*objectsName*:
The 'gettextized' functionnal class name string (Usualy the class name
The 'gettextized' functionnal class name string (Usually the class name
without the type (proxy or server, etc...)).
*objectsNameCapitalized*:
The capitalized 'gettextized' class name string (Usualy the class name
The capitalized 'gettextized' class name string (Usually the class name
without the type (proxy or server, etc...)).
*serverRole*:

View File

@ -733,12 +733,12 @@ def convertStringToXml(s):
def convertStringToXmlAttributeValue(s):
### FIXME: Which characters should be transcoded?
s = s.replace('&', '&amp;') # ?
s = s.replace('"', '&quot;') # '"' must be converted.
s = s.replace('<', '&lt;') # ?
s = s.replace('>', '&gt;') # ?
return s
return s.replace(
'&', '&amp;').replace(
'"', '&quot;').replace(
'\'', '&apos;').replace(
'<', '&lt;').replace(
'>', '&gt;')
def enclose(object, **enclosingAttributes):

View File

@ -92,6 +92,7 @@ faultCodeStringNotAvailableThroughGettext = 39
faultCodeUnknownCommandAction = 40
faultCodeValueTooBig = 41
faultCodeValueTooSmall = 42
faultCodeRoleNotInProfiles = 43
faultCodeUnknownVoteToken = 1000
faultCodeUnknownVoterToken = 1001
@ -552,6 +553,12 @@ class ValueTooBig(BaseFault):
return 'Value (= %s) too big for slot "%s"' % (value, slot)
class RoleNotInProfiles(BaseFault):
faultCode = faultCodeRoleNotInProfiles
uiFaultString = N_('Role not in profiles')
def makeFaultString(self, role):
return 'Role (%s) not in profiles' % role
# Dataflow.

View File

@ -435,13 +435,13 @@ class BaseKind(things.BaseThing):
isRequired = 1
label = N_('Widget')
def getGroupedValues(self, slot, fields):
def getGroupedValues(self, slot):
return (None, None) # groupNames, groupedValues
def getter(self, slot):
return slot.getContainer().getModelWidget(slot.parent)
def getValues(self, slot, fields):
def getValues(self, slot):
values = slot.getContainer().getPossibleWidgetNames()
if values:
return values
@ -1017,22 +1017,22 @@ class Boolean(BaseKind):
return str(value)
return BaseKind.convertValueToOtherType(self, value, otherType)
def getGroupedValues(self, slot, fields):
def getGroupedValues(self, slot):
return (None, None) # groupNames, groupedValues
def getLabels(self, slot, fields):
def getLabels(self, slot):
return self.labels
def getSortedValues(self, slot, fields):
values = self.getValues(slot, fields)
def getSortedValues(self, slot):
values = self.getValues(slot)
if values is not None:
values = values[:]
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
values.sort(lambda x, y:
locale.strcoll(_(labels[x]), _(labels[y])))
return values
def getValues(self, slot, fields):
def getValues(self, slot):
return self.values
def getOrderedLayoutSlotNames(self, parentSlot = None):
@ -1129,10 +1129,10 @@ class Choice(BaseKind):
def checkModelValue(self, slot, value):
BaseKind.checkModelValue(self, slot, value)
if value and self.values and value not in self.getValues(slot, {}):
if value and self.values and value not in self.getValues(slot):
raise faults.BadSlotValue(slot, value)
def getGroupedValues(self, slot, fields):
def getGroupedValues(self, slot):
if self.groupedValuesGetterName:
currentSlot = slot
while currentSlot is not None:
@ -1140,22 +1140,22 @@ class Choice(BaseKind):
try:
groupedValuesGetter = getattr(container,
self.groupedValuesGetterName)
self.groupedValues = groupedValuesGetter(slot, fields)
self.groupedValues = groupedValuesGetter(slot)
if self.groupNamesGetterName:
groupNamesGetter = getattr(container,
self.groupNamesGetterName)
self.groupNames = groupNamesGetter(slot, fields)
self.groupNames = groupNamesGetter(slot)
break
except AttributeError:
currentSlot = currentSlot.parent
continue
return (self.groupNames, self.groupedValues)
def getLabels(self, slot, fields):
def getLabels(self, slot):
if self.labels:
return self.labels
labels = {}
values = self.getValues(slot, fields)
values = self.getValues(slot)
if values is not None:
for value in values:
labels[str(value)] = str(value)
@ -1167,8 +1167,8 @@ class Choice(BaseKind):
slotNames += ['values', 'labels', 'titles']
return slotNames
def getSortedValues(self, slot, fields):
values = self.getValues(slot, fields)
def getSortedValues(self, slot):
values = self.getValues(slot)
if values is None:
return None
values = values[:]
@ -1179,12 +1179,12 @@ class Choice(BaseKind):
if '__all__' in values:
sortedValues.append('__all__')
values.remove('__all__')
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
values.sort(lambda x, y: locale.strcoll(_(labels[x]), _(labels[y])))
sortedValues += values
return sortedValues
def getValues(self, slot, fields):
def getValues(self, slot):
groupedValuesGetterName = self.groupedValuesGetterName
if groupedValuesGetterName is not None:
currentSlot = slot
@ -1196,7 +1196,7 @@ class Choice(BaseKind):
except AttributeError:
currentSlot = currentSlot.parent
continue
groupedValues = groupedValuesGetter(slot, fields)
groupedValues = groupedValuesGetter(slot)
assert type(groupedValues) is type({})
values = []
for group in groupedValues.keys():
@ -1214,7 +1214,7 @@ class Choice(BaseKind):
except AttributeError:
currentSlot = currentSlot.parent
continue
return valuesGetter(slot, fields)
return valuesGetter(slot)
return []
if self.groupedValues:
result = []
@ -1504,44 +1504,6 @@ class Float(BaseKind):
register(Float)
class FunctionName(Choice):
defaultValue_kindName = 'FunctionName'
pythonStorageType = types.StringType
serverIdSlotName = None
serverIdSlotName_kindName = 'String'
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Function Name')
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):
containerNames = ['Any']
@ -1595,8 +1557,8 @@ class Id(BaseKind):
kindServerRoles.sort()
return serverRoles == kindServerRoles
def getLabels(self, slot, fields):
values = self.getValues(slot, fields)
def getLabels(self, slot):
values = self.getValues(slot)
from glasnost.proxy.tools import getObjectLabelsTranslated
labels = getObjectLabelsTranslated(values,
context.getVar('readLanguages'))
@ -1605,7 +1567,7 @@ class Id(BaseKind):
def getServerRoles(self, slot):
return self.serverRoles
def getValues(self, slot, fields):
def getValues(self, slot):
valuesGetterName = self.valuesGetterName
if valuesGetterName is not None:
currentSlot = slot
@ -1616,7 +1578,7 @@ class Id(BaseKind):
except AttributeError:
currentSlot = currentSlot.parent
continue
return valuesGetter(slot, fields)
return valuesGetter(slot)
# TODO:
# 1. remove valuesGetterName since getValues() can now be redefined
@ -3118,8 +3080,8 @@ class ServerRole(Choice):
thingPublicName = N_('Server Role')
def getLabels(self, slot, fields):
roles = self.getValues(slot, fields)
def getLabels(self, slot):
roles = self.getValues(slot)
labels = {}
for role in roles:
if role in [None, '__all__']:
@ -3132,7 +3094,7 @@ class ServerRole(Choice):
labels[role] = label
return labels
def getValues(self, slot, fields):
def getValues(self, slot):
from glasnost.proxy.DispatcherProxy import getRegisteredRoles
values = []
if self.allowNone:
@ -3389,7 +3351,7 @@ class Thing(Choice):
return None
return value.exportToXmlRpc(parentSlot = slot)
def getGroupedValues(self, slot, fields):
def getGroupedValues(self, slot):
categories = []
groupedValues = {}
for thingClass in commonTools.getAllThingClasses().values():
@ -3403,7 +3365,7 @@ class Thing(Choice):
groupedValues[thingClass.thingPublicCategory].append(
thingClass.getThingName.im_func(thingClass))
categories.sort(lambda x, y: locale.strcoll(_(x), _(y)))
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
for values in groupedValues.values():
values.sort(lambda x, y:
locale.strcoll(_(labels[x]), _(labels[y])))
@ -3414,7 +3376,7 @@ class Thing(Choice):
self.valueThingCategory, self.valueThingName)
return value.getDefaultValue(slot)
def getLabels(self, slot, fields):
def getLabels(self, slot):
if self.labels is not None:
return self.labels
self.labels = {}
@ -3461,7 +3423,7 @@ class Thing(Choice):
widget.buildOptions(widgetOptions)
return widget
def getValues(self, slot, fields):
def getValues(self, slot):
if self.values is not None:
return self.values
self.values = [
@ -3781,7 +3743,7 @@ class XChoice(Choice):
thingPublicName = N_('Extended Choice')
widgetName = 'XSelect'
def getGroupedValues(self, slot, fields):
def getGroupedValues(self, slot):
return (self.groupNames, self.groupedValues)
register(XChoice)
@ -3871,7 +3833,7 @@ class KindName(Choice):
## for kindClass in commonTools.getAllThingClasses().values()
## if kindClass.thingCategory == 'kind']
def getGroupedValues(self, slot, fields):
def getGroupedValues(self, slot):
categories = []
groupedValues = {}
for kindClass in commonTools.getAllThingClasses().values():
@ -3885,13 +3847,13 @@ class KindName(Choice):
groupedValues[kindClass.thingPublicCategory].append(
kindClass.getThingName.im_func(kindClass))
categories.sort(lambda x, y: locale.strcoll(_(x), _(y)))
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
for values in groupedValues.values():
values.sort(lambda x, y:
locale.strcoll(_(labels[x]), _(labels[y])))
return (categories, groupedValues) # groupNames, groupedValues
def getValues(self, slot, fields):
def getValues(self, slot):
return [
kindClass.getThingName.im_func(kindClass)
for kindClass in commonTools.getAllThingClasses().values()
@ -3922,7 +3884,7 @@ class Mode(Thing):
return value.getThingName()
return BaseKind.convertValueToOtherType(self, value, otherType)
def getGroupedValues(self, slot, fields):
def getGroupedValues(self, slot):
return (None, None) # groupNames, groupedValues
register(Mode)
@ -3979,8 +3941,8 @@ class WidgetName(Choice):
thingPublicCategory = None # N_('Glasnost')
thingPublicName = N_('Widget Name')
def getValues(self, slot, fields):
values = Choice.getValues(self, slot, fields)
def getValues(self, slot):
values = Choice.getValues(self, slot)
if values:
return values
else:

View File

@ -81,7 +81,7 @@ class Aspect(things.BaseThing):
label = N_('Name')
widget_apply = 1
def getValues(self, slot, fields):
def getValues(self, slot):
card = slot.getObject()
return card.getPropertyNames()
@ -140,10 +140,10 @@ class Aspect(things.BaseThing):
isRequired = 1
label = N_('Widget')
def getGroupedValues(self, slot, fields):
def getGroupedValues(self, slot):
return (None, None) # groupNames, groupedValues
def getValues(self, slot, fields):
def getValues(self, slot):
nameSlot = slot.getContainer().getSlot(
'name', parentSlot = slot.parent)
name = nameSlot.getValue()
@ -154,7 +154,7 @@ class Aspect(things.BaseThing):
return kind.getPossibleWidgetNames()
# When the property name is missing, return an empty list of
# widgets.
# return self.getRealKindClass().getValues(self, slot, fields)
# return self.getRealKindClass().getValues(self, slot)
return []
def getOrderedFieldSlotNames(self, fields, parentSlot = None):

View File

@ -353,36 +353,6 @@ Content-Type: application/octet-stream
raise faults.SmtpError()
def splitApplicationId(applicationId):
# FIXME: To remove and replace by commonTools.splitId, which accepts any
# id.
try:
assert applicationId.startswith('glasnost://')
splittedApplicationId = applicationId[11:].split('/', 2)
assert len(splittedApplicationId) == 2
# applicationHostNameAndPort, applicationRole = splittedApplicationId
except IndexError:
raise Exception('Malformed application id = %s' % str(applicationId))
except AssertionError:
raise Exception('Malformed application id = %s' % str(applicationId))
return splittedApplicationId
def splitObjectId(id):
# FIXME: To remove and replace by commonTools.splitId, which accepts any
# id.
try:
assert id.startswith('glasnost://')
splittedId = id[11:].split('/', 2)
assert len(splittedId) == 3
# applicationHostNameAndPort, applicationRole, localId = splittedId
except IndexError:
raise Exception('Malformed id = %s' % str(id))
except AssertionError:
raise Exception('Malformed id = %s' % str(id))
return splittedId
def utf8(s):
"""Convert a string from iso-8859-15 to utf-8."""
if type(s) == types.UnicodeType:

View File

@ -166,10 +166,10 @@ class ExclusiveChoiceAbstract(BaseWidget):
titles_kind_valueKind_valueName = 'String'
titles_kindName = 'Mapping'
def getLabels(self, slot, fields):
def getLabels(self, slot):
if self.labels:
return self.labels
return slot.getKind().getLabels(slot, fields)
return slot.getKind().getLabels(slot)
class Amount(BaseWidget):
@ -256,10 +256,10 @@ class InputCheckBox(BaseWidget):
titles_kind_valueKind_valueName = 'String'
titles_kindName = 'Mapping'
def getLabels(self, slot, fields):
def getLabels(self, slot):
if self.labels:
return self.labels
return slot.getKind().getLabels(slot, fields)
return slot.getKind().getLabels(slot)
register(InputCheckBox)

View File

@ -239,6 +239,9 @@ class buttonStandalone:
trueTag = a(_class = 'button', href = self.href)(text)
return trueTag.getAsXml(**keywords)
def hContext():
sectionLevel = context.getVar('sectionLevel')
return globals()['h%d' % (sectionLevel+1)]
class menuIds:
attributes = {}

View File

@ -94,7 +94,7 @@ class RubricsScreen(CursesScreen):
if not hasattr(rubric, 'membersSet'):
return
for r in rubric.membersSet:
if splitObjectId(r)[1] != 'rubrics':
if commonTools.extractRole(r) != 'rubrics':
continue
r = [ x for x in self.rubricsL if x.id == r ][0]
self.buildHier(r, level+1)
@ -140,7 +140,7 @@ class RubricsScreen(CursesScreen):
statusLine = '%s %s' % (
currentRubric.rubric.id.ljust(width-17),
(currentRubric.rubric.contentId and \
'contentId: %3d' % int(splitObjectId(currentRubric.rubric.contentId)[2]))
'contentId: %3d' % int(commonTools.extractLocalId(currentRubric.rubric.contentId)))
or '')
self.stdscr.addstr(height-1, 0, statusLine.ljust(width-1))
@ -203,7 +203,8 @@ class RubricsScreen(CursesScreen):
i = start
if not hasattr(r, 'membersSet'):
r.membersSet = []
r.membersSet = [ x for x in r.membersSet if splitObjectId(x)[1] != 'rubrics' ]
r.membersSet = [ x for x in r.membersSet if \
commonTools.extractRole(x) != 'rubrics' ]
for r2 in self.rubrics[start:]:
i += 1
if r2.level == indent:
@ -297,7 +298,7 @@ class RubricScreen(CursesScreen):
}
self.rubric = rubric
self.objects = [ GlasnostObject(x) for x in rubric.membersSet \
if splitObjectId(x)[1] != 'rubrics' ]
if commonTools.extractRole(x) != 'rubrics' ]
height, width = self.stdscr.getmaxyx()
for i in range(1, height-3):

View File

@ -228,11 +228,6 @@ class Float(KindMixin, proxyKinds.Float):
register(Float)
class FunctionName(ChoiceMixin, proxyKinds.FunctionName):
pass
register(FunctionName)
class Id(IdMixin, proxyKinds.Id):
pass
register(Id)

View File

@ -64,16 +64,26 @@ register(Comment)
class CommentsProxy(CommentsCommonMixin, ObjectsProxy):
def getObjectIdsWithParent(self, parentId, serverId = None):
def canPostEditorialComment(self, parentId, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'canPostEditorialComment',
[serverId, getApplicationToken(), userToken, parentId])
def getObjectIdsWithParent(self, parentId, isEditorial, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'getObjectIdsWithParent',
[serverId, getApplicationToken(), userToken, parentId])
[serverId, getApplicationToken(), userToken,
parentId, isEditorial])
def getObjectsWithParent(self, parentId, serverId = None):
objectIds = self.getObjectIdsWithParent(parentId, serverId = serverId)
def getObjectsWithParent(self, parentId, isEditorial, serverId = None):
objectIds = self.getObjectIdsWithParent(parentId, isEditorial,
serverId = serverId)
multiCall = MultiCall()
for objectId in objectIds:
self.getObject(objectId, multiCall = multiCall)

View File

@ -748,13 +748,14 @@ def getServerAccessor(serverId):
return serverAccessor
def registerDispatcherId(newDispatcherId):
def registerDispatcherId(newDispatcherId, profiles):
userToken = context.getVar('userToken', default = '')
dispatcherId = context.getVar('dispatcherId', default = '')
callServer(
dispatcherId,
'registerDispatcherId',
[dispatcherId, getApplicationToken(), userToken, newDispatcherId])
[dispatcherId, getApplicationToken(), userToken, newDispatcherId,
profiles])
def registerServer(serverHostName, serverPort):

View File

@ -405,14 +405,15 @@ class AdministrableProxyMixin:
[serverId, getApplicationToken(), userToken, adminExport])
return None
def newAdmin(self, fields):
def newAdmin(self, keywords = None):
"""Instanciate a new Admin class.
Keyword argument:
=================
*fields*:
Not used, if somebody knows, tell us :-).
*keywords*:
May be used in subclasses to create different objects on the basis
of some keyword.
Exceptions:
===========
@ -1598,7 +1599,7 @@ class ObjectsProxy(ObjectsCommonMixin, AdministrableProxyMixin, Proxy):
userToken, objectExport, givenSlotNames])
return None
def newObject(self, fields = None):
def newObject(self, keywords = None):
"""Instanciate a new object.
The class of the new object instance is stored in the *objectClassName*
@ -1607,8 +1608,9 @@ class ObjectsProxy(ObjectsCommonMixin, AdministrableProxyMixin, Proxy):
Keyword argument:
=================
*fields*:
Useless.
*keywords*:
May be used in subclasses to create different objects on the basis
of some keyword.
Return the new object instance.

View File

@ -90,9 +90,6 @@ class VirtualHostsProxy(VirtualHostsCommonMixin, ObjectsProxy):
'canModifyObject',
[serverId, getApplicationToken(), userToken, objectId])
def getObjectByHostName(self, hostName, serverId = None):
userToken = context.getVar('userToken', default = '')
def getHostName(self, serverId):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
@ -127,6 +124,8 @@ class VirtualHostsProxy(VirtualHostsCommonMixin, ObjectsProxy):
'getObjectByHostName',
[serverId, getApplicationToken(), userToken, utf8(hostName)])
return commonTools.importThing(objectImport)
objectId = self.getObjectIdByHostName(hostName, serverId = serverId)
return self.getObject(objectId)
def getObjectIdByHostName(self, hostName, serverId = None):
userToken = context.getVar('userToken', default = '')

View File

@ -219,11 +219,6 @@ class Float(KindMixin, commonKinds.Float):
register(Float)
class FunctionName(ChoiceMixin, commonKinds.FunctionName):
pass
register(FunctionName)
class Id(IdMixin, commonKinds.Id):
pass
register(Id)

View File

@ -66,11 +66,11 @@ def getObjectLabelsTranslated(ids, destinationLanguages):
while remainingIds:
id = remainingIds[0]
del remainingIds[0]
serverHostNameAndPort, serverRole, localId = splitObjectId(id)
serverHostNameAndPort, serverRole, localId = commonTools.splitId(id)
proxyIds = [id]
remainingIds2 = remainingIds[:]
for id2 in remainingIds2:
serverHostNameAndPort2, serverRole2, localId2 = splitObjectId(id2)
serverHostNameAndPort2, serverRole2, localId2 = commonTools.splitId(id2)
if serverHostNameAndPort2 == serverHostNameAndPort \
and serverRole2 == serverRole:
proxyIds.append(id2)
@ -170,7 +170,7 @@ def sortIds(ids):
return []
idsByServer = {}
for id in ids:
serverHostNameAndPort, serverRole, localId = splitObjectId(id)
serverHostNameAndPort, serverRole, localId = commonTools.splitId(id)
serverId = commonTools.extractServerId(id)
if not idsByServer.has_key(serverId):
proxy = getProxyForServerRole(serverRole)
@ -184,7 +184,7 @@ def sortIds(ids):
serverIds.sort()
result = []
for serverId in serverIds:
serverHostNameAndPort, serverRole = splitApplicationId(serverId)
serverNameAndPort, serverRole, mu = commonTools.splitId(serverId)
proxy = getProxyForServerRole(serverRole)
ids = idsByServer[serverId]
sortedIds = proxy.sortObjectIds(ids, serverId = serverId, forceIds = 1)

View File

@ -89,7 +89,7 @@ class ObjectServerMixin(things.ThingMixin):
All methods can be overriden or extended, in fact, this class define their
default behavior.
The client that want to operate on the object is usualy a other server.
The client that want to operate on the object is usually a other server.
"""
id_kind_isAutomaticallyModified = 1
@ -108,7 +108,7 @@ class ObjectServerMixin(things.ThingMixin):
"""Load the data associated with the object.
The datas are loaded, but the metadata are in the object instance.
The datas are usualy big things like files, text, etc...
The datas are usually big things like files, text, etc...
Keyword arguments:
==================
@ -135,8 +135,8 @@ class ObjectServerMixin(things.ThingMixin):
dataDirectoryPath = virtualServer.dataDirectoryPath
objectsDirectoryPath = os.path.join(
dataDirectoryPath, server.applicationRole)
serverHostNameAndPort, serverRole, localId = splitObjectId(
self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
objectDirectoryPath = os.path.join(
objectsDirectoryPath, localId)
things.ThingMixin.acquireNonCore(
@ -145,10 +145,7 @@ class ObjectServerMixin(things.ThingMixin):
def canBeCreatedByClient(self):
"""Indicate whether the client application can create an object."""
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
return clientRole == 'workflows'
return 0
def canBeDeletedByClient(self):
"""Indicate whether the client application can delete the object."""
@ -158,10 +155,7 @@ class ObjectServerMixin(things.ThingMixin):
def canBeGottenByClient(self):
"""Indicate whether the client application can get the object."""
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
return clientRole == 'workflows'
return 0
def canBeModified(self):
"""Indicate whether the object can be modified."""
@ -171,10 +165,7 @@ class ObjectServerMixin(things.ThingMixin):
def canBeModifiedByClient(self):
"""Indicate whether the client application can modify the object."""
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
return clientRole == 'workflows'
return 0
def checkAddIsPossible(self):
"""Indicate whether the object can be added to the server dictionnary.
@ -319,7 +310,7 @@ class ObjectServerMixin(things.ThingMixin):
dataDirectoryPath = None, parentSlot = None):
"""Remove the object datas from memory.
The datas are usualy big things like files, text, etc...
The datas are usually big things like files, text, etc...
Keyword arguments:
==================
@ -350,7 +341,8 @@ class ObjectServerMixin(things.ThingMixin):
dataDirectoryPath, server.applicationRole)
if not os.access(objectsDirectoryPath, os.F_OK):
return
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
objectDirectoryPath = os.path.join(objectsDirectoryPath, localId)
if not os.access(objectDirectoryPath, os.F_OK):
return
@ -364,7 +356,7 @@ class ObjectServerMixin(things.ThingMixin):
parentSlot = None):
"""Save the object datas.
The datas are usualy big things like files, text, etc...
The datas are usually big things like files, text, etc...
Keyword arguments:
==================
@ -399,7 +391,8 @@ class ObjectServerMixin(things.ThingMixin):
if not os.access(objectsDirectoryPath, os.F_OK):
os.mkdir(objectsDirectoryPath)
os.chmod(objectsDirectoryPath, 0750)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id)
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
objectDirectoryPath = os.path.join(objectsDirectoryPath, localId)
if os.access(objectDirectoryPath, os.F_OK):
try:
@ -739,7 +732,6 @@ class Server(things.BaseThing, applications.Application):
hasMultipleVirtualServers = 1
hostName = None
isThreaded = 1
onlyForDispatcherIds = None
port = None
rpcServer = None
thingCategory = 'server'
@ -756,12 +748,14 @@ class Server(things.BaseThing, applications.Application):
# TODO: check on clientToken (only dispatcher we registered to should
# be allowed)
if self.hasMultipleVirtualServers and self.onlyForDispatcherIds \
and not newDispatcherId in self.onlyForDispatcherIds:
return
newVirtualServerId = commonTools.makeApplicationId(
newDispatcherId, self.applicationRole)
try:
registerVirtualServer(self.hostName, self.port, newVirtualServerId)
except faults.RoleNotInProfiles:
return
if self.hasMultipleVirtualServers:
self.virtualServers[newVirtualServerId] = self.loadVirtualServer(
newVirtualServerId)
@ -771,7 +765,6 @@ class Server(things.BaseThing, applications.Application):
context.getVar('applicationTokens')[newVirtualServerId] = \
getApplicationToken()
context.pull()
registerVirtualServer(self.hostName, self.port, newVirtualServerId)
def canGetAdmin(self):
"""Indicate whether the caller is able to get the admin instance.
@ -1125,14 +1118,6 @@ class Server(things.BaseThing, applications.Application):
if self.port is not None:
del self.port
onlyForDispatcherIds = commonTools.getConfig(
self.applicationName, 'OnlyForDispatchers')
if onlyForDispatcherIds:
self.onlyForDispatcherIds = onlyForDispatcherIds.replace(
',', ' ').split()
elif self.onlyForDispatcherIds is not None:
del self.onlyForDispatcherIds
if self.useDataFile:
self.dataDirectoryPath = commonTools.getConfig(
'Misc', 'DataDirectoryPath')
@ -1317,14 +1302,14 @@ class Server(things.BaseThing, applications.Application):
# Register each virtual server to the dispatcher.
if self.hasMultipleVirtualServers:
if self.onlyForDispatcherIds:
dispatcherIds = [
dispatcherId
for dispatcherId in self.onlyForDispatcherIds
if dispatcherId and dispatcherId in dispatcherIds]
for dispatcherId in dispatcherIds:
virtualServerId = commonTools.makeApplicationId(
dispatcherId, self.applicationRole)
try:
registerVirtualServer(
self.hostName, self.port, virtualServerId)
except faults.RoleNotInProfiles:
continue
self.virtualServers[virtualServerId] = self.loadVirtualServer(
virtualServerId)
context.push(
@ -1333,8 +1318,6 @@ class Server(things.BaseThing, applications.Application):
context.getVar('applicationTokens')[virtualServerId] = \
getApplicationToken()
context.pull()
registerVirtualServer(
self.hostName, self.port, virtualServerId)
def removeIdsFromVirtualServer(self, dispatcherId, rolesToKeep):
virtualServerId = commonTools.makeApplicationId(

View File

@ -277,11 +277,6 @@ class Float(KindMixin, commonKinds.Float):
register(Float)
class FunctionName(ChoiceMixin, commonKinds.FunctionName):
pass
register(FunctionName)
class Id(IdMixin, commonKinds.Id):
pass
register(Id)

View File

@ -47,6 +47,8 @@ __version__ = '$Revision$'[11:-2]
import calendar
import time
import glasnost.common.tools_new as commonTools
from glasnost.proxy.AppointmentsProxy import *
from ObjectsWeb import register, AdminMixin, ObjectWebMixin, ObjectsWebMixin
@ -77,7 +79,7 @@ class Appointment(ObjectWebMixin, Appointment):
stateInEditMode = 'read-write'
class itemKind_valueClass:
_kindName = 'Id'
def getValues(self, slot, fields):
def getValues(self, slot):
admin = slot.getObject().getWeb().getAdmin()
groupsProxy = getProxyForServerRole('groups')
if not admin.categoriesGroupId:
@ -624,7 +626,7 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
for d in dayAppointments:
hasDetails = 0
li = X.li()
disp, role, id = splitObjectId(d.id)
disp, role, id = commonTools.splitId(d.id)
idAttribute = 'appointment-%s-%s' % (disp, id)
li += X.a(href = X.idUrl(d.id), id = idAttribute)(
d.getLabelTranslated(withHour = 1))

View File

@ -537,7 +537,7 @@ correctly configured.\
if not usercardWeb.canAddObject():
return accessForbidden()
userCardObject = usercardWeb.newObject(None)
userCardObject = usercardWeb.newObject()
authObject = self.newAuthenticationObject()
return self.newAccountObject(userCardObject, authObject)
@ -583,7 +583,7 @@ correctly configured.\
if not usercardWeb.canAddObject():
return accessForbidden()
userCardObject = usercardWeb.newObject(fields = None)
userCardObject = usercardWeb.newObject()
userCardSlot = slots.Root(userCardObject, name = 'userCard')
userCardObject.submitFields(keywords, parentSlot = userCardSlot)
if userCardObject.id:

View File

@ -66,10 +66,6 @@ class Comment(ObjectWebMixin, Comment):
body_kind_widget_rows = 20
body_kind_widgetName = 'TextArea'
title_kind_widget_fieldLabel = N_('Title')
title_kind_widget_size = 40
title_kind_widgetName = 'InputText'
def getEditLayoutSlotNames(self, fields, parentSlot = None):
slotNames = ObjectWebMixin.getEditLayoutSlotNames(self, fields,
parentSlot = parentSlot) [:]
@ -79,23 +75,28 @@ class Comment(ObjectWebMixin, Comment):
slotNames.remove('parentId')
if 'creationTime' in slotNames:
slotNames.remove('creationTime')
if 'isEditorial' in slotNames:
if not self.getWeb().canPostEditorialComment(self.parentId):
slotNames.remove('isEditorial')
pass
return slotNames
def getViewLayoutSlotNames(self, fields, parentSlot = None):
return ['title', 'body']
return ['authorId', 'creationTime', 'body']
def getViewLayout(self, fields, parentSlot = None):
sectionLevel = context.getVar('sectionLevel')
context.push(sectionLevel = sectionLevel+1)
layout = X.array()
titleSlot = self.getSlot('title')
titleHtml = titleSlot.getWidget().getHtmlValue(titleSlot, fields)
titleTag = getattr(X, 'h%s' % (sectionLevel+1))
if len(titleHtml.children) == 2:
# remove translation bar
del titleHtml.children[1]
layout += titleTag(titleHtml)
#titleSlot = self.getSlot('title')
#titleHtml = titleSlot.getWidget().getHtmlValue(titleSlot, fields)
#titleTag = getattr(X, 'h%s' % (sectionLevel+1))
#if len(titleHtml.children) == 2:
# # remove translation bar
# del titleHtml.children[1]
#layout += titleTag(titleHtml)
authorIdSlot = self.getSlot('authorId')
if authorIdSlot.getValue():
@ -130,6 +131,46 @@ class CommentsWeb(ObjectsWebMixin, CommentsProxy):
def use(self): pass
def view(self): pass
def getCommentsLayout(self, parentId, isEditorial = 0):
comments = self.getObjectsWithParent(parentId, isEditorial).values()
comments.sort(lambda x,y: cmp(x.creationTime, y.creationTime))
layout = X.array()
if len(comments) == 0:
#layout += X.p(_('No comment.'))
return None
for i, comment in zip(range(len(comments)), comments):
layout += X.div(_class = 'comment', id = 'comment-%d' % (i+i))(
X.span(_class = 'comment-no')(str(i+1)),
comment.getViewLayout(self, None))
return layout
def getBothCommentsLayout(self, parentId):
layout = X.array()
if self.canPostEditorialComment(parentId):
context.push(sectionLevel = context.getVar('sectionLevel') + 1)
comments = self.getCommentsLayout(parentId, isEditorial = 1)
context.pull()
if comments is not None:
layout += X.hContext()(
id = 'editorial-comments')(_('Editorial Comments'))
layout += comments
context.push(sectionLevel = context.getVar('sectionLevel') + 1)
comments = self.getCommentsLayout(parentId)
context.pull()
if comments is not None:
layout += X.hContext()(id = 'comments')(_('Comments'))
layout += comments
if self.canAddObject():
layout += X.div(_class = 'buttons-bar')(
X.buttonStandalone(_('Add Comment'),
X.idUrl(parentId, 'addComment')))
return layout
def viewAll(self):
layout = X.array()
userToken = context.getVar('userToken')

View File

@ -770,9 +770,9 @@ class ElectionsWeb(ObjectsWebMixin, ElectionsProxy):
return OK
graphPie.isPublicForWeb = 1
def newObject(self, fields = None):
if fields and fields.has_key('method') and \
fields['method'] == 'average':
def newObject(self, keywords = None):
if keywords and keywords.has_key('method') and \
keywords['method'] == 'average':
object = ElectionAverage()
else:
object = ElectionCondorcet()

View File

@ -176,13 +176,13 @@ class GroupsWeb(objects.ObjectsWebMixin, proxyGroups.GroupsProxy):
object.itemIds = _('Illegal recursive group')
return object
def newObject(self, fields = None):
def newObject(self, keywords = None):
group = GroupUnion() # fake group to get className
if not fields:
if not keywords:
group.className = 'GroupUnion'
return group
classNameSlot = group.getSlot('className')
className = classNameSlot.getWidget().submit(classNameSlot, fields)
className = classNameSlot.getWidget().submit(classNameSlot, keywords)
if not className:
className = 'GroupUnion'
group = commonTools.newThing('object', 'groups.%s' % className)

View File

@ -302,7 +302,7 @@ class ObjectsWebMixin(AdministrableWebMixin):
return pageNotFound()
delete.isPublicForWeb = 1
def download(self, id, path):
def download(self, id, filename = '', path = 'self'):
localId = commonTools.extractLocalId(id)
if localId == '__admin__':
if not self.canGetAdmin():
@ -324,6 +324,10 @@ class ObjectsWebMixin(AdministrableWebMixin):
dataFileName = upload.getSlot(
'dataFileName', parentSlot = uploadSlot).getValue()
if dataFileName:
if not filename:
uri = X.idUrl(id, 'download/%s' % dataFileName).add(
'path', path)
return redirect(uri)
req.headers_out['Content-Disposition'] = \
'inline; filename="%s"' % dataFileName
req.headers_out['Content-Length'] = str(len(data))
@ -611,6 +615,10 @@ class ObjectsWebMixin(AdministrableWebMixin):
return None
def getViewBelowButtonsBarLayout(self, object, fields):
if hasattr(self, 'addComment') and \
'comments' in context.getVar('knownRoles'):
return getWebForServerRole(
'comments').getBothCommentsLayout(object.id)
return None
def getViewButtonsBarLayout(self, object, fields):
@ -1143,6 +1151,7 @@ class CommentableObjectMixin(things.ThingMixin):
def addCommentObject(self, id, object):
webRole = getWebForServerRole('comments')
object.parentId = id
context.push(_level = 'edit', layoutMode = 'edit')
try:
layout = X.array()
@ -1182,56 +1191,6 @@ class CommentableObjectMixin(things.ThingMixin):
if context.getVar('debug'):
raise
return accessForbidden()
return redirect(X.idUrl(id, 'withComments'))
return redirect(X.idUrl(id))
addCommentSubmit.isPublicForWeb = 1
def commentsLayout(self, id):
commentsWeb = getWebForServerRole('comments')
comments = commentsWeb.getObjectsWithParent(id).values()
comments.sort(lambda x,y: cmp(x.creationTime, y.creationTime))
layout = X.array()
if len(comments) == 0:
layout += X.p(_('No comment.'))
for i, comment in zip(range(len(comments)), comments):
layout += X.div(_class = 'comment', id = 'comment-%d' % (i+i))(
X.span(_class = 'comment-no')(str(i+1)),
comment.getViewLayout(self, None))
if self.canAddObject():
layout += X.div(_class = 'buttons-bar')(
X.buttonStandalone('add', X.idUrl(id, 'addComment')))
return layout
def comments(self, id):
layout = self.commentsLayout(id)
return writePageLayout(layout, _('Comments'))
comments.isPublicForWeb = 1
def withComments(self, id):
object = self.getObject(id)
rememberObject(id)
label = object.getLabelTranslated(context.getVar('readLanguages'))
layout = X.array()
slot = slots.Root(object)
widget = slot.getWidget()
layout += widget.getModelPageBodyLayout(slot, {})
layout += self.getViewButtonsBarLayout(object, None)
pageTitle = context.getVar('pageTitle', default = None)
layout += X.h2(id = 'comments')(_('Comments'))
context.push(sectionLevel = context.getVar('sectionLevel') + 1)
layout += self.commentsLayout(id)
context.pull()
context.push(
currentObject = WebAPI.GlasnostObject(object = object),
)
if not pageTitle:
pageTitle = '%s - %s' % (_(self.objectNameCapitalized), label)
layout = writePageLayout(layout, pageTitle)
context.pull()
return layout
withComments.isPublicForWeb = 1

View File

@ -205,6 +205,9 @@ class UploadFilesWeb(ObjectsWebMixin, UploadFilesProxy):
if fileName and object.dataFileName != fileName:
pageNotFound()
if not fileName and object.dataFileName:
uri = X.idUrl(id, 'download/%s' % object.dataFileName)
return redirect(uri)
req = context.getVar('req')
req.depends.append(id)

View File

@ -135,7 +135,7 @@ class GlasnostObject:
else:
raise "You should give an id or an object!"
try:
self.serverRole = tools.splitObjectId(self.objectId)[1]
self.serverRole = commonTools.extractRole(self.objectId)
except IndexError:
pass
except:
@ -346,7 +346,7 @@ def _getPathToObject(object, source):
if object in source.membersSet:
return [source]
for m in source.membersSet:
if tools.splitObjectId(m.objectId)[1] != 'rubrics':
if commonTools.extractRole(m.objectId) != 'rubrics':
# we don't go through getSetContainedIds here
continue
t = _getPathToObject(object, m)
@ -369,7 +369,7 @@ def getPathToObject(object):
def getTree(source, done = None, level=5):
if done is None:
done = []
if tools.splitObjectId(source.objectId)[1] != 'rubrics' or \
if commonTools.extractRole(source.objectId) != 'rubrics' or \
level == 0 or source in done:
return (source, [])
try:

View File

@ -199,8 +199,7 @@ class ThingMixin(ChoiceMixin):
def makeModelTitleFromValue(self, slot, fields, value):
object = slot.getObject()
label = _(self.getLabels(slot, fields)[
self.getModelValueAsString(value)])
label = _(self.getLabels(slot)[self.getModelValueAsString(value)])
return object.makeContentTitle(slot, label)
def newModelWidget(self, slot):
@ -350,11 +349,6 @@ class Float(KindMixin, proxyKinds.Float):
register(Float)
class FunctionName(ChoiceMixin, proxyKinds.FunctionName):
pass
register(FunctionName)
class Id(IdMixin, proxyKinds.Id):
pass
register(Id)
@ -397,8 +391,7 @@ class KindName(ChoiceMixin, proxyKinds.KindName):
def makeModelTitleFromValue(self, slot, fields, value):
object = slot.getObject()
label = _(self.getLabels(slot, fields)[
self.getModelValueAsString(value)])
label = _(self.getLabels(slot)[self.getModelValueAsString(value)])
return object.makeContentTitle(slot, label)
register(KindName)
@ -656,8 +649,7 @@ class WidgetName(ChoiceMixin, proxyKinds.WidgetName):
def makeModelTitleFromValue(self, slot, fields, value):
object = slot.getObject()
label = _(self.getLabels(slot, fields)[
self.getModelValueAsString(value)])
label = _(self.getLabels(slot)[self.getModelValueAsString(value)])
return object.makeContentTitle(slot, label)
register(WidgetName)

View File

@ -270,10 +270,10 @@ def getWebForServerRole(serverRole):
not serverRole in context.getVar('knownRoles'):
return None
if context.getVar('virtualHost'):
serverRoleWeb = commonTools.getConfig(
context.getVar('virtualHost').hostName,
serverRole + '-web', default = serverRole)
virtualHost = context.getVar('virtualHost')
if virtualHost is not None and virtualHost.customWebs and \
serverRole in virtualHost.customWebs.keys():
serverRoleWeb = virtualHost.customWebs[serverRole].lower()
else:
serverRoleWeb = serverRole
serverRoleWeb = serverRoleWeb.replace('-', '')
@ -718,7 +718,7 @@ def writePageLayout(layout, title, canCache = 1):
def getAppropriateTalFile(serverRole, idValue, action):
if idValue:
id = splitObjectId(idValue)
id = commonTools.splitId(idValue)
serverRole = id[1]
fileNames = (
'%s-%s.%s.%s.tal' % (serverRole, id[0], id[2], action),
@ -766,7 +766,7 @@ def getAppropriateTalFile(serverRole, idValue, action):
def getAppropriatePyFile(serverRole, idValue, action):
if idValue:
id = splitObjectId(idValue)
id = commonTools.splitId(idValue)
serverRole = id[1]
fileNames = (
'%s-%s.%s.%s.py' % (serverRole, id[0], id[2], action),

View File

@ -282,7 +282,7 @@ class ExclusiveChoiceMixin(WidgetMixin):
kind = slot.getKind()
value = slot.getValue() or ''
valueAsString = kind.getModelValueAsString(value)
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
if labels.has_key(valueAsString):
return self.makeModelTitleFromValue(slot, fields, value)
elif value == '__all__':
@ -300,7 +300,7 @@ class ExclusiveChoiceMixin(WidgetMixin):
title = kind.makeModelTitleFromValue(slot, fields, value)
if title:
return title
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
if labels and labels.has_key(valueAsString):
return _(labels[valueAsString])
return None
@ -814,13 +814,13 @@ class InputCheckBox(WidgetMixin, proxyWidgets.InputCheckBox):
inputAttributes = {}
if value:
inputAttributes['checked'] = 'checked'
trueValue = kind.getValues(slot, fields)[1]
trueValue = kind.getValues(slot)[1]
layout += X.input(
_class = 'checkbox', name = fieldName, type = 'checkbox',
value = kind.getModelValueAsString(trueValue),
**inputAttributes)
layout += X.nbsp
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
label = labels[kind.getModelValueAsString(trueValue)]
layout += _(label)
if self.apply:
@ -838,7 +838,7 @@ class InputCheckBox(WidgetMixin, proxyWidgets.InputCheckBox):
title = kind.makeModelTitleFromValue(slot, fields, value)
if title:
return title
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
if labels and labels.has_key(valueAsString):
return _(labels[valueAsString])
return None
@ -1191,7 +1191,7 @@ class MultiCheck(WidgetMixin, proxyWidgets.MultiCheck):
def getHtmlViewValue(self, slot, fields, **keywords):
kind = slot.getKind()
layout = X.ul()
value = slot.getValue()
value = slot.getValue() or []
for i, v in zip(range(len(value)), value):
itemSlot = kind.getItemSlot(slot, i)
itemWidget = itemSlot.getWidget()
@ -1201,8 +1201,8 @@ class MultiCheck(WidgetMixin, proxyWidgets.MultiCheck):
def getHtmlFormValue(self, slot, fields, **keywords):
kind = slot.getKind()
layout = X.ul()
values = kind.itemKind.getValues(slot, fields)
labels = kind.itemKind.getLabels(slot, fields)
values = kind.itemKind.getSortedValues(slot)
labels = kind.itemKind.getLabels(slot)
for i in range(len(values)):
itemSlot = kind.getItemSlot(slot, i)
itemWidget = itemSlot.getWidget()
@ -1212,13 +1212,13 @@ class MultiCheck(WidgetMixin, proxyWidgets.MultiCheck):
attrs = {'checked': 'checked'}
layout += X.li(
X.input(type = 'checkbox', name = fieldName, **attrs),
labels[values[i]])
_(labels[values[i]]))
return layout
def submit(self, slot, fields):
kind = slot.getKind()
value = []
values = kind.itemKind.getValues(slot, fields)
values = kind.itemKind.getValues(slot)
for i in range(len(values)):
fieldName = slot.getFieldOptionName(values[i])
itemValue = slot.getFieldOption(fields, values[i])
@ -1291,13 +1291,13 @@ class RadioButtons(ExclusiveChoiceMixin, proxyWidgets.RadioButtons):
valueAsString = ''
if hasattr(kind, 'sortLabels') and kind.sortLabels:
values = kind.getSortedValues(slot, fields)
values = kind.getSortedValues(slot)
else:
values = kind.getValues(slot, fields)
values = kind.getValues(slot)
if values is None:
raise Exception('Kind "%s" of slot "%s" has no values' % (
kind, slot))
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
layout = X.array()
layout += self.getModelErrorLayout(slot, fields)
@ -1381,13 +1381,13 @@ class Select(ExclusiveChoiceMixin, proxyWidgets.Select):
valueAsString = ''
if hasattr(kind, 'sortLabels') and kind.sortLabels:
values = kind.getSortedValues(slot, fields)
values = kind.getSortedValues(slot)
else:
values = kind.getValues(slot, fields)
values = kind.getValues(slot)
if values is None:
raise Exception('Kind "%s" of slot "%s" has no values' % (
kind, slot))
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
layout = X.array()
layout += self.getModelErrorLayout(slot, fields)
@ -1419,7 +1419,7 @@ class Select(ExclusiveChoiceMixin, proxyWidgets.Select):
layout += self.getModelHelpLayout(slot, fields)
groupNames = None
if hasattr(kind, 'getGroupedValues'):
groupNames, groupedValues = kind.getGroupedValues(slot, fields)
groupNames, groupedValues = kind.getGroupedValues(slot)
if groupNames is not None:
for groupName in groupNames:
groupValues = groupedValues[groupName]
@ -1492,9 +1492,9 @@ class SelectId(WidgetMixin, proxyWidgets.SelectId):
showOthersButton = self.showOthersButton
values = kind.getValues(slot, fields)
values = kind.getValues(slot)
for serverRole in serverRoles:
ids = [x for x in values if splitObjectId(x)[1] == serverRole]
ids = [x for x in values if commonTools.extractRole(x) == serverRole]
if not ids:
continue
menus[serverRole] = getObjectLabelsTranslated(
@ -1820,6 +1820,9 @@ class UploadFile(WidgetMixin, proxyWidgets.UploadFile):
if value.value:
upload.data = value.value
upload.dataFileName = value.filename
if '\\' in upload.dataFileName:
upload.dataFileName = upload.dataFileName[
upload.dataFileName.rindex('\\')+1:]
upload.dataType = value.type
else:
data = sessionsProxy.getTemporaryData(dataToken)
@ -1899,10 +1902,10 @@ class XSelect(Select, proxyWidgets.XSelect):
otherFieldValue = slot.getFieldOption(fields, 'other', default = '')
kind = slot.getKind()
if kind.sortLabels:
values = kind.getSortedValues(slot, fields)
values = kind.getSortedValues(slot)
else:
values = kind.getValues(slot, fields)
groupNames, groupedValues = kind.getGroupedValues(slot, fields)
values = kind.getValues(slot)
groupNames, groupedValues = kind.getGroupedValues(slot)
if values is None:
raise Exception('Kind "%s" of slot "%s" has no values' % (
kind, slot))
@ -1912,7 +1915,7 @@ class XSelect(Select, proxyWidgets.XSelect):
fieldValue = ''
else:
fieldValue = str(fieldValue)
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
if not self.isInForm():
if labels.has_key(str(fieldValue)):
@ -1951,7 +1954,7 @@ class XSelect(Select, proxyWidgets.XSelect):
noneLabel)
groupNames = None
if hasattr(kind, 'getGroupedValues'):
groupNames, groupedValues = kind.getGroupedValues(slot, fields)
groupNames, groupedValues = kind.getGroupedValues(slot)
if groupNames is not None:
for groupName in groupNames:
groupValues = groupedValues[groupName]
@ -2036,7 +2039,7 @@ class XSelect(Select, proxyWidgets.XSelect):
title = kind.makeModelTitleFromValue(slot, fields, value)
if title:
return title
labels = self.getLabels(slot, fields)
labels = self.getLabels(slot)
if labels and labels.has_key(valueAsString):
return _(labels[valueAsString])
return valueAsString

View File

@ -26,7 +26,7 @@
</div>
-->
<h1><a href="/" tal:reroot="href"><img tal:reroot="src" src="/images/logo-entrouvert.be.png" alt="entrouvert.be" /></a>
<span tal:condition="virtualHost.hostName[0] != '*'" tal:content="str(virtualHost)">title</span>
<span tal:condition="virtualHost.hostName[0] != 'entrouvert.be'" tal:content="str(virtualHost)">title</span>
</h1>
</div>

View File

@ -118,8 +118,9 @@ ul.article-meta {
max-width: 15em;
}
ul.article-meta li {
div#main-content ul.article-meta li {
padding: 0 0.3em;
margin: 0;
}
div#main-content h1, div#main-content h2.title {

View File

@ -273,3 +273,10 @@ td.translation-ok, td.translation-missing {
text-align: center;
}
div.spip-notes {
margin-top: 1em;
border-top: 1px solid #44618f;
font-size: 90%;
}

View File

@ -0,0 +1,4 @@
*.htmlc.*
*.talc.*
infos.xml
infos.xml.in.h

View File

@ -6,9 +6,13 @@ import unittest
glasnostPythonDir = '/usr/local/lib/glasnost-tests'
sys.path.insert(0, glasnostPythonDir)
import glasnost.common.context as context
from glasnost.common.parsers import makeHtmlFromSpip
class SpipParserTestCase(unittest.TestCase):
def setUp(self):
context.push(dispatcherId = 'glasnost://localhost')
def test00_plainSentence(self):
'''Render a plain sentence'''
result = makeHtmlFromSpip('''this is not interesting''')
@ -37,12 +41,12 @@ class SpipParserTestCase(unittest.TestCase):
def test05_glasnostLink(self):
'''Render a link to a Glasnost article'''
result = makeHtmlFromSpip('''[->article 2]''', inline = 1)
self.failUnless(result == '<a href="[{glasnost:partialid:articles:2}]">[{glasnost:label:articles:2}]</a>')
self.failUnless(result == '<a href="[{glasnost:partialid:localhost:articles:2}]">[{glasnost:label:localhost:articles:2}]</a>')
def test06_glasnostPageNameLink(self):
'''Render a link using an alias'''
result = makeHtmlFromSpip('''[->alias test]''', inline = 1)
self.failUnless(result == '<a href="[{glasnost:alias:test}]">[{glasnost:aliaslabel:test}]</a>')
self.failUnless(result == '<a href="[{glasnost:alias:localhost:test}]">[{glasnost:aliaslabel:localhost:test}]</a>')
def test07_nothingSpecialLink(self):
'''Render a plain link, nothing special'''

View File

@ -84,6 +84,10 @@ class ParserForForms(sgmllib.SGMLParser):
if attrs.has_key('type') and attrs['type'] == 'submit':
self.currentForm.buttons.append( (attrs['name'], attrs['value']) )
return
if attrs.has_key('type') and attrs['type'] == 'checkbox':
if attrs.has_key('checked') and attrs['checked'] == 'checked':
self.currentForm.values[attrs['name']] = 'checked'
return
self.currentForm.values[attrs['name']] = None
if attrs.has_key('value'):
self.currentForm.values[attrs['name']] = attrs['value']